Game_Character.prototype.findDirectionTo = function(goalX, goalY) {
var searchLimit = this.searchLimit();
var mapWidth = $gameMap.width();
var nodeList = [];
var openList = [];
var closedList = [];
var start = {};
var best = start;
if (this.x === goalX && this.y === goalY) {
return 0
}
start.parent = null;
start.x = this.x;
start.y = this.y;
start.g = 0;
start.f = $gameMap.distance(start.x, start.y, goalX, goalY);
nodeList.push(start);
openList.push(start.y * mapWidth + start.x);
while (nodeList.length > 0) {
var bestIndex = 0;
for (var i = 0; i < nodeList.length; i++) {
if (nodeList[i].f < nodeList[bestIndex].f) {
bestIndex = i
}
}
var current = nodeList[bestIndex];
var x1 = current.x;
var y1 = current.y;
var pos1 = y1 * mapWidth + x1;
var g1 = current.g;
nodeList.splice(bestIndex, 1);
openList.splice(openList.indexOf(pos1), 1);
closedList.push(pos1);
if (current.x === goalX && current.y === goalY) {
best = current;
goaled = true;
break
}
if (g1 >= searchLimit) {
continue
}
for (var j = 1; j <= 9; j++) {
var direction = j;
if (direction == 5)
continue
var x2 = $gameMap.roundXWithDirection(x1, direction);
var y2 = $gameMap.roundYWithDirection(y1, direction);
var pos2 = y2 * mapWidth + x2;
if (closedList.contains(pos2)) {
continue
}
if (!this.canPass(x1, y1, direction)) {
continue
}
var g2 = g1 + 1;
var index2 = openList.indexOf(pos2);
if (index2 < 0 || g2 < nodeList[index2].g) {
var neighbor;
if (index2 >= 0) {
neighbor = nodeList[index2]
} else {
neighbor = {};
nodeList.push(neighbor);
openList.push(pos2)
}
neighbor.parent = current;
neighbor.x = x2;
neighbor.y = y2;
neighbor.g = g2;
neighbor.f = g2 + $gameMap.distance(x2, y2, goalX, goalY);
if (!best || neighbor.f - neighbor.g < best.f - best.g) {
best = neighbor
}
}
}
}
var node = best;
while (node.parent && node.parent !== start) {
node = node.parent
}
var deltaX1 = $gameMap.deltaX(node.x, start.x);
var deltaY1 = $gameMap.deltaY(node.y, start.y);
if (3 * (-deltaY1) + deltaX1 != 0)
return 5 + 3 * (-deltaY1) + deltaX1
return 0
};
Game_Map.prototype.xWithDirection = function(x, d) {
var temp = ((d - 4 > 0) ? d - 4 : d - 1);
return x + (temp % 3) - 1;
};
Game_Map.prototype.yWithDirection = function(y, d) {
return y - Math.floor((d - 4) / 3);
};
Game_Map.prototype.roundXWithDirection = function(x, d) {
return this.roundX(this.xWithDirection(x, d));
};
Game_Map.prototype.roundYWithDirection = function(y, d) {
return this.roundY(this.yWithDirection(y, d));
};
Game_Map.prototype.isPassableDiagonally = function(x, y, direction) {
var horz = (direction % 3 == 1)? 4 : 6;
var vert = (direction < 4)? 2 : 8;
var x2 = $gameMap.roundXWithDirection(x, horz);
var y2 = $gameMap.roundYWithDirection(y, vert);
if (this.isPassable(x, y, vert) && this.isPassable(x, y2, horz)) {
return true;
}
if (this.isPassable(x, y, horz) && this.isPassable(x2, y, vert)) {
return true;
}
return false;
};
Game_CharacterBase.prototype.isMapPassable = function(x, y, d) {
var x2 = $gameMap.roundXWithDirection(x, d);
var y2 = $gameMap.roundYWithDirection(y, d);
var d2 = this.reverseDir(d);
if (d % 2 == 0)
return $gameMap.isPassable(x, y, d) && $gameMap.isPassable(x2, y2, d2);
else
return $gameMap.isPassableDiagonally(x, y, d) && $gameMap.isPassableDiagonally(x2, y2, d2);
};