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,62 +0,0 @@
|
||||||
declare global {
|
|
||||||
interface CreepMemory {
|
|
||||||
state?: number;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ChainableAction {
|
|
||||||
or: (action: Action) => ChainableAction;
|
|
||||||
and: (action: Action) => ChainableAction;
|
|
||||||
andThen: (action: Action) => ChainableAction;
|
|
||||||
repeat: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const NoOp: Action = (creep: Creep, state: number = 0) => ({
|
|
||||||
or: () => NoOp(creep, state),
|
|
||||||
and: () => NoOp(creep, state),
|
|
||||||
andThen: () => NoOp(creep, state),
|
|
||||||
repeat: () => {},
|
|
||||||
});
|
|
||||||
|
|
||||||
export const Success: Action = (creep: Creep, state: number = 0) => ({
|
|
||||||
or: () => Success(creep, state),
|
|
||||||
and: (action: Action) => action(creep, state),
|
|
||||||
andThen: (action: Action) => {
|
|
||||||
creep.memory.state = state + 1;
|
|
||||||
return action(creep, state + 1);
|
|
||||||
},
|
|
||||||
repeat: () => {
|
|
||||||
creep.memory.state = 0;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export const InProgress: Action = (creep: Creep, state: number = 0) => ({
|
|
||||||
or: () => InProgress(creep, state),
|
|
||||||
and: (action: Action) => action(creep, state),
|
|
||||||
andThen: () => NoOp(creep, state),
|
|
||||||
repeat: () => {},
|
|
||||||
});
|
|
||||||
|
|
||||||
export const Fail: Action = (creep: Creep, state: number = 0) => ({
|
|
||||||
or: (action: Action) => action(creep, state),
|
|
||||||
and: () => NoOp(creep, state),
|
|
||||||
andThen: () => NoOp(creep, state),
|
|
||||||
repeat: () => {
|
|
||||||
console.log("Warning: Last task in series failed for creep " + creep.name);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export const createAction
|
|
||||||
= (name: string, action: (c: Creep) => Action): Action => {
|
|
||||||
return (creep: Creep, state: number = 0) => {
|
|
||||||
if ((creep.memory.state ?? 0) > state) {
|
|
||||||
return Success(creep, state);
|
|
||||||
}
|
|
||||||
return action(creep)(creep, state);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export const runAction = (creep: Creep, action: Action): ChainableAction =>
|
|
||||||
action(creep);
|
|
||||||
|
|
||||||
export type Action = (creep: Creep, state?: number) => ChainableAction;
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
import { createAction, Fail, InProgress, Success } from "./Action";
|
|
||||||
import { moveTo } from "./moveTo";
|
|
||||||
|
|
||||||
export const buildConstructionSite = () =>
|
|
||||||
createAction("buildConstructionSite", (creep: Creep) => {
|
|
||||||
const cs = creep.pos.findClosestByRange(FIND_CONSTRUCTION_SITES);
|
|
||||||
if (!cs) {
|
|
||||||
return Fail;
|
|
||||||
}
|
|
||||||
switch (creep.build(cs)) {
|
|
||||||
case OK: {
|
|
||||||
return InProgress;
|
|
||||||
}
|
|
||||||
case ERR_NOT_ENOUGH_RESOURCES: {
|
|
||||||
return Success;
|
|
||||||
}
|
|
||||||
case ERR_NOT_IN_RANGE: {
|
|
||||||
return moveTo(cs);
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
return Fail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
import { createAction, Fail, InProgress, Success } from "./Action";
|
|
||||||
import { moveTo } from "./moveTo";
|
|
||||||
|
|
||||||
export const harvestFromClosestActiveSource = () =>
|
|
||||||
createAction("harvestFromClosestActiveSource", (creep: Creep) => {
|
|
||||||
const source = creep.pos.findClosestByPath(FIND_SOURCES_ACTIVE);
|
|
||||||
if (!source) {
|
|
||||||
return Fail;
|
|
||||||
}
|
|
||||||
if (creep.store.getFreeCapacity(RESOURCE_ENERGY) === 0) {
|
|
||||||
return Success;
|
|
||||||
}
|
|
||||||
switch (creep.harvest(source)) {
|
|
||||||
case OK: {
|
|
||||||
return InProgress;
|
|
||||||
}
|
|
||||||
case ERR_NOT_IN_RANGE: {
|
|
||||||
return moveTo(source);
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
return Fail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
import { createAction, Fail, InProgress } from "./Action";
|
|
||||||
|
|
||||||
export const moveTo = (pos: _HasRoomPosition | RoomPosition) =>
|
|
||||||
createAction("moveTo", (creep: Creep) => {
|
|
||||||
switch (creep.travelTo(pos)) {
|
|
||||||
case OK: {
|
|
||||||
return InProgress;
|
|
||||||
}
|
|
||||||
case ERR_TIRED: {
|
|
||||||
return InProgress;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
return Fail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
||||||
import { createAction, Fail, InProgress, Success } from "./Action";
|
|
||||||
import { moveTo } from "./moveTo";
|
|
||||||
|
|
||||||
export const repairStructure = () =>
|
|
||||||
createAction("repairStructure", (creep: Creep) => {
|
|
||||||
const cs = creep.pos.findClosestByRange(FIND_STRUCTURES,
|
|
||||||
{ filter: str => str.hits < str.hitsMax * 0.8 });
|
|
||||||
if (!cs) {
|
|
||||||
return Fail;
|
|
||||||
}
|
|
||||||
switch (creep.repair(cs)) {
|
|
||||||
case OK: {
|
|
||||||
return InProgress;
|
|
||||||
}
|
|
||||||
case ERR_NOT_ENOUGH_RESOURCES: {
|
|
||||||
return Success;
|
|
||||||
}
|
|
||||||
case ERR_NOT_IN_RANGE: {
|
|
||||||
return moveTo(cs);
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
return Fail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
@ -1,33 +0,0 @@
|
||||||
import { createAction, Fail, InProgress, Success } from "./Action";
|
|
||||||
import { moveTo } from "./moveTo";
|
|
||||||
|
|
||||||
type TransferTarget = Creep
|
|
||||||
| StructureSpawn
|
|
||||||
| StructureContainer
|
|
||||||
| StructureStorage
|
|
||||||
| StructureExtension
|
|
||||||
| StructureTower;
|
|
||||||
|
|
||||||
export const transferEnergy = (target: TransferTarget | null) =>
|
|
||||||
createAction("transferEnergy", (creep: Creep) => {
|
|
||||||
if (target == null) {
|
|
||||||
return Fail;
|
|
||||||
}
|
|
||||||
if (target.store.getFreeCapacity(RESOURCE_ENERGY) === 0) {
|
|
||||||
return Fail;
|
|
||||||
}
|
|
||||||
switch (creep.transfer(target, RESOURCE_ENERGY)) {
|
|
||||||
case OK: {
|
|
||||||
return InProgress;
|
|
||||||
}
|
|
||||||
case ERR_NOT_ENOUGH_RESOURCES: {
|
|
||||||
return Success;
|
|
||||||
}
|
|
||||||
case ERR_NOT_IN_RANGE: {
|
|
||||||
return moveTo(target);
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
return Fail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
import { createAction, Fail, InProgress, Success } from "./Action";
|
|
||||||
import { moveTo } from "./moveTo";
|
|
||||||
|
|
||||||
export const upgradeController = (controller: StructureController) =>
|
|
||||||
createAction("upgradeController", (creep: Creep) => {
|
|
||||||
switch (creep.upgradeController(controller)) {
|
|
||||||
case OK: {
|
|
||||||
return InProgress;
|
|
||||||
}
|
|
||||||
case ERR_NOT_ENOUGH_RESOURCES: {
|
|
||||||
return Success;
|
|
||||||
}
|
|
||||||
case ERR_NOT_IN_RANGE: {
|
|
||||||
return moveTo(controller);
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
return Fail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
import { createAction, Fail, InProgress, Success } from "./Action";
|
|
||||||
import { moveTo } from "./moveTo";
|
|
||||||
|
|
||||||
export const withdrawEnergy
|
|
||||||
= (target: StructureContainer | StructureStorage | null) =>
|
|
||||||
createAction("withdrawEnergy", (creep: Creep) => {
|
|
||||||
if (target == null) {
|
|
||||||
return Fail;
|
|
||||||
}
|
|
||||||
if (target.store.getUsedCapacity(RESOURCE_ENERGY) === 0) {
|
|
||||||
return Fail;
|
|
||||||
}
|
|
||||||
switch (creep.withdraw(target, RESOURCE_ENERGY)) {
|
|
||||||
case OK: {
|
|
||||||
return InProgress;
|
|
||||||
}
|
|
||||||
case ERR_FULL: {
|
|
||||||
return Success;
|
|
||||||
}
|
|
||||||
case ERR_NOT_IN_RANGE: {
|
|
||||||
return moveTo(target);
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
return Fail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
@ -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;
|
||||||
|
});
|
||||||
|
|
@ -16,7 +16,7 @@ export const runBuild = profiler.registerFN((creep: Creep): TaskStatus => {
|
||||||
return TaskStatus.DONE;
|
return TaskStatus.DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (creep.store.getUsedCapacity(RESOURCE_ENERGY) === 0) {
|
if (creep.store.energy === 0) {
|
||||||
return TaskStatus.DONE;
|
return TaskStatus.DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -28,7 +28,6 @@ export const runBuild = profiler.registerFN((creep: Creep): TaskStatus => {
|
||||||
if (target == null
|
if (target == null
|
||||||
|| creep.build(target) === ERR_NOT_IN_RANGE) {
|
|| creep.build(target) === ERR_NOT_IN_RANGE) {
|
||||||
creep.travelTo(task.targetPos);
|
creep.travelTo(task.targetPos);
|
||||||
return TaskStatus.IN_PROGRESS;
|
|
||||||
}
|
}
|
||||||
return TaskStatus.DONE;
|
return TaskStatus.IN_PROGRESS;
|
||||||
}, "runBuild");
|
}, "runBuild");
|
||||||
|
|
|
||||||
35
src/Tasks/Pickup.ts
Normal file
35
src/Tasks/Pickup.ts
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
import { TaskData, TaskStatus, TaskType } from "./Task";
|
||||||
|
|
||||||
|
export const Pickup
|
||||||
|
= (target: Resource): TaskData => ({
|
||||||
|
target,
|
||||||
|
targetPos: target.pos,
|
||||||
|
type: TaskType.Pickup,
|
||||||
|
options: {},
|
||||||
|
data: { resource: target.resourceType },
|
||||||
|
});
|
||||||
|
|
||||||
|
export const runPickup = (creep: Creep): TaskStatus => {
|
||||||
|
const task = creep.task;
|
||||||
|
if (task == null) {
|
||||||
|
return TaskStatus.DONE;
|
||||||
|
}
|
||||||
|
if (task.target == null && task.targetPos.roomName == creep.room.name) {
|
||||||
|
return TaskStatus.DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
const target = task.target as Resource;
|
||||||
|
const resource: ResourceConstant
|
||||||
|
= (task.data as { resource: ResourceConstant }).resource;
|
||||||
|
|
||||||
|
if (creep.store.getFreeCapacity(resource) == 0) {
|
||||||
|
return TaskStatus.DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target == null
|
||||||
|
|| creep.pickup(target) === ERR_NOT_IN_RANGE) {
|
||||||
|
creep.travelTo(task.targetPos);
|
||||||
|
return TaskStatus.IN_PROGRESS;
|
||||||
|
}
|
||||||
|
return TaskStatus.DONE;
|
||||||
|
};
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import {
|
import {
|
||||||
packId, packPos, unpackId, unpackPos,
|
packPos, unpackPos,
|
||||||
} from "../../deps/screeps-packrat/src/packrat";
|
} from "../../deps/screeps-packrat/src/packrat";
|
||||||
|
|
||||||
export enum TaskType {
|
export enum TaskType {
|
||||||
|
|
@ -9,6 +9,7 @@ export enum TaskType {
|
||||||
Transfer,
|
Transfer,
|
||||||
Build,
|
Build,
|
||||||
Repair,
|
Repair,
|
||||||
|
Pickup
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum TaskStatus {
|
export enum TaskStatus {
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,9 @@ export const runWithdraw = (creep: Creep): TaskStatus => {
|
||||||
if (task == null) {
|
if (task == null) {
|
||||||
return TaskStatus.DONE;
|
return TaskStatus.DONE;
|
||||||
}
|
}
|
||||||
|
if (task.target == null && task.targetPos.roomName == creep.room.name) {
|
||||||
|
return TaskStatus.DONE;
|
||||||
|
}
|
||||||
|
|
||||||
const target = task.target as Structure | Tombstone | Ruin;
|
const target = task.target as Structure | Tombstone | Ruin;
|
||||||
const opts = task.options as WithdrawOptions;
|
const opts = task.options as WithdrawOptions;
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import { runTransfer, Transfer } from "./Transfer";
|
||||||
import { Build, runBuild } from "./Build";
|
import { Build, runBuild } from "./Build";
|
||||||
import { Repair, runRepair } from "./Repair";
|
import { Repair, runRepair } from "./Repair";
|
||||||
import profiler from "screeps-profiler";
|
import profiler from "screeps-profiler";
|
||||||
|
import { Pickup, runPickup } from "./Pickup";
|
||||||
export { TaskType, TaskStatus } from "./Task";
|
export { TaskType, TaskStatus } from "./Task";
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
|
@ -29,6 +30,8 @@ const runTask = profiler.registerFN((creep: Creep): TaskStatus => {
|
||||||
return runBuild(creep);
|
return runBuild(creep);
|
||||||
case TaskType.Repair:
|
case TaskType.Repair:
|
||||||
return runRepair(creep);
|
return runRepair(creep);
|
||||||
|
case TaskType.Pickup:
|
||||||
|
return runPickup(creep);
|
||||||
default:
|
default:
|
||||||
return TaskStatus.DONE;
|
return TaskStatus.DONE;
|
||||||
}
|
}
|
||||||
|
|
@ -45,12 +48,16 @@ Creep.prototype.run = function (generator?: (creep: Creep) => TaskData | null) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default profiler.registerObject({
|
const Tasks = {
|
||||||
Harvest,
|
Harvest,
|
||||||
Upgrade,
|
Upgrade,
|
||||||
Withdraw,
|
Withdraw,
|
||||||
Transfer,
|
Transfer,
|
||||||
Build,
|
Build,
|
||||||
Repair,
|
Repair,
|
||||||
|
Pickup,
|
||||||
...TaskStatus,
|
...TaskStatus,
|
||||||
}, "Tasks");
|
};
|
||||||
|
profiler.registerObject(Tasks, "Tasks");
|
||||||
|
|
||||||
|
export default Tasks;
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,3 @@
|
||||||
import { Action, Fail } from "../Actions/Action";
|
|
||||||
|
|
||||||
export const notNull
|
|
||||||
= <T>(x: T | null | undefined, f: (y: T) => Action): Action => {
|
|
||||||
if (x == null) {
|
|
||||||
return Fail;
|
|
||||||
}
|
|
||||||
return f(x);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const closestTowerToFill = (pos: RoomPosition): StructureTower | null =>
|
export const closestTowerToFill = (pos: RoomPosition): StructureTower | null =>
|
||||||
pos.findClosestByRange(FIND_MY_STRUCTURES, {
|
pos.findClosestByRange(FIND_MY_STRUCTURES, {
|
||||||
filter: structure => structure.structureType === STRUCTURE_TOWER
|
filter: structure => structure.structureType === STRUCTURE_TOWER
|
||||||
7
src/screeps-profiler.d.ts
vendored
7
src/screeps-profiler.d.ts
vendored
|
|
@ -1,7 +0,0 @@
|
||||||
declare module "screeps-profiler" {
|
|
||||||
export const registerFN: <T extends Function>(f: T, n?: string) => T;
|
|
||||||
export const registerObject: <T extends Object>(f: T, n?: string) => T;
|
|
||||||
export const registerClass: <T extends Object>(f: T, n?: string) => T;
|
|
||||||
export const enable: () => void;
|
|
||||||
export const wrap: (f: () => void) => () => void;
|
|
||||||
};
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue