Add a new Room Layout Generator
This commit is contained in:
parent
3922f367a2
commit
28d2b2d38b
19 changed files with 499 additions and 362 deletions
|
|
@ -1,47 +0,0 @@
|
|||
export const buildContainers = (room: Room) => {
|
||||
const controller = room.controller;
|
||||
if (controller == null) {
|
||||
return;
|
||||
}
|
||||
if (controller.level < 2
|
||||
&& room.find(FIND_MY_STRUCTURES,
|
||||
{ filter: STRUCTURE_EXTENSION }).length > 1) {
|
||||
return;
|
||||
}
|
||||
const sources = room.find(FIND_SOURCES);
|
||||
for (const source of sources) {
|
||||
const pos = source.pos;
|
||||
room.createConstructionSite(pos.x - 1, pos.y, STRUCTURE_CONTAINER);
|
||||
room.createConstructionSite(pos.x + 1, pos.y, STRUCTURE_CONTAINER);
|
||||
room.createConstructionSite(pos.x, pos.y - 1, STRUCTURE_CONTAINER);
|
||||
room.createConstructionSite(pos.x, pos.y + 1, STRUCTURE_CONTAINER);
|
||||
room.createConstructionSite(pos.x - 1, pos.y + 1, STRUCTURE_CONTAINER);
|
||||
room.createConstructionSite(pos.x + 1, pos.y - 1, STRUCTURE_CONTAINER);
|
||||
room.createConstructionSite(pos.x - 1, pos.y - 1, STRUCTURE_CONTAINER);
|
||||
room.createConstructionSite(pos.x + 1, pos.y + 1, STRUCTURE_CONTAINER);
|
||||
}
|
||||
if (controller.level < 4) {
|
||||
return;
|
||||
}
|
||||
const terrain = room.getTerrain();
|
||||
if (terrain.get(controller.pos.x, controller.pos.y - 3)
|
||||
!== TERRAIN_MASK_WALL) {
|
||||
room.createConstructionSite(
|
||||
controller.pos.x, controller.pos.y - 3, STRUCTURE_STORAGE);
|
||||
}
|
||||
else if (terrain.get(controller.pos.x, controller.pos.y + 3)
|
||||
!== TERRAIN_MASK_WALL) {
|
||||
room.createConstructionSite(
|
||||
controller.pos.x, controller.pos.y + 3, STRUCTURE_STORAGE);
|
||||
}
|
||||
else if (terrain.get(controller.pos.x - 3, controller.pos.y)
|
||||
!== TERRAIN_MASK_WALL) {
|
||||
room.createConstructionSite(
|
||||
controller.pos.x - 3, controller.pos.y, STRUCTURE_STORAGE);
|
||||
}
|
||||
else if (terrain.get(controller.pos.x + 3, controller.pos.y)
|
||||
!== TERRAIN_MASK_WALL) {
|
||||
room.createConstructionSite(
|
||||
controller.pos.x + 3, controller.pos.y, STRUCTURE_STORAGE);
|
||||
}
|
||||
};
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
const extentionsAvailable = (roomlevel: number) => {
|
||||
return roomlevel > 2 ? roomlevel * 10 - 20 : (roomlevel - 1) * 5;
|
||||
};
|
||||
|
||||
export const buildExtentions = (room: Room) => {
|
||||
const spawns = room.find(FIND_MY_SPAWNS);
|
||||
if (spawns.length < 1) return;
|
||||
const spawn = spawns[0];
|
||||
const exts = extentionsAvailable(room.controller?.level ?? 0);
|
||||
const terrain = room.getTerrain();
|
||||
const sqroffset = Math.sqrt(exts) / 2;
|
||||
for (let x = -Math.floor(sqroffset); x < sqroffset; x++) {
|
||||
for (let y = -Math.floor(sqroffset); y < sqroffset; y++) {
|
||||
room.visual.circle(spawn.pos.x + x * 2, spawn.pos.y + y * 2);
|
||||
if (terrain.get(spawn.pos.x + x * 2 - 1, spawn.pos.y + y * 2 - 1)
|
||||
!== TERRAIN_MASK_WALL) {
|
||||
room.createConstructionSite(
|
||||
spawn.pos.x + x * 2 - 1, spawn.pos.y + y * 2 - 1, STRUCTURE_ROAD);
|
||||
}
|
||||
if (terrain.get(spawn.pos.x + x * 2, spawn.pos.y + y * 2 - 1)
|
||||
!== TERRAIN_MASK_WALL) {
|
||||
room.createConstructionSite(
|
||||
spawn.pos.x + x * 2, spawn.pos.y + y * 2 - 1, STRUCTURE_ROAD);
|
||||
}
|
||||
if (terrain.get(spawn.pos.x + x * 2 - 1, spawn.pos.y + y * 2)
|
||||
!== TERRAIN_MASK_WALL) {
|
||||
room.createConstructionSite(
|
||||
spawn.pos.x + x * 2 - 1, spawn.pos.y + y * 2, STRUCTURE_ROAD);
|
||||
}
|
||||
room.createConstructionSite(
|
||||
spawn.pos.x + x * 2, spawn.pos.y + y * 2, STRUCTURE_EXTENSION);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
export const buildRoads = (room: Room) => {
|
||||
const rc = room.controller?.level ?? 0;
|
||||
if (rc < 2) {
|
||||
return;
|
||||
}
|
||||
const sources: _HasRoomPosition[] = room.find(FIND_SOURCES);
|
||||
const sourcesAndSpawns = sources.concat(room.find(FIND_MY_SPAWNS));
|
||||
const sourcesAndMinerals = sources.concat(room.find(FIND_MINERALS));
|
||||
room.visual.clear();
|
||||
for (const source of sourcesAndSpawns) {
|
||||
for (const source2 of rc > 4 ? sourcesAndMinerals : sources) {
|
||||
const path = source.pos.findPathTo(source2, {
|
||||
ignoreCreeps: true,
|
||||
ignoreRoads: true,
|
||||
});
|
||||
for (const point of path) {
|
||||
if ((point.x === source.pos.x && point.y === source.pos.y)
|
||||
|| (point.x === source2.pos.x && point.y === source2.pos.y)) {
|
||||
continue;
|
||||
}
|
||||
room.visual.line(point.x, point.y,
|
||||
point.x - point.dx, point.y - point.dy);
|
||||
room.createConstructionSite(point.x, point.y, STRUCTURE_ROAD);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
448
src/RoomPlanner/index.ts
Normal file
448
src/RoomPlanner/index.ts
Normal file
|
|
@ -0,0 +1,448 @@
|
|||
import profiler from "screeps-profiler";
|
||||
|
||||
const roomSize = 50;
|
||||
const OBSTACLE = 1000;
|
||||
const UNSET = 999;
|
||||
|
||||
declare global {
|
||||
interface RoomMemory {
|
||||
_planner: string
|
||||
}
|
||||
}
|
||||
const structureCoding: (BuildableStructureConstant | null)[] =
|
||||
[null, STRUCTURE_ROAD, STRUCTURE_CONTAINER, STRUCTURE_EXTENSION, STRUCTURE_FACTORY,
|
||||
STRUCTURE_EXTRACTOR, STRUCTURE_WALL, STRUCTURE_SPAWN, STRUCTURE_POWER_SPAWN,
|
||||
STRUCTURE_STORAGE, STRUCTURE_NUKER, STRUCTURE_TERMINAL, STRUCTURE_LAB,
|
||||
STRUCTURE_LINK, STRUCTURE_TOWER, STRUCTURE_RAMPART];
|
||||
|
||||
const getCoord = (x: number, y: number): number => {
|
||||
return x + y * roomSize;
|
||||
}
|
||||
|
||||
const distanceTransform = (mask: (0 | 999 | 1000)[]): number[] => {
|
||||
let arr: number[] = new Array(...mask);
|
||||
for (let i = 0; arr.find((x) => x === UNSET) != null; i++) {
|
||||
for (let x = 0; x < roomSize; x++) {
|
||||
for (let y = 0; y < roomSize; y++) {
|
||||
if (arr[getCoord(x, y)] === i) {
|
||||
for (let dx = -1; dx < 2; dx++) {
|
||||
for (let dy = -1; dy < 2; dy++) {
|
||||
if (x + dx < 0 || y + dy < 0 || x + dx >= 50 || y + dy >= 50
|
||||
|| arr[getCoord(x, y)] === OBSTACLE) {
|
||||
continue;
|
||||
}
|
||||
if (arr[getCoord(x + dx, y + dy)] === UNSET) {
|
||||
arr[getCoord(x + dx, y + dy)] = i + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return arr;
|
||||
};
|
||||
|
||||
/* const renderHeatmap = (mask: number[], visual: RoomVisual) => {
|
||||
for (let x = 0; x < 50; x++) {
|
||||
for (let y = 0; y < 50; y++) {
|
||||
if (mask[getCoord(x, y)] === OBSTACLE) {
|
||||
continue;
|
||||
}
|
||||
visual.rect(x - 0.5, y - 0.5, 1, 1, {
|
||||
fill: "#" + (127 + mask[getCoord(x, y)] * 3).toString(16)
|
||||
+ 127..toString(16)
|
||||
+ (255 - mask[getCoord(x, y)] * 5).toString(16),
|
||||
opacity: 0.2
|
||||
}).text(mask[getCoord(x, y)].toString(), x, y + 0.25);
|
||||
}
|
||||
}
|
||||
} */
|
||||
|
||||
const createBuildSites = (room: Room) => {
|
||||
let structures = new Array();
|
||||
for (let i = 0; i < room.memory._planner.length; i++) {
|
||||
structures.push(
|
||||
structureCoding[(room.memory._planner.charCodeAt(i) - 32) & 0b11111]
|
||||
);
|
||||
structures.push(
|
||||
structureCoding[(room.memory._planner.charCodeAt(i) - 32) >> 5]
|
||||
);
|
||||
}
|
||||
for (let x = 0; x < roomSize; x++) {
|
||||
for (let y = 0; y < roomSize; y++) {
|
||||
if ((room.controller?.level ?? 0) < 2
|
||||
&& structures[getCoord(x, y)] != STRUCTURE_CONTAINER) {
|
||||
continue;
|
||||
}
|
||||
if ((room.controller?.level ?? 0) < 3
|
||||
&& !(structures[getCoord(x, y)] == STRUCTURE_CONTAINER
|
||||
|| structures[getCoord(x, y)] == STRUCTURE_ROAD
|
||||
|| structures[getCoord(x, y)] == STRUCTURE_EXTENSION)) {
|
||||
continue;
|
||||
}
|
||||
if ((room.controller?.level ?? 0) < 4
|
||||
&& !(structures[getCoord(x, y)] == STRUCTURE_CONTAINER
|
||||
|| structures[getCoord(x, y)] == STRUCTURE_ROAD
|
||||
|| structures[getCoord(x, y)] == STRUCTURE_EXTENSION
|
||||
|| structures[getCoord(x, y)] == STRUCTURE_RAMPART
|
||||
|| structures[getCoord(x, y)] == STRUCTURE_TOWER)) {
|
||||
continue;
|
||||
}
|
||||
if ((room.controller?.level ?? 0) < 5
|
||||
&& !(structures[getCoord(x, y)] == STRUCTURE_CONTAINER
|
||||
|| structures[getCoord(x, y)] == STRUCTURE_ROAD
|
||||
|| structures[getCoord(x, y)] == STRUCTURE_EXTENSION
|
||||
|| structures[getCoord(x, y)] == STRUCTURE_RAMPART
|
||||
|| structures[getCoord(x, y)] == STRUCTURE_TOWER
|
||||
|| structures[getCoord(x, y)] == STRUCTURE_WALL)) {
|
||||
continue;
|
||||
}
|
||||
if ((room.controller?.level ?? 0) < 6
|
||||
&& !(structures[getCoord(x, y)] == STRUCTURE_CONTAINER
|
||||
|| structures[getCoord(x, y)] == STRUCTURE_ROAD
|
||||
|| structures[getCoord(x, y)] == STRUCTURE_EXTENSION
|
||||
|| structures[getCoord(x, y)] == STRUCTURE_RAMPART
|
||||
|| structures[getCoord(x, y)] == STRUCTURE_TOWER
|
||||
|| structures[getCoord(x, y)] == STRUCTURE_WALL
|
||||
|| structures[getCoord(x, y)] == STRUCTURE_STORAGE)) {
|
||||
continue;
|
||||
}
|
||||
if ((room.controller?.level ?? 0) < 8
|
||||
&& !(structures[getCoord(x, y)] == STRUCTURE_CONTAINER
|
||||
|| structures[getCoord(x, y)] == STRUCTURE_ROAD
|
||||
|| structures[getCoord(x, y)] == STRUCTURE_EXTENSION
|
||||
|| structures[getCoord(x, y)] == STRUCTURE_RAMPART
|
||||
|| structures[getCoord(x, y)] == STRUCTURE_TOWER
|
||||
|| structures[getCoord(x, y)] == STRUCTURE_WALL
|
||||
|| structures[getCoord(x, y)] == STRUCTURE_STORAGE
|
||||
|| structures[getCoord(x, y)] == STRUCTURE_EXTRACTOR)) {
|
||||
continue;
|
||||
}
|
||||
if (structures[getCoord(x, y)] != null) {
|
||||
if (room.createConstructionSite(x, y, structures[getCoord(x, y)])
|
||||
=== ERR_FULL) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default profiler.registerFN(function RoomPlanner(room: Room) {
|
||||
if (room.controller == null || !room.controller.my) {
|
||||
return;
|
||||
}
|
||||
if (Game.cpu.bucket < 100 && room.name != "sim") {
|
||||
return;
|
||||
}
|
||||
if (room.name != "sim" && Game.time % 113 !== 0) {
|
||||
return;
|
||||
}
|
||||
if (room.memory._planner != null) {
|
||||
createBuildSites(room);
|
||||
return;
|
||||
}
|
||||
const terrain = room.getTerrain();
|
||||
let mask: number[] = new Array(roomSize * roomSize).fill(0);
|
||||
for (let x = 0; x < roomSize; x++) {
|
||||
for (let y = 0; y < roomSize; y++) {
|
||||
mask[getCoord(x, y)] = terrain.get(x, y);
|
||||
}
|
||||
}
|
||||
const wallDistance = distanceTransform(
|
||||
mask.map((t) => t === TERRAIN_MASK_WALL ? 0 : UNSET));
|
||||
const controllerCoord =
|
||||
(room.controller?.pos.x ?? 0) + (room.controller?.pos.y ?? -1) * roomSize;
|
||||
const controllerDistance = distanceTransform(
|
||||
mask.map((t, i) =>
|
||||
i === controllerCoord ? 0 : (
|
||||
t === TERRAIN_MASK_WALL ? OBSTACLE : UNSET
|
||||
))
|
||||
);
|
||||
const buildCenter = wallDistance.map(
|
||||
(x, i) => [x * 2.5 - controllerDistance[i], i]).sort(
|
||||
(a, b) => b[0] - a[0])[0][1];
|
||||
const buildCenterX = buildCenter % roomSize;
|
||||
const buildCenterY = Math.floor(buildCenter / roomSize);
|
||||
const buildCenterPos = room.getPositionAt(buildCenterX, buildCenterY)!;
|
||||
/* room.visual.rect(buildCenterX - 0.5, buildCenterY - 0.5, 1, 1, {
|
||||
stroke: "#FF0000",
|
||||
}); */
|
||||
|
||||
//
|
||||
// Build structures
|
||||
//
|
||||
|
||||
let structures: (BuildableStructureConstant | null)[]
|
||||
= new Array(roomSize * roomSize);
|
||||
|
||||
// Build Roads + Containers
|
||||
const roadTargets = (room.sources as (_HasRoomPosition | null)[])
|
||||
.concat([room.controller, room.mineral])
|
||||
.concat([room.find(FIND_EXIT_TOP)?.[0],
|
||||
room.find(FIND_EXIT_LEFT)?.[0],
|
||||
room.find(FIND_EXIT_RIGHT)?.[0],
|
||||
room.find(FIND_EXIT_BOTTOM)?.[0]]
|
||||
.map((pos) => pos == null ? null : ({ pos, highRange: true })));
|
||||
for (let target of roadTargets) {
|
||||
if (target == null) { continue; }
|
||||
const { path } = PathFinder.search(buildCenterPos,
|
||||
{ pos: target.pos, range: "highRange" in target ? 3 : 1 }, {
|
||||
swampCost: 10,
|
||||
plainCost: 2,
|
||||
roomCallback: function(roomName) {
|
||||
if (roomName != room.name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let costs = new PathFinder.CostMatrix;
|
||||
for (let x = 0; x < roomSize; x++) {
|
||||
for (let y = 0; y < roomSize; y++) {
|
||||
if (structures[getCoord(x, y)] === STRUCTURE_ROAD) {
|
||||
costs.set(x, y, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return costs;
|
||||
}
|
||||
});
|
||||
for (let i = 0; i < path.length; i++) {
|
||||
const pos = path[i];
|
||||
structures[getCoord(pos.x, pos.y)]
|
||||
= (i === path.length - 1 && "energy" in target)
|
||||
? STRUCTURE_CONTAINER : STRUCTURE_ROAD;
|
||||
}
|
||||
}
|
||||
|
||||
// Build Core
|
||||
for (let dx = -2; dx < 3; dx++) {
|
||||
for (let dy = -2; dy < 3; dy++) {
|
||||
structures[getCoord(buildCenterX + dx, buildCenterY + dy)]
|
||||
= STRUCTURE_ROAD;
|
||||
}
|
||||
}
|
||||
structures[getCoord(buildCenterX, buildCenterY)] = STRUCTURE_RAMPART;
|
||||
structures[getCoord(buildCenterX + 1, buildCenterY)] = STRUCTURE_STORAGE;
|
||||
structures[getCoord(buildCenterX + 1, buildCenterY - 1)] = STRUCTURE_TERMINAL;
|
||||
structures[getCoord(buildCenterX, buildCenterY - 1)] = STRUCTURE_LINK;
|
||||
structures[getCoord(buildCenterX - 1, buildCenterY - 1)] = STRUCTURE_FACTORY;
|
||||
structures[getCoord(buildCenterX - 1, buildCenterY)] = STRUCTURE_NUKER;
|
||||
structures[getCoord(buildCenterX - 1, buildCenterY + 1)] = STRUCTURE_SPAWN;
|
||||
structures[getCoord(buildCenterX, buildCenterY + 1)] = STRUCTURE_POWER_SPAWN;
|
||||
structures[getCoord(buildCenterX + 1, buildCenterY + 1)] = STRUCTURE_ROAD;
|
||||
|
||||
// Labs
|
||||
const coreCorners = [
|
||||
[buildCenterX - 2, buildCenterY - 2],
|
||||
[buildCenterX - 2, buildCenterY + 2],
|
||||
[buildCenterX + 2, buildCenterY - 2],
|
||||
[buildCenterX + 2, buildCenterY + 2],
|
||||
].map(([x, y]) => [x, y, controllerDistance[x + y * roomSize]]
|
||||
).sort(([_x, _y, i], [_x2, _y2, j]) => i - j);
|
||||
|
||||
for (let [x, y, i] of coreCorners) {
|
||||
const directionX = (x - buildCenterX) / Math.abs(x - buildCenterX);
|
||||
const directionY = (y - buildCenterY) / Math.abs(y - buildCenterY);
|
||||
let ok = true;
|
||||
s: for (let dx = 0; Math.abs(dx) < 4; dx += directionX) {
|
||||
for (let dy = 0; Math.abs(dy) < 4; dy += directionY) {
|
||||
if ((structures[getCoord(x + dx, y + dy)] == null
|
||||
|| structures[getCoord(x + dx, y + dy)] === STRUCTURE_ROAD)
|
||||
&& mask[getCoord(x + dx, y + dy)] === 0) {
|
||||
continue;
|
||||
}
|
||||
ok = false;
|
||||
break s;
|
||||
}
|
||||
}
|
||||
if (ok) {
|
||||
for (let dx = 0; Math.abs(dx) < 5; dx += directionX) {
|
||||
for (let dy = 0; Math.abs(dy) < 5; dy += directionY) {
|
||||
if (Math.abs(dx) == Math.abs(dy)) {
|
||||
structures[getCoord(x + dx, y + dy)] = STRUCTURE_ROAD;
|
||||
continue;
|
||||
}
|
||||
if (Math.abs(dx) === 4 || Math.abs(dy) === 4) {
|
||||
if (mask[getCoord(x + dx, y + dy)] === 0) {
|
||||
structures[getCoord(x + dx, y + dy)] = STRUCTURE_ROAD;
|
||||
}
|
||||
}
|
||||
if (!(dx === 0 && Math.abs(dy) === 3)
|
||||
&& !(dy === 0 && Math.abs(dx) === 3)) {
|
||||
structures[getCoord(x + dx, y + dy)] = STRUCTURE_LAB;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Extensions
|
||||
let extensions = 0;
|
||||
a: for (let dx = 0; dx < roomSize / 2; dx++) {
|
||||
for (let dy = 0; dy < wallDistance[getCoord(buildCenterX, buildCenterY)]; dy++) {
|
||||
for (let cardinal = 0; cardinal < 4; cardinal++) {
|
||||
const x = cardinal < 2 ? buildCenterX + dx : buildCenterX - dx;
|
||||
const y = cardinal % 2 == 0 ? buildCenterY + dy : buildCenterY - dy;
|
||||
if (extensions >= 60) {
|
||||
break a;
|
||||
}
|
||||
if (structures[getCoord(x, y)] == null
|
||||
&& (mask[getCoord(x, y)] === 0
|
||||
|| mask[getCoord(x, y)] === TERRAIN_MASK_SWAMP)) {
|
||||
let ok = false;
|
||||
s: for (let ddx = -1; ddx < 2; ddx++) {
|
||||
for (let ddy = -1; ddy < 2; ddy++) {
|
||||
if (structures[getCoord(x + ddx, y + ddy)] === STRUCTURE_ROAD) {
|
||||
ok = true;
|
||||
break s;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ok) {
|
||||
if (x % 2 == y % 3 || x % 3 == y % 2) {
|
||||
structures[getCoord(x, y)] = STRUCTURE_ROAD;
|
||||
} else {
|
||||
structures[getCoord(x, y)] = STRUCTURE_EXTENSION;
|
||||
extensions++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (room.mineral != null) {
|
||||
structures[getCoord(room.mineral.pos.x, room.mineral.pos.y)]
|
||||
= STRUCTURE_EXTRACTOR;
|
||||
}
|
||||
|
||||
// Walls
|
||||
let smallestX = roomSize;
|
||||
let largestX = 0;
|
||||
let smallestY = roomSize;
|
||||
let largestY = 0;
|
||||
for (let x = 0; x < roomSize; x++) {
|
||||
for (let y = 0; y < roomSize; y++) {
|
||||
if (structures[getCoord(x, y)] != null
|
||||
&& structures[getCoord(x, y)] != STRUCTURE_ROAD
|
||||
&& structures[getCoord(x, y)] != STRUCTURE_CONTAINER) {
|
||||
if (x < smallestX) {
|
||||
smallestX = x;
|
||||
}
|
||||
if (x > largestX) {
|
||||
largestX = x;
|
||||
}
|
||||
if (y < smallestY) {
|
||||
smallestY = y;
|
||||
}
|
||||
if (y > largestY) {
|
||||
largestY = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
smallestX = Math.max(2, smallestX - 3);
|
||||
smallestY = Math.max(2, smallestY - 3);
|
||||
largestX = Math.min(48, largestX + 3);
|
||||
largestY = Math.min(48, largestY + 3);
|
||||
|
||||
const centerLine = Math.floor(largestY / 2 + smallestY / 2);
|
||||
|
||||
const { path } = PathFinder.search(
|
||||
room.getPositionAt(smallestX - 1, centerLine + 1)!,
|
||||
room.getPositionAt(smallestX - 1, centerLine - 1)!,
|
||||
{
|
||||
plainCost: 100,
|
||||
swampCost: 100,
|
||||
|
||||
roomCallback: function(roomName) {
|
||||
if (roomName != room.name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let costs = new PathFinder.CostMatrix;
|
||||
for (let x = 0; x < roomSize; x++) {
|
||||
for (let y = 0; y < roomSize; y++) {
|
||||
if (mask[getCoord(x, y)] === TERRAIN_MASK_WALL) {
|
||||
costs.set(x, y, 1);
|
||||
}
|
||||
if (structures[getCoord(x, y)] != null) {
|
||||
if (structures[getCoord(x, y)] == STRUCTURE_ROAD) {
|
||||
costs.set(x, y, 254);
|
||||
} else {
|
||||
costs.set(x, y, 255);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (let x = smallestX; x <= largestX; x++) {
|
||||
for (let y = smallestY; y <= largestY; y++) {
|
||||
costs.set(x, y, 255);
|
||||
}
|
||||
}
|
||||
for (let x = 0; x < smallestX; x++) {
|
||||
costs.set(x, centerLine, 255);
|
||||
}
|
||||
|
||||
return costs;
|
||||
},
|
||||
});
|
||||
|
||||
path.push(room.getPositionAt(smallestX - 1, centerLine)!);
|
||||
for (let i = 0; i < path.length; i++) {
|
||||
let s = structures[getCoord(path[i].x, path[i].y)] === STRUCTURE_ROAD
|
||||
|| structures[getCoord(path[i].x + 1, path[i].y)] === STRUCTURE_ROAD
|
||||
|| structures[getCoord(path[i].x - 1, path[i].y)] === STRUCTURE_ROAD
|
||||
|| structures[getCoord(path[i].x + 1, path[i].y + 1)] === STRUCTURE_ROAD
|
||||
|| structures[getCoord(path[i].x + 1, path[i].y - 1)] === STRUCTURE_ROAD
|
||||
|| structures[getCoord(path[i].x - 1, path[i].y + 1)] === STRUCTURE_ROAD
|
||||
|| structures[getCoord(path[i].x - 1, path[i].y - 1)] === STRUCTURE_ROAD
|
||||
|| structures[getCoord(path[i].x, path[i].y + 1)] === STRUCTURE_ROAD
|
||||
|| structures[getCoord(path[i].x, path[i].y - 1)] === STRUCTURE_ROAD
|
||||
? STRUCTURE_RAMPART
|
||||
: STRUCTURE_WALL;
|
||||
if (mask[getCoord(path[i].x, path[i].y)] != TERRAIN_MASK_WALL) {
|
||||
structures[getCoord(path[i].x, path[i].y)] = s;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
if (mask[getCoord(path[i].x+1, path[i].y)] != TERRAIN_MASK_WALL
|
||||
&& structures[getCoord(path[i].x+1, path[i].y)] != STRUCTURE_RAMPART) {
|
||||
structures[getCoord(path[i].x+1, path[i].y)] = s;
|
||||
}if (mask[getCoord(path[i].x-1, path[i].y)] != TERRAIN_MASK_WALL
|
||||
&& structures[getCoord(path[i].x-1, path[i].y)] != STRUCTURE_RAMPART) {
|
||||
structures[getCoord(path[i].x-1, path[i].y)] = s;
|
||||
}if (mask[getCoord(path[i].x, path[i].y+1)] != TERRAIN_MASK_WALL
|
||||
&& structures[getCoord(path[i].x, path[i].y+1)] != STRUCTURE_RAMPART) {
|
||||
structures[getCoord(path[i].x, path[i].y+1)] = s;
|
||||
}if (mask[getCoord(path[i].x, path[i].y-1)] != TERRAIN_MASK_WALL
|
||||
&& structures[getCoord(path[i].x, path[i].y-1)] != STRUCTURE_RAMPART) {
|
||||
structures[getCoord(path[i].x, path[i].y-1)] = s;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Render
|
||||
// renderHeatmap(controllerDistance, room.visual);
|
||||
/* for (let x = 0; x < roomSize; x++) {
|
||||
for (let y = 0; y < roomSize; y++) {
|
||||
if (structures[getCoord(x, y)] != null) {
|
||||
room.visual.structure(x, y, structures[getCoord(x, y)]);
|
||||
}
|
||||
}
|
||||
}
|
||||
room.visual.connectRoads(); */
|
||||
|
||||
let str = "";
|
||||
for (let i = 0; i < structures.length; i += 2) {
|
||||
str += String.fromCharCode(32 +
|
||||
(structureCoding.findIndex((s) => s == structures[i]))
|
||||
+ (structureCoding.findIndex((s) => s == structures[i + 1]) << 5)
|
||||
);
|
||||
}
|
||||
|
||||
room.memory._planner = str;
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue