OMORI_Android/www.eng/js/plugins/YEP_EventChasePlayer.js
2024-01-15 18:44:53 +03:00

435 lines
14 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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