|
|
|
|
//=============================================================================
|
|
|
|
|
// 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.05;
|
|
|
|
|
|
|
|
|
|
//=============================================================================
|
|
|
|
|
/*:
|
|
|
|
|
* @plugindesc v1.05 事件追逐☁️
|
|
|
|
|
* @author Yanfly Engine Plugins
|
|
|
|
|
*
|
|
|
|
|
* @param Sight Lock
|
|
|
|
|
* @text 瞄准器
|
|
|
|
|
* @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
|
|
|
|
|
* @text 见玩家
|
|
|
|
|
* @desc Does the event have to be able to see the player by default?
|
|
|
|
|
* NO - false YES - true
|
|
|
|
|
* @default true
|
|
|
|
|
*
|
|
|
|
|
* @param Alert Timer
|
|
|
|
|
* @text 警报计时器
|
|
|
|
|
* @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
|
|
|
|
|
* @text 警示气球
|
|
|
|
|
* @desc This is the default balloon used when the player is seen.
|
|
|
|
|
* Refer to balloon ID's.
|
|
|
|
|
* @default 1
|
|
|
|
|
*
|
|
|
|
|
* @param Alert Sound
|
|
|
|
|
* @text 警报声
|
|
|
|
|
* @desc This is the default sound played when the player is seen.
|
|
|
|
|
* @default Attack1
|
|
|
|
|
*
|
|
|
|
|
* @param Alert Common Event
|
|
|
|
|
* @text 警报常见事件
|
|
|
|
|
* @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
|
|
|
|
|
* @text 之后返回
|
|
|
|
|
* @desc After chasing/fleeing from a player, the event returns
|
|
|
|
|
* to its original spot. NO - false YES - true
|
|
|
|
|
* @default true
|
|
|
|
|
*
|
|
|
|
|
* @param Return Wait
|
|
|
|
|
* @text 返回等待
|
|
|
|
|
* @desc The frames to wait after finishing a chase/flee.
|
|
|
|
|
* @default 180
|
|
|
|
|
*
|
|
|
|
|
* @help
|
|
|
|
|
* ============================================================================
|
|
|
|
|
* Introduction
|
|
|
|
|
* ============================================================================
|
|
|
|
|
*
|
|
|
|
|
* 目前事件只拥有传统乏味的移动行为。他们站在一个地方,追寻你,远离你,随
|
|
|
|
|
* 机移动,或者在一个设定路径行走。这个插件让你的事件可以迅速切换靠近角色
|
|
|
|
|
* 和远离角色.
|
|
|
|
|
* 在你靠近事件范围或者事件看到角色时,这个插件可以让你的事件追寻或者逃离
|
|
|
|
|
* 角色。
|
|
|
|
|
*
|
|
|
|
|
* ============================================================================
|
|
|
|
|
* How to Use
|
|
|
|
|
* ============================================================================
|
|
|
|
|
*
|
|
|
|
|
* 把下面这些脚本语句插入事件移动路线里,让其生效。
|
|
|
|
|
*
|
|
|
|
|
* Note: This doesn’t work with players.注意:这些对角色不生效。
|
|
|
|
|
*
|
|
|
|
|
* Script Call lines
|
|
|
|
|
* this._chaseRange = x 如果角色距离事件x,事件追逐角色。
|
|
|
|
|
* this._fleeRange = x 如果角色距离事件x,事件逃离角色。
|
|
|
|
|
* this._chaseSpeed = x 事件追逐速度
|
|
|
|
|
* this._fleeSpeed = x 事件逃离速度
|
|
|
|
|
* this._sightLock = x 事件追逐或者逃离角色时间
|
|
|
|
|
* this._seePlayer = true 需要事件能够看到角色
|
|
|
|
|
* this._seePlayer = false 不需要事件能够看到角色
|
|
|
|
|
* this._alertBalloon = x 当看到角色时弹出对白框
|
|
|
|
|
* this._alertSound = x 当看到角色时播放音乐
|
|
|
|
|
* this._alertSoundVol = x 当看到角色时播放音乐的音量
|
|
|
|
|
* this._alertSoundPitch = x The pitch used by the alert sound.
|
|
|
|
|
* this._alertSoundPan = x The pan used by the alert sound.
|
|
|
|
|
* this._alertCommonEvent = x 当看到角色时执行公共事件
|
|
|
|
|
* 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.
|
|
|
|
|
*
|
|
|
|
|
* 这个最适合用来自定义移动路线的速度。记住这个效果需要事件被设置为移动
|
|
|
|
|
* 这意味着载入地图时,如果事件没有被载入命令,这个事件永远不会追逐角色。
|
|
|
|
|
*
|
|
|
|
|
* ============================================================================
|
|
|
|
|
* Changelog
|
|
|
|
|
* ============================================================================
|
|
|
|
|
*
|
|
|
|
|
* 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._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._stopCount > 0 && this._chasePlayer) {
|
|
|
|
|
var direction = this.findDirectionTo($gamePlayer.x, $gamePlayer.y);
|
|
|
|
|
if (direction > 0) this.moveStraight(direction);
|
|
|
|
|
} 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
|
|
|
|
|
//=============================================================================
|