@screeps/engine
Version:
This is a module for Screeps standalone server. See [main repository](https://github.com/screeps/screeps) for more info.
278 lines (231 loc) • 10.1 kB
JavaScript
;
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
var utils = require('../utils'),
driver = utils.getDriver(),
C = driver.constants,
_ = require('lodash'),
util = require('util'),
pathUtils = require('./path-utils'),
Heap = pathUtils.Heap,
OpenClosed = pathUtils.OpenClosed;
var kRouteGrid = 30;
exports.makeMap = function (runtimeData, register) {
var heap, openClosed, parents;
var originX, originY;
var toX, toY;
function describeExits(roomName) {
if (!/^(W|E)\d+(N|S)\d+$/.test(roomName)) {
return null;
}
var _utils$roomNameToXY = utils.roomNameToXY(roomName),
_utils$roomNameToXY2 = _slicedToArray(_utils$roomNameToXY, 2),
x = _utils$roomNameToXY2[0],
y = _utils$roomNameToXY2[1];
var gridItem = runtimeData.mapGrid.gridData[x + ',' + y];
if (!gridItem) {
return null;
}
var exits = {};
if (gridItem.t) {
exits[C.TOP] = utils.getRoomNameFromXY(x, y - 1);
}
if (gridItem.b) {
exits[C.BOTTOM] = utils.getRoomNameFromXY(x, y + 1);
}
if (gridItem.l) {
exits[C.LEFT] = utils.getRoomNameFromXY(x - 1, y);
}
if (gridItem.r) {
exits[C.RIGHT] = utils.getRoomNameFromXY(x + 1, y);
}
return exits;
}
function xyToIndex(xx, yy) {
var ox = originX - xx;
var oy = originY - yy;
if (ox < 0 || ox >= kRouteGrid * 2 || oy < 0 || oy >= kRouteGrid * 2) {
return;
}
return ox * kRouteGrid * 2 + oy;
}
function indexToXY(index) {
return [originX - Math.floor(index / (kRouteGrid * 2)), originY - index % (kRouteGrid * 2)];
}
function heuristic(xx, yy) {
return Math.abs(xx - toX) + Math.abs(yy - toY);
}
return {
findRoute: function findRoute(fromRoom, toRoom, opts) {
if (_.isObject(fromRoom)) {
fromRoom = fromRoom.name;
}
if (_.isObject(toRoom)) {
toRoom = toRoom.name;
}
if (fromRoom == toRoom) {
return [];
}
if (!/(W|E)\d+(N|S)\d+$/.test(fromRoom) || !/(W|E)\d+(N|S)\d+$/.test(toRoom)) {
return C.ERR_NO_PATH;
}
var _utils$roomNameToXY3 = utils.roomNameToXY(fromRoom),
_utils$roomNameToXY4 = _slicedToArray(_utils$roomNameToXY3, 2),
fromX = _utils$roomNameToXY4[0],
fromY = _utils$roomNameToXY4[1];
var _utils$roomNameToXY5 = utils.roomNameToXY(toRoom);
var _utils$roomNameToXY6 = _slicedToArray(_utils$roomNameToXY5, 2);
toX = _utils$roomNameToXY6[0];
toY = _utils$roomNameToXY6[1];
if (fromX == toX && fromY == toY) {
return [];
}
originX = fromX + kRouteGrid;
originY = fromY + kRouteGrid;
// Init path finding structures
if (heap) {
heap.clear();
openClosed.clear();
} else {
heap = new Heap(Math.pow(kRouteGrid * 2, 2), Float64Array);
openClosed = new OpenClosed(Math.pow(kRouteGrid * 2, 2));
}
if (!parents) {
parents = new Uint16Array(Math.pow(kRouteGrid * 2, 2));
}
var fromIndex = xyToIndex(fromX, fromY);
heap.push(fromIndex, heuristic(fromX, fromY));
var routeCallback = opts && opts.routeCallback || function () {
return 1;
};
// Astar
while (heap.size()) {
// Pull node off heap
var index = heap.min();
var fcost = heap.minPriority();
// Close this node
heap.pop();
openClosed.close(index);
// Calculate costs
var _indexToXY = indexToXY(index),
_indexToXY2 = _slicedToArray(_indexToXY, 2),
xx = _indexToXY2[0],
yy = _indexToXY2[1];
var hcost = heuristic(xx, yy);
var gcost = fcost - hcost;
// Reached destination?
if (hcost === 0) {
var route = [];
while (index !== fromIndex) {
var _indexToXY3 = indexToXY(index),
_indexToXY4 = _slicedToArray(_indexToXY3, 2),
_xx = _indexToXY4[0],
_yy = _indexToXY4[1];
index = parents[index];
var _indexToXY5 = indexToXY(index),
_indexToXY6 = _slicedToArray(_indexToXY5, 2),
nx = _indexToXY6[0],
ny = _indexToXY6[1];
var dir = void 0;
if (nx < _xx) {
dir = C.FIND_EXIT_RIGHT;
} else if (nx > _xx) {
dir = C.FIND_EXIT_LEFT;
} else if (ny < _yy) {
dir = C.FIND_EXIT_BOTTOM;
} else {
dir = C.FIND_EXIT_TOP;
}
route.push({
exit: dir,
room: utils.getRoomNameFromXY(_xx, _yy)
});
}
route.reverse();
return route;
}
// Add neighbors
var fromRoomName = utils.getRoomNameFromXY(xx, yy);
var exits = describeExits(fromRoomName);
for (var _dir in exits) {
// Calculate costs and check if this node was already visited
var roomName = exits[_dir];
var graphKey = fromRoomName + ':' + roomName;
var _utils$roomNameToXY7 = utils.roomNameToXY(roomName),
_utils$roomNameToXY8 = _slicedToArray(_utils$roomNameToXY7, 2),
_xx2 = _utils$roomNameToXY8[0],
_yy2 = _utils$roomNameToXY8[1];
var neighborIndex = xyToIndex(_xx2, _yy2);
if (neighborIndex === undefined || openClosed.isClosed(neighborIndex)) {
continue;
}
var cost = Number(routeCallback(roomName, fromRoomName)) || 1;
if (cost === Infinity) {
continue;
}
var _fcost = gcost + heuristic(_xx2, _yy2) + cost;
// Add to or update heap
if (openClosed.isOpen(neighborIndex)) {
if (heap.priority(neighborIndex) > _fcost) {
heap.update(neighborIndex, _fcost);
parents[neighborIndex] = index;
}
} else {
heap.push(neighborIndex, _fcost);
openClosed.open(neighborIndex);
parents[neighborIndex] = index;
}
}
}
return C.ERR_NO_PATH;
},
findExit: function findExit(fromRoom, toRoom, opts) {
var route = this.findRoute(fromRoom, toRoom, opts);
if (!_.isArray(route)) {
return route;
}
if (!route.length) {
return C.ERR_INVALID_ARGS;
}
return route[0].exit;
},
describeExits: describeExits,
isRoomProtected: function isRoomProtected(roomName) {
register.deprecated('Method `Game.map.isRoomProtected` is deprecated and will be removed. Please use `Game.map.isRoomAvailable` instead.');
if (!/^(W|E)\d+(N|S)\d+$/.test(roomName)) {
return null;
}
return !_.contains(runtimeData.accessibleRooms, roomName);
},
isRoomAvailable: function isRoomAvailable(roomName) {
if (!/^(W|E)\d+(N|S)\d+$/.test(roomName)) {
return false;
}
return _.contains(runtimeData.accessibleRooms, roomName);
},
getTerrainAt: function getTerrainAt(x, y, roomName) {
if (_.isObject(x)) {
y = x.y;
roomName = x.roomName;
x = x.x;
}
if (!runtimeData.staticTerrainData || !runtimeData.staticTerrainData[roomName]) {
return undefined;
}
var terrain = runtimeData.staticTerrainData[roomName][y * 50 + x];
if (terrain & C.TERRAIN_MASK_WALL) {
return 'wall';
}
if (terrain & C.TERRAIN_MASK_SWAMP) {
return 'swamp';
}
return 'plain';
},
getRoomLinearDistance: function getRoomLinearDistance(roomName1, roomName2, continuous) {
return utils.calcRoomsDistance(roomName1, roomName2, continuous);
},
getWorldSize: function getWorldSize() {
return driver.getWorldSize();
}
};
};
//# sourceMappingURL=../sourcemaps/game/map.js.map