/*:
*
* @plugindesc Two events as stairs with event notes...
* @author Jake Jilg "mogwai"
*
* Create two events per staircase using these notes with the same id
*
* <stairs_bottom:id> event at the bottom of a stairs
* <stairs_top:id> event at the top of a stairs
*
* version 0.2
*/
(function(alias){
Game_CharacterBase.prototype.canPass = function(x, y, d) {
this._isOnStairs = this._isOnStairs || false;
this._isOnStairsFromTop = this._isOnStairsFromTop || false;
this._isOnStairsFromBottom = this._isOnStairsFromBottom || false;
this._isOnStairsEvents = this._isOnStairsEvents || [];
var ev2 = $gameMap.eventsXy(
$gameMap.roundXWithDirection(x, d), // x2
$gameMap.roundYWithDirection(y, d) // y2
)[0];
if(ev2 !== undefined && ev2._eventId !== undefined){
var meta = $dataMap.events[ev2._eventId].meta || {};
var top = meta.stairs_top !== undefined;
var bottom = meta.stairs_bottom !== undefined;
var from_top = this._isOnStairsFromTop;
var from_bottom = this._isOnStairsFromBottom;
var ev = this._isOnStairsEvents;
if(top || bottom){
var partner1 = "stairs_" + (!bottom && top ? "top" : "bottom");
var id1 = meta[partner1];
if(!from_top && !from_bottom){ // mount
this._isOnStairsFromTop = top;
this._isOnStairsFromBottom = bottom;
this._isOnStairs = true;
this._isOnStairsEvents[0] = ev2;
this[partner1] = ev2;
for(var i = 0; i < $dataMap.events.length; i++){
if($gameMap._events[i] === undefined
|| $dataMap.events[i] === undefined)
continue;
var partner = "stairs_" + (bottom && !top ? "top" : "bottom");
var id2 = $dataMap.events[i].meta[partner];
if(id2 !== undefined && id2 === id1){
var ev3 = $gameMap._events[i];
this._isOnStairsEvents[1] = ev3;
this[partner] = ev3;
break;
}
}
return true;
}
}
}
if(this._isOnStairs){
return true;
}
return alias.apply(this, arguments);
};
})(Game_CharacterBase.prototype.canPass);
(function(alias){
Game_CharacterBase.prototype.moveStraight = function(d) {
if(this._isOnStairs){
this.moveAt = this.moveAt || [];
this.moveAt.push({x:this._x, y:this._y, d:d});
var ev = this._isOnStairsEvents;
var left = ev[0]._x < ev[1]._x;
var x1 = ev[0]._x;
var x2 = ev[1]._x;
var y1 = ev[0]._y;
var y2 = ev[1]._y;
var lx = Math.min(x1, x2);
var rx = Math.max(x1, x2);
var ty = Math.min(y1, y2);
var by = Math.max(y1, y2);
var r = x1 === lx && y1 == ty || x2 === lx && y2 == ty;
var l = d === (r?8:2) || d === 4;
this.setDirection(l?4:6);
var bt = Math.abs(this._y - ty) === 0 || Math.abs(this._y - by) === 0;
var lcx = Math.abs(this._x - lx);
var rcx = Math.abs(this._x - rx);
// sorry I math like a chimpanzee
if(bt && (lcx === 0 && !l || rcx === 0 && l) || this._x > lx && this._x < rx){
var a = Math.atan2(
r ? by - ty : ty - by,
rx - lx
);
var oldx = this._x;
var oldy = this._y;
var newx = oldx + (l ? 0 - Math.cos(a) : Math.cos(a));
var newy = oldy + (l ? 0 - Math.sin(a) : Math.sin(a));
if(newx < lx) newx = lx;
if(newx > rx) newx = rx;
if(newy < ty) newy = ty;
if(newy > by) newy = by;
this._realX = this._x;
this._realY = this._y;
this._x = newx;
this._y = newy;
this.increaseSteps();
return;
}else if(lcx < 1 && l || rcx < 1 && !l){
if(Math.abs(x1 - this._x) < Math.abs(x2 - this._x)){
this._x = ev[0]._x;
this._y = ev[0]._y;
}else{
this._x = ev[1]._x;
this._y = ev[1]._y;
}
this._isOnStairs = false;
this._isOnStairsFromTop = false;
this._isOnStairsFromBottom = false;
this._isOnStairsEvents = [];
}
}
return alias.apply(this, arguments);
};
})(Game_CharacterBase.prototype.moveStraight);
(function(alias){
Game_CharacterBase.prototype.moveDiagonally = function(horz, vert) {
if(this._isOnStairs){
this.moveStraight(horz);
}else{
return alias.apply(this, arguments);
}
};
})(Game_CharacterBase.prototype.moveDiagonally);
(function(alias){
Game_Character.prototype.findDirectionTo = function() {
if(this._isOnStairs){
if(this._isOnStairsFromTop){
arguments[0] = this.stairs_bottom._x;
arguments[1] = this.stairs_bottom._y;
}
if(this._isOnStairsFromBottom){
arguments[0] = this.stairs_top._x;
arguments[1] = this.stairs_top._y;
}
}
return alias.apply(this, arguments);
}
})(Game_Character.prototype.findDirectionTo);
Game_Map.prototype.eventsXy = function(x, y) {
return this.events().filter(function(event) {
if(event._isOnStairs)
return Math.hypot(event._x - x, event._y - y) < 1.5;
else
return event.pos(x, y);
});
};