312 lines
8.4 KiB
JavaScript
312 lines
8.4 KiB
JavaScript
// トリアコンタン氏のhalfmoveとyami氏のYami_8DirEx
|
|
|
|
Game_Map.prototype.xWithDirection = function (x, d) {
|
|
if (SceneManager._scene.constructor.name == "Scene_Survive_Battle_Map") {
|
|
return x + (d === 6 ? 0.125 : d === 4 ? -0.125 : 0);
|
|
} else {
|
|
return x + (d === 6 ? 1 : d === 4 ? -1 : 0);
|
|
}
|
|
};
|
|
|
|
Game_Map.prototype.yWithDirection = function (y, d) {
|
|
if (SceneManager._scene.constructor.name == "Scene_Survive_Battle_Map") {
|
|
return y + (d === 2 ? 0.125 : d === 8 ? -0.125 : 0);
|
|
} else {
|
|
return y + (d === 2 ? 1 : d === 8 ? -1 : 0);
|
|
}
|
|
};
|
|
|
|
Game_Map.prototype.roundXWithDirection = function (x, d) {
|
|
if (SceneManager._scene.constructor.name == "Scene_Survive_Battle_Map") {
|
|
return this.roundX(x + (d === 6 ? 0.125 : d === 4 ? -0.125 : 0));
|
|
} else {
|
|
return this.roundX(x + (d === 6 ? 1 : d === 4 ? -1 : 0));
|
|
}
|
|
};
|
|
|
|
Game_Map.prototype.roundYWithDirection = function (y, d) {
|
|
if (SceneManager._scene.constructor.name == "Scene_Survive_Battle_Map") {
|
|
return this.roundY(y + (d === 2 ? 0.125 : d === 8 ? -0.125 : 0));
|
|
} else {
|
|
return this.roundY(y + (d === 2 ? 1 : d === 8 ? -1 : 0));
|
|
}
|
|
};
|
|
|
|
Game_CharacterBase.prototype.isMapPassable = function (x, y, d) {
|
|
var x2 = $gameMap.roundXWithDirection(x, d);
|
|
var y2 = $gameMap.roundYWithDirection(y, d);
|
|
const d2 = this.reverseDir(d);
|
|
|
|
if (SceneManager._scene.constructor.name == "Scene_Survive_Battle_Map") {
|
|
if (d == 4) {
|
|
x2 = Math.floor(x2);
|
|
} else if (d == 6) {
|
|
x2 = Math.ceil(x2);
|
|
} else if (d == 8) {
|
|
y2 = Math.floor(y2);
|
|
} else if (d == 2) {
|
|
y2 = Math.ceil(y2);
|
|
}
|
|
}
|
|
return $gameMap.isPassable(x, y, d) && $gameMap.isPassable(x2, y2, d2);
|
|
};
|
|
|
|
Game_Map.prototype.checkPassage = function (x, y, bit) {
|
|
const flags = this.tilesetFlags();
|
|
const tiles = this.allTiles(Math.round(x), Math.round(y)); //ここ
|
|
for (const tile of tiles) {
|
|
const flag = flags[tile];
|
|
if ((flag & 0x10) !== 0) {
|
|
// [*] No effect on passage
|
|
continue;
|
|
}
|
|
if ((flag & bit) === 0) {
|
|
// [o] Passable
|
|
return true;
|
|
}
|
|
if ((flag & bit) === bit) {
|
|
// [x] Impassable
|
|
return false;
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
|
|
// ここから8方向
|
|
(function () {
|
|
Game_Player.prototype.isMoveDiagonally = function (direction) {
|
|
return [1, 3, 7, 9].contains(direction);
|
|
};
|
|
|
|
Game_Player.prototype.isMoveStraight = function (direction) {
|
|
return [2, 4, 6, 8].contains(direction);
|
|
};
|
|
|
|
Game_Character.prototype.getDiagonallyMovement = function (direction) {
|
|
var horz = 0;
|
|
var vert = 0;
|
|
if (direction === 1) {
|
|
horz = 4;
|
|
vert = 2;
|
|
} else if (direction === 3) {
|
|
horz = 6;
|
|
vert = 2;
|
|
} else if (direction === 7) {
|
|
horz = 4;
|
|
vert = 8;
|
|
} else if (direction === 9) {
|
|
horz = 6;
|
|
vert = 8;
|
|
}
|
|
return [horz, vert];
|
|
};
|
|
|
|
Game_Player.prototype.processMoveByInput = function (direction) {
|
|
if (this.isMoveStraight(direction)) {
|
|
this.moveStraight(direction);
|
|
} else if (this.isMoveDiagonally(direction)) {
|
|
var diagonal = this.getDiagonallyMovement(direction);
|
|
this.moveDiagonally.apply(this, diagonal);
|
|
}
|
|
};
|
|
|
|
//
|
|
// by Sasuke KANNAZUKI
|
|
// when fail to diagonally move, perform straight move.
|
|
//
|
|
var _Game_Player_moveDiagonally = Game_Player.prototype.moveDiagonally;
|
|
Game_Player.prototype.moveDiagonally = function (horz, vert) {
|
|
_Game_Player_moveDiagonally.call(this, horz, vert);
|
|
|
|
if (SceneManager._scene.constructor.name == "Scene_Survive_Battle_Map") {
|
|
if (!this.isMovementSucceeded()) {
|
|
// try vertical move
|
|
this.setMovementSuccess(this.canPass(this._x, this._y, vert));
|
|
if (this.isMovementSucceeded()) {
|
|
this.moveStraight(vert);
|
|
}
|
|
// try horizontal move
|
|
this.setMovementSuccess(this.canPass(this._x, this._y, horz));
|
|
if (this.isMovementSucceeded()) {
|
|
this.moveStraight(horz);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
// by Sasuke KANNAZUKI
|
|
// add dir4mode.
|
|
//
|
|
var _Game_Player_moveByInput = Game_Player.prototype.moveByInput;
|
|
Game_Player.prototype.moveByInput = function () {
|
|
if (SceneManager._scene.constructor.name == "Scene_Survive_Battle_Map") {
|
|
if (!this.isMoving() && this.canMove()) {
|
|
var direction = Input.dir8;
|
|
if (direction > 0) {
|
|
$gameTemp.clearDestination();
|
|
} else if ($gameTemp.isDestinationValid()) {
|
|
var x = $gameTemp.destinationX();
|
|
var y = $gameTemp.destinationY();
|
|
direction = this.findDiagonalDirectionTo(x, y);
|
|
}
|
|
if (direction > 0) {
|
|
this.processMoveByInput(direction);
|
|
}
|
|
}
|
|
} else {
|
|
_Game_Player_moveByInput.call(this);
|
|
}
|
|
};
|
|
|
|
// all following by Sasuke KANNAZUKI
|
|
// also at touch device, diagonal move to the shortest way.
|
|
//
|
|
Game_Map.prototype.diagonalDistance = function (x1, y1, x2, y2) {
|
|
var x = Math.abs(this.deltaX(x1, x2));
|
|
var y = Math.abs(this.deltaY(y1, y2));
|
|
return (Math.min(x, y) * 3) / 2 + Math.abs(x - y);
|
|
};
|
|
|
|
Game_Character.prototype.findDiagonalDirectionTo = 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.diagonalDistance(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++) {
|
|
if (j === 5) {
|
|
continue;
|
|
}
|
|
var directions;
|
|
if (this.isMoveDiagonally(j)) {
|
|
directions = this.getDiagonallyMovement(j);
|
|
} else {
|
|
directions = [j, j];
|
|
}
|
|
var horz = directions[0];
|
|
var vert = directions[1];
|
|
var x2 = $gameMap.roundXWithDirection(x1, horz);
|
|
var y2 = $gameMap.roundYWithDirection(y1, vert);
|
|
var pos2 = y2 * mapWidth + x2;
|
|
|
|
if (closedList.contains(pos2)) {
|
|
continue;
|
|
}
|
|
|
|
if (this.isMoveStraight(j)) {
|
|
if (!this.canPass(x1, y1, j)) {
|
|
continue;
|
|
}
|
|
} else if (this.isMoveDiagonally(j)) {
|
|
if (!this.canPassDiagonally(x1, y1, horz, vert)) {
|
|
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.diagonalDistance(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 (deltaY1 > 0) {
|
|
return deltaX1 === 0 ? 2 : deltaX1 > 0 ? 3 : 1;
|
|
} else if (deltaY1 < 0) {
|
|
return deltaX1 === 0 ? 8 : deltaX1 > 0 ? 9 : 7;
|
|
} else {
|
|
// deltaY1 === 0
|
|
if (deltaX1 !== 0) {
|
|
return deltaX1 > 0 ? 6 : 4;
|
|
}
|
|
}
|
|
|
|
var deltaX2 = this.deltaXFrom(goalX);
|
|
var deltaY2 = this.deltaYFrom(goalY);
|
|
if (Math.abs(deltaX2) > Math.abs(deltaY2)) {
|
|
if (deltaX2 > 0) {
|
|
return deltaY2 === 0 ? 4 : deltaY2 > 0 ? 7 : 1;
|
|
} else if (deltaX2 < 0) {
|
|
return deltaY2 === 0 ? 6 : deltaY2 > 0 ? 9 : 3;
|
|
} else {
|
|
// deltaX2 === 0
|
|
return deltaY2 === 0 ? 0 : deltaY2 > 0 ? 8 : 2;
|
|
}
|
|
} else {
|
|
if (deltaY2 > 0) {
|
|
return deltaX2 === 0 ? 8 : deltaX2 > 0 ? 7 : 9;
|
|
} else if (deltaY2 < 0) {
|
|
return deltaX2 === 0 ? 2 : deltaX2 > 0 ? 1 : 3;
|
|
} else {
|
|
// deltaY2 === 0
|
|
return deltaX2 === 0 ? 0 : deltaX2 > 0 ? 4 : 6;
|
|
}
|
|
}
|
|
};
|
|
})();
|