Add lint-staged
This commit is contained in:
parent
28d2b2d38b
commit
2375765503
15 changed files with 511 additions and 211 deletions
|
|
@ -1,9 +1,8 @@
|
|||
declare global {
|
||||
interface RoomMemory {
|
||||
sources: {
|
||||
[id: Id<Source>]: SourceMemory;
|
||||
};
|
||||
sources: Record<Id<Source>, SourceMemory>;
|
||||
spawn: Id<StructureSpawn> | null;
|
||||
mineral: Id<Mineral> | null;
|
||||
_spawnCacheTimeout?: number;
|
||||
}
|
||||
|
||||
|
|
@ -19,6 +18,7 @@ declare global {
|
|||
interface Room {
|
||||
get sources(): Source[];
|
||||
get spawn(): StructureSpawn | null;
|
||||
get mineral(): Mineral | null;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -63,6 +63,23 @@ Object.defineProperty(Room.prototype, "spawn", {
|
|||
configurable: true,
|
||||
});
|
||||
|
||||
Object.defineProperty(Room.prototype, "mineral", {
|
||||
get: function (this: Room) {
|
||||
if (this == Room.prototype || this == undefined) return undefined;
|
||||
if (!this.memory.mineral) {
|
||||
const minerals = this.find(FIND_MINERALS);
|
||||
if (minerals.length > 0) {
|
||||
this.memory.mineral = minerals[0].id;
|
||||
}
|
||||
}
|
||||
return this.memory.mineral == null
|
||||
? null
|
||||
: Game.getObjectById(this.memory.mineral);
|
||||
},
|
||||
enumerable: false,
|
||||
configurable: true,
|
||||
});
|
||||
|
||||
Object.defineProperty(Source.prototype, "memory", {
|
||||
get: function (this: Source) {
|
||||
return this.room.memory.sources[this.id];
|
||||
|
|
@ -80,7 +97,7 @@ Object.defineProperty(Source.prototype, "container", {
|
|||
|| Game.getObjectById(this.memory.container) == null) {
|
||||
const containers = this.pos.findInRange(FIND_STRUCTURES, 1, {
|
||||
filter: (s: Structure) => s.structureType === STRUCTURE_CONTAINER,
|
||||
}) as StructureContainer[];
|
||||
});
|
||||
if (containers.length > 0) {
|
||||
this.memory.container = containers[0].id;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,29 +6,30 @@ const UNSET = 999;
|
|||
|
||||
declare global {
|
||||
interface RoomMemory {
|
||||
_planner: string
|
||||
_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 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++) {
|
||||
const 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) {
|
||||
|| arr[getCoord(x, y)] === OBSTACLE) {
|
||||
continue;
|
||||
}
|
||||
if (arr[getCoord(x + dx, y + dy)] === UNSET) {
|
||||
|
|
@ -60,13 +61,13 @@ const distanceTransform = (mask: (0 | 999 | 1000)[]): number[] => {
|
|||
} */
|
||||
|
||||
const createBuildSites = (room: Room) => {
|
||||
let structures = new Array();
|
||||
const structures = [];
|
||||
for (let i = 0; i < room.memory._planner.length; i++) {
|
||||
structures.push(
|
||||
structureCoding[(room.memory._planner.charCodeAt(i) - 32) & 0b11111]
|
||||
structureCoding[(room.memory._planner.charCodeAt(i) - 32) & 0b11111],
|
||||
);
|
||||
structures.push(
|
||||
structureCoding[(room.memory._planner.charCodeAt(i) - 32) >> 5]
|
||||
structureCoding[(room.memory._planner.charCodeAt(i) - 32) >> 5],
|
||||
);
|
||||
}
|
||||
for (let x = 0; x < roomSize; x++) {
|
||||
|
|
@ -127,10 +128,10 @@ const createBuildSites = (room: Room) => {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default profiler.registerFN(function RoomPlanner(room: Room) {
|
||||
if (room.controller == null || !room.controller.my) {
|
||||
if (!room.controller?.my) {
|
||||
return;
|
||||
}
|
||||
if (Game.cpu.bucket < 100 && room.name != "sim") {
|
||||
|
|
@ -144,21 +145,23 @@ export default profiler.registerFN(function RoomPlanner(room: Room) {
|
|||
return;
|
||||
}
|
||||
const terrain = room.getTerrain();
|
||||
let mask: number[] = new Array(roomSize * roomSize).fill(0);
|
||||
const 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;
|
||||
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
|
||||
))
|
||||
i === controllerCoord
|
||||
? 0
|
||||
: (
|
||||
t === TERRAIN_MASK_WALL ? OBSTACLE : UNSET
|
||||
)),
|
||||
);
|
||||
const buildCenter = wallDistance.map(
|
||||
(x, i) => [x * 2.5 - controllerDistance[i], i]).sort(
|
||||
|
|
@ -174,7 +177,7 @@ export default profiler.registerFN(function RoomPlanner(room: Room) {
|
|||
// Build structures
|
||||
//
|
||||
|
||||
let structures: (BuildableStructureConstant | null)[]
|
||||
const structures: (BuildableStructureConstant | null)[]
|
||||
= new Array(roomSize * roomSize);
|
||||
|
||||
// Build Roads + Containers
|
||||
|
|
@ -184,34 +187,37 @@ export default profiler.registerFN(function RoomPlanner(room: Room) {
|
|||
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; }
|
||||
.map(pos => pos == null ? null : ({ pos, highRange: true })));
|
||||
for (const 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;
|
||||
}
|
||||
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);
|
||||
const 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;
|
||||
}
|
||||
});
|
||||
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;
|
||||
? STRUCTURE_CONTAINER
|
||||
: STRUCTURE_ROAD;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -238,18 +244,18 @@ export default profiler.registerFN(function RoomPlanner(room: Room) {
|
|||
[buildCenterX - 2, buildCenterY + 2],
|
||||
[buildCenterX + 2, buildCenterY - 2],
|
||||
[buildCenterX + 2, buildCenterY + 2],
|
||||
].map(([x, y]) => [x, y, controllerDistance[x + y * roomSize]]
|
||||
].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) {
|
||||
for (const [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) {
|
||||
|| structures[getCoord(x + dx, y + dy)] === STRUCTURE_ROAD)
|
||||
&& mask[getCoord(x + dx, y + dy)] === 0) {
|
||||
continue;
|
||||
}
|
||||
ok = false;
|
||||
|
|
@ -269,7 +275,7 @@ export default profiler.registerFN(function RoomPlanner(room: Room) {
|
|||
}
|
||||
}
|
||||
if (!(dx === 0 && Math.abs(dy) === 3)
|
||||
&& !(dy === 0 && Math.abs(dx) === 3)) {
|
||||
&& !(dy === 0 && Math.abs(dx) === 3)) {
|
||||
structures[getCoord(x + dx, y + dy)] = STRUCTURE_LAB;
|
||||
}
|
||||
}
|
||||
|
|
@ -281,7 +287,8 @@ export default profiler.registerFN(function RoomPlanner(room: Room) {
|
|||
// Extensions
|
||||
let extensions = 0;
|
||||
a: for (let dx = 0; dx < roomSize / 2; dx++) {
|
||||
for (let dy = 0; dy < wallDistance[getCoord(buildCenterX, buildCenterY)]; dy++) {
|
||||
const dylimit = wallDistance[getCoord(buildCenterX, buildCenterY)];
|
||||
for (let dy = 0; dy < dylimit; 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;
|
||||
|
|
@ -289,8 +296,8 @@ export default profiler.registerFN(function RoomPlanner(room: Room) {
|
|||
break a;
|
||||
}
|
||||
if (structures[getCoord(x, y)] == null
|
||||
&& (mask[getCoord(x, y)] === 0
|
||||
|| mask[getCoord(x, y)] === TERRAIN_MASK_SWAMP)) {
|
||||
&& (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++) {
|
||||
|
|
@ -303,7 +310,8 @@ export default profiler.registerFN(function RoomPlanner(room: Room) {
|
|||
if (ok) {
|
||||
if (x % 2 == y % 3 || x % 3 == y % 2) {
|
||||
structures[getCoord(x, y)] = STRUCTURE_ROAD;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
structures[getCoord(x, y)] = STRUCTURE_EXTENSION;
|
||||
extensions++;
|
||||
}
|
||||
|
|
@ -326,8 +334,8 @@ export default profiler.registerFN(function RoomPlanner(room: Room) {
|
|||
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) {
|
||||
&& structures[getCoord(x, y)] != STRUCTURE_ROAD
|
||||
&& structures[getCoord(x, y)] != STRUCTURE_CONTAINER) {
|
||||
if (x < smallestX) {
|
||||
smallestX = x;
|
||||
}
|
||||
|
|
@ -358,12 +366,12 @@ export default profiler.registerFN(function RoomPlanner(room: Room) {
|
|||
plainCost: 100,
|
||||
swampCost: 100,
|
||||
|
||||
roomCallback: function(roomName) {
|
||||
roomCallback: function (roomName) {
|
||||
if (roomName != room.name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let costs = new PathFinder.CostMatrix;
|
||||
const 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) {
|
||||
|
|
@ -372,7 +380,8 @@ export default profiler.registerFN(function RoomPlanner(room: Room) {
|
|||
if (structures[getCoord(x, y)] != null) {
|
||||
if (structures[getCoord(x, y)] == STRUCTURE_ROAD) {
|
||||
costs.set(x, y, 254);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
costs.set(x, y, 255);
|
||||
}
|
||||
}
|
||||
|
|
@ -392,39 +401,42 @@ export default profiler.registerFN(function RoomPlanner(room: Room) {
|
|||
});
|
||||
|
||||
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
|
||||
for (const pos of path) {
|
||||
const s = structures[getCoord(pos.x, pos.y)] === STRUCTURE_ROAD
|
||||
|| structures[getCoord(pos.x + 1, pos.y)] === STRUCTURE_ROAD
|
||||
|| structures[getCoord(pos.x - 1, pos.y)] === STRUCTURE_ROAD
|
||||
|| structures[getCoord(pos.x + 1, pos.y + 1)] === STRUCTURE_ROAD
|
||||
|| structures[getCoord(pos.x + 1, pos.y - 1)] === STRUCTURE_ROAD
|
||||
|| structures[getCoord(pos.x - 1, pos.y + 1)] === STRUCTURE_ROAD
|
||||
|| structures[getCoord(pos.x - 1, pos.y - 1)] === STRUCTURE_ROAD
|
||||
|| structures[getCoord(pos.x, pos.y + 1)] === STRUCTURE_ROAD
|
||||
|| structures[getCoord(pos.x, pos.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 {
|
||||
if (mask[getCoord(pos.x, pos.y)] != TERRAIN_MASK_WALL) {
|
||||
structures[getCoord(pos.x, pos.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;
|
||||
if (mask[getCoord(pos.x + 1, pos.y)] != TERRAIN_MASK_WALL
|
||||
&& structures[getCoord(pos.x + 1, pos.y)] != STRUCTURE_RAMPART) {
|
||||
structures[getCoord(pos.x + 1, pos.y)] = s;
|
||||
}
|
||||
if (mask[getCoord(pos.x - 1, pos.y)] != TERRAIN_MASK_WALL
|
||||
&& structures[getCoord(pos.x - 1, pos.y)] != STRUCTURE_RAMPART) {
|
||||
structures[getCoord(pos.x - 1, pos.y)] = s;
|
||||
}
|
||||
if (mask[getCoord(pos.x, pos.y + 1)] != TERRAIN_MASK_WALL
|
||||
&& structures[getCoord(pos.x, pos.y + 1)] != STRUCTURE_RAMPART) {
|
||||
structures[getCoord(pos.x, pos.y + 1)] = s;
|
||||
}
|
||||
if (mask[getCoord(pos.x, pos.y - 1)] != TERRAIN_MASK_WALL
|
||||
&& structures[getCoord(pos.x, pos.y - 1)] != STRUCTURE_RAMPART) {
|
||||
structures[getCoord(pos.x, pos.y - 1)] = s;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Render
|
||||
// renderHeatmap(controllerDistance, room.visual);
|
||||
/* for (let x = 0; x < roomSize; x++) {
|
||||
|
|
@ -438,10 +450,10 @@ export default profiler.registerFN(function RoomPlanner(room: Room) {
|
|||
|
||||
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)
|
||||
);
|
||||
str += String.fromCharCode(32
|
||||
+ (structureCoding.findIndex(s => s == structures[i]))
|
||||
+ (structureCoding.findIndex(s => s == structures[i + 1]) << 5),
|
||||
);
|
||||
}
|
||||
|
||||
room.memory._planner = str;
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ const defaultOptions: HarvestOptions = {
|
|||
};
|
||||
|
||||
export const Harvest
|
||||
= (target: Source | Mineral<MineralConstant>,
|
||||
= (target: Source | Mineral,
|
||||
opts: Partial<HarvestOptions> = {}): TaskData => ({
|
||||
target,
|
||||
targetPos: target.pos,
|
||||
|
|
@ -33,7 +33,7 @@ export const runHarvest = profiler.registerFN((creep: Creep): TaskStatus => {
|
|||
return TaskStatus.DONE;
|
||||
}
|
||||
|
||||
const target = task.target as Source | Mineral<MineralConstant> | null;
|
||||
const target = task.target as Source | Mineral | null;
|
||||
const opts = task.options as HarvestOptions;
|
||||
const data = task.data as HarvestData;
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ export enum TaskType {
|
|||
Transfer,
|
||||
Build,
|
||||
Repair,
|
||||
Pickup
|
||||
Pickup,
|
||||
}
|
||||
|
||||
export enum TaskStatus {
|
||||
|
|
|
|||
|
|
@ -1,26 +1,53 @@
|
|||
import { runAction } from "../Actions/Action";
|
||||
import { harvestFromClosestActiveSource } from "../Actions/harvest";
|
||||
import { transferEnergy } from "../Actions/transferEnergy";
|
||||
import { upgradeController } from "../Actions/upgradeController";
|
||||
import {
|
||||
closestContainerWithEnergy,
|
||||
closestExtensionToFill,
|
||||
closestStorageToFill,
|
||||
closestTowerToFill,
|
||||
notNull,
|
||||
} from "../Actions/Util";
|
||||
import { withdrawEnergy } from "../Actions/withdrawEnergy";
|
||||
} from "./Util";
|
||||
import Tasks from "../Tasks";
|
||||
import { WorkerDefinition } from "./worker";
|
||||
|
||||
const action = (creep: Creep, spawn: StructureSpawn) => runAction(creep,
|
||||
withdrawEnergy(closestContainerWithEnergy(creep.pos)))
|
||||
.or(harvestFromClosestActiveSource())
|
||||
.andThen(transferEnergy(closestExtensionToFill(creep.pos)))
|
||||
.or(transferEnergy(spawn))
|
||||
.or(transferEnergy(closestTowerToFill(creep.pos)))
|
||||
.or(transferEnergy(closestStorageToFill(creep.pos, RESOURCE_ENERGY)))
|
||||
.or(notNull(creep.room.controller, upgradeController))
|
||||
.repeat();
|
||||
const assignTask = (creep: Creep) => {
|
||||
if (creep.store.energy > 0) {
|
||||
const ext = closestExtensionToFill(creep.pos);
|
||||
if (ext != null) {
|
||||
return Tasks.Transfer(ext);
|
||||
}
|
||||
if (creep.room.spawn?.store.getFreeCapacity(RESOURCE_ENERGY) ?? 0 > 0) {
|
||||
return Tasks.Transfer(creep.room.spawn!);
|
||||
}
|
||||
const tower = closestTowerToFill(creep.pos);
|
||||
if (tower != null) {
|
||||
return Tasks.Transfer(tower);
|
||||
}
|
||||
if (creep.room.controller != null) {
|
||||
if (creep.room.controller.ticksToDowngrade > 1000) {
|
||||
const urgentRepair = creep.pos.findClosestByRange(FIND_MY_STRUCTURES, {
|
||||
filter: s => s.hits < s.hitsMax * 0.3,
|
||||
});
|
||||
if (urgentRepair != null) {
|
||||
return Tasks.Repair(urgentRepair);
|
||||
}
|
||||
}
|
||||
return Tasks.Upgrade(creep.room.controller);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const resource = creep.pos.findClosestByRange(FIND_DROPPED_RESOURCES,
|
||||
{ filter: r => r.resourceType === RESOURCE_ENERGY });
|
||||
if (resource != null) {
|
||||
return Tasks.Pickup(resource);
|
||||
}
|
||||
const container = closestContainerWithEnergy(creep.pos);
|
||||
if (container != null) {
|
||||
return Tasks.Withdraw(container);
|
||||
}
|
||||
const source = creep.pos.findClosestByPath(FIND_SOURCES_ACTIVE);
|
||||
if (source != null) {
|
||||
return Tasks.Harvest(source);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
const body = (energy: number) => (
|
||||
energy < 100
|
||||
|
|
@ -30,7 +57,7 @@ const body = (energy: number) => (
|
|||
);
|
||||
|
||||
export const Clerk: WorkerDefinition = {
|
||||
runAction: action,
|
||||
assignTask,
|
||||
name: "clerk",
|
||||
requiredCreeps: () => 3,
|
||||
bodyDefinition: body,
|
||||
|
|
|
|||
|
|
@ -1,34 +1,61 @@
|
|||
import { runAction } from "../Actions/Action";
|
||||
import { buildConstructionSite } from "../Actions/buildConstructionSite";
|
||||
import { harvestFromClosestActiveSource } from "../Actions/harvest";
|
||||
import { repairStructure } from "../Actions/repairStructure";
|
||||
import { upgradeController } from "../Actions/upgradeController";
|
||||
import {
|
||||
closestContainerWithEnergy,
|
||||
closestStorageWithResource,
|
||||
notNull,
|
||||
} from "../Actions/Util";
|
||||
import { withdrawEnergy } from "../Actions/withdrawEnergy";
|
||||
} from "./Util";
|
||||
import Tasks from "../Tasks";
|
||||
import { WorkerDefinition } from "./worker";
|
||||
|
||||
const action = (creep: Creep) => runAction(creep,
|
||||
withdrawEnergy(closestStorageWithResource(creep.pos, RESOURCE_ENERGY)))
|
||||
.or(withdrawEnergy(closestContainerWithEnergy(creep.pos)))
|
||||
.or(harvestFromClosestActiveSource())
|
||||
.andThen(buildConstructionSite())
|
||||
.or(repairStructure())
|
||||
.or(notNull(creep.room.controller, upgradeController))
|
||||
.repeat();
|
||||
const assignTask = (creep: Creep) => {
|
||||
if (creep.store.energy === 0) {
|
||||
const storage = creep.room.storage;
|
||||
if (storage != null && storage.store.energy > 0) {
|
||||
return Tasks.Withdraw(storage);
|
||||
}
|
||||
const container = closestContainerWithEnergy(creep.pos);
|
||||
if (container != null) {
|
||||
return Tasks.Withdraw(container);
|
||||
}
|
||||
const source = creep.room.sources.find(s => s.energy > 0);
|
||||
if (source != null) {
|
||||
return Tasks.Harvest(source);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const urgentRepair = creep.pos.findClosestByRange(FIND_MY_STRUCTURES, {
|
||||
filter: s => s.hits < s.hitsMax * 0.3,
|
||||
});
|
||||
if (urgentRepair != null) {
|
||||
return Tasks.Repair(urgentRepair);
|
||||
}
|
||||
const constructionSite
|
||||
= creep.pos.findClosestByRange(FIND_MY_CONSTRUCTION_SITES);
|
||||
if (constructionSite != null) {
|
||||
return Tasks.Build(constructionSite);
|
||||
}
|
||||
const structure = creep.pos.findClosestByRange(FIND_MY_STRUCTURES, {
|
||||
filter: s => s.hits < s.hitsMax * 0.8,
|
||||
}) ?? creep.pos.findClosestByRange(FIND_STRUCTURES, {
|
||||
filter: s => s.hits < s.hitsMax * 0.8
|
||||
&& (s.structureType === STRUCTURE_WALL
|
||||
|| s.structureType === STRUCTURE_ROAD),
|
||||
});
|
||||
if (structure != null) {
|
||||
return Tasks.Repair(structure);
|
||||
}
|
||||
else if (creep.room.controller != null) {
|
||||
return Tasks.Upgrade(creep.room.controller);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
const body = (energy: number) =>
|
||||
new Array(Math.floor(energy / 250))
|
||||
.fill([WORK, MOVE, CARRY, CARRY]).reduce((x, y) => x.concat(y), []);
|
||||
|
||||
export const Constructor: WorkerDefinition = {
|
||||
runAction: action,
|
||||
assignTask,
|
||||
name: "constructor",
|
||||
requiredCreeps: (room: Room) =>
|
||||
room.find(FIND_CONSTRUCTION_SITES).length > 10 ? 2 : 1,
|
||||
requiredCreeps: () => 1,
|
||||
bodyDefinition: body,
|
||||
motivationalThougts: [
|
||||
"I 💗 making",
|
||||
|
|
|
|||
|
|
@ -1,29 +1,32 @@
|
|||
import { runAction } from "../Actions/Action";
|
||||
import { harvestFromClosestActiveSource } from "../Actions/harvest";
|
||||
import { transferEnergy } from "../Actions/transferEnergy";
|
||||
import { closestContainerToFill } from "../Actions/Util";
|
||||
import Tasks from "../Tasks";
|
||||
import { WorkerDefinition } from "./worker";
|
||||
|
||||
const action = (creep: Creep) => runAction(creep,
|
||||
harvestFromClosestActiveSource())
|
||||
.andThen(transferEnergy(closestContainerToFill(creep.pos)))
|
||||
.repeat();
|
||||
const assignTask = (creep: Creep) => {
|
||||
const source = creep.room.sources.find(
|
||||
s => s.container != null
|
||||
&& s.assignedCreeps.find(c => c.name.startsWith("miner")) == null);
|
||||
if (source != null) {
|
||||
return Tasks.Harvest(source, { stopWhenFull: false });
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
const body = (energy: number) => (
|
||||
energy < 300
|
||||
? []
|
||||
: ([WORK, WORK, MOVE, CARRY]
|
||||
.concat(new Array(Math.floor((energy - 300) / 100)).fill(WORK)))
|
||||
);
|
||||
const body = (energy: number) => {
|
||||
const maximumWorkParts
|
||||
= SOURCE_ENERGY_CAPACITY / ENERGY_REGEN_TIME / HARVEST_POWER;
|
||||
if (energy < BODYPART_COST.move + BODYPART_COST.work) {
|
||||
return [];
|
||||
}
|
||||
return [MOVE].concat(new Array(Math.min(maximumWorkParts,
|
||||
Math.floor((energy - BODYPART_COST.move) / BODYPART_COST.work)))
|
||||
.fill(WORK));
|
||||
};
|
||||
|
||||
export const Miner: WorkerDefinition = {
|
||||
runAction: action,
|
||||
assignTask,
|
||||
name: "miner",
|
||||
requiredCreeps: (room: Room) =>
|
||||
room.find(FIND_STRUCTURES,
|
||||
{ filter: { structureType: STRUCTURE_CONTAINER } }).length > 0
|
||||
? 4
|
||||
: 0,
|
||||
room.sources.filter(s => s.container != null).length,
|
||||
bodyDefinition: body,
|
||||
motivationalThougts: [
|
||||
"RocknStone",
|
||||
|
|
|
|||
|
|
@ -1,27 +1,33 @@
|
|||
import { runAction } from "../Actions/Action";
|
||||
import { harvestFromClosestActiveSource } from "../Actions/harvest";
|
||||
import { upgradeController } from "../Actions/upgradeController";
|
||||
import {
|
||||
closestContainerWithEnergy,
|
||||
closestStorageWithResource,
|
||||
notNull,
|
||||
} from "../Actions/Util";
|
||||
import { withdrawEnergy } from "../Actions/withdrawEnergy";
|
||||
import Tasks from "../Tasks";
|
||||
import { closestContainerWithEnergy, closestStorageWithResource } from "./Util";
|
||||
import { WorkerDefinition } from "./worker";
|
||||
|
||||
const action = (creep: Creep) => runAction(creep,
|
||||
withdrawEnergy(closestStorageWithResource(creep.pos, RESOURCE_ENERGY)))
|
||||
.or(withdrawEnergy(closestContainerWithEnergy(creep.pos)))
|
||||
.or(harvestFromClosestActiveSource())
|
||||
.andThen(notNull(creep.room.controller, upgradeController))
|
||||
.repeat();
|
||||
const assignTask = (creep: Creep) => {
|
||||
if (creep.store.energy > 0
|
||||
&& creep.room.controller != null) {
|
||||
return Tasks.Upgrade(creep.room.controller);
|
||||
}
|
||||
const storage = closestStorageWithResource(creep.pos, RESOURCE_ENERGY);
|
||||
if (storage != null) {
|
||||
return Tasks.Withdraw(storage);
|
||||
}
|
||||
const container = closestContainerWithEnergy(creep.pos);
|
||||
if (container != null) {
|
||||
return Tasks.Withdraw(container);
|
||||
}
|
||||
const source = creep.pos.findClosestByPath(FIND_SOURCES_ACTIVE);
|
||||
if (source != null) {
|
||||
return Tasks.Harvest(source);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
const body = (energy: number) =>
|
||||
new Array(Math.floor(energy / 300))
|
||||
.fill([WORK, WORK, MOVE, CARRY]).reduce((x, y) => x.concat(y), []);
|
||||
|
||||
export const Upgrader: WorkerDefinition = {
|
||||
runAction: action,
|
||||
assignTask,
|
||||
name: "upgrader",
|
||||
requiredCreeps: () => 1,
|
||||
bodyDefinition: body,
|
||||
|
|
|
|||
|
|
@ -1,38 +1,37 @@
|
|||
import profiler from "screeps-profiler";
|
||||
import { TaskData } from "../Tasks/Task";
|
||||
|
||||
export interface WorkerDefinition {
|
||||
runAction: (creep: Creep, spawn: StructureSpawn) => void;
|
||||
assignTask: (creep: Creep) => TaskData | null;
|
||||
name: string;
|
||||
requiredCreeps: (room: Room) => number;
|
||||
bodyDefinition: (energy: number) => BodyPartConstant[];
|
||||
motivationalThougts?: string[];
|
||||
}
|
||||
|
||||
export const spawnWorkers
|
||||
= (spawn: StructureSpawn, workers: WorkerDefinition[]): void => {
|
||||
export const spawnWorkers = profiler.registerFN(
|
||||
(spawn: StructureSpawn, workers: WorkerDefinition[]): void => {
|
||||
for (const worker of workers) {
|
||||
for (let i = 0; i < worker.requiredCreeps(spawn.room); i++) {
|
||||
const ret = spawn.spawnCreep(worker.bodyDefinition(
|
||||
spawn.store.getCapacity(RESOURCE_ENERGY)
|
||||
+ (spawn.room.find(FIND_MY_STRUCTURES,
|
||||
{ filter: { structureType: STRUCTURE_EXTENSION } }).length
|
||||
* (Object.keys(Game.creeps).length < 2
|
||||
? (25 * Object.keys(Game.creeps).length)
|
||||
: 50))), worker.name + i.toString());
|
||||
const ret = spawn.spawnCreep(
|
||||
worker.bodyDefinition(spawn.room.energyCapacityAvailable),
|
||||
worker.name + i.toString());
|
||||
if (ret === OK || ret === ERR_NOT_ENOUGH_ENERGY) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}, "spawnWorkers");
|
||||
|
||||
export const runWorkers
|
||||
= (spawn: StructureSpawn, workers: WorkerDefinition[]): void => {
|
||||
export const runWorkers = profiler.registerFN(
|
||||
function runWorkers(workers: WorkerDefinition[]) {
|
||||
for (const worker of workers) {
|
||||
for (const creep of Object.values(Game.creeps)) {
|
||||
if (creep.spawning) {
|
||||
continue;
|
||||
}
|
||||
if (creep.name.startsWith(worker.name)) {
|
||||
worker.runAction(creep, spawn);
|
||||
creep.run(worker.assignTask);
|
||||
if (worker.motivationalThougts != null && Math.random() < 0.1) {
|
||||
creep.say(
|
||||
worker.motivationalThougts[
|
||||
|
|
@ -42,4 +41,4 @@ export const runWorkers
|
|||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
|
|
|||
38
src/index.ts
38
src/index.ts
|
|
@ -1,14 +1,14 @@
|
|||
import { buildContainers } from "./RoomPlanner/Blueprints/Containers";
|
||||
import { buildExtentions } from "./RoomPlanner/Blueprints/Extensions";
|
||||
import { buildRoads } from "./RoomPlanner/Blueprints/Roads";
|
||||
import { Clerk } from "./Workers/Clerk";
|
||||
import { Constructor } from "./Workers/Constructor";
|
||||
import { Miner } from "./Workers/Miner";
|
||||
import { Upgrader } from "./Workers/Upgrader";
|
||||
import { runWorkers, spawnWorkers } from "./Workers/worker";
|
||||
import "../deps/Traveler/Traveler";
|
||||
import profiler from "screeps-profiler";
|
||||
import "./Proto";
|
||||
import RoomPlanner from "./RoomPlanner";
|
||||
|
||||
const runTowers = (spawn: StructureSpawn) => {
|
||||
const runTowers = profiler.registerFN((spawn: StructureSpawn) => {
|
||||
const towers: StructureTower[] = spawn.room.find(FIND_MY_STRUCTURES,
|
||||
{ filter: s => s.structureType === STRUCTURE_TOWER });
|
||||
for (const tower of towers) {
|
||||
|
|
@ -34,28 +34,32 @@ const runTowers = (spawn: StructureSpawn) => {
|
|||
console.log(tower.repair(str));
|
||||
}
|
||||
};
|
||||
};
|
||||
}, "runTowers");
|
||||
|
||||
export function loop() {
|
||||
profiler.enable();
|
||||
export const loop = profiler.wrap(() => {
|
||||
const spawn = Game.spawns.Spawn1;
|
||||
const controller = spawn.room.controller;
|
||||
if (!controller) {
|
||||
return;
|
||||
}
|
||||
const workerTypes = [Clerk, Upgrader, Miner, Constructor];
|
||||
spawnWorkers(spawn, workerTypes);
|
||||
runWorkers(spawn, workerTypes);
|
||||
runTowers(spawn);
|
||||
if (Game.time % 100 === 0) {
|
||||
buildRoads(spawn.room);
|
||||
if (spawn.room.name != "sim") {
|
||||
const workerTypes = [Clerk, Upgrader, Miner, Constructor];
|
||||
spawnWorkers(spawn, workerTypes);
|
||||
runWorkers(workerTypes);
|
||||
runTowers(spawn);
|
||||
}
|
||||
if (Game.time % 100 === 50) {
|
||||
buildExtentions(spawn.room);
|
||||
|
||||
for (const creep in Memory.creeps) {
|
||||
if (!(creep in Game.creeps)) {
|
||||
delete Memory.creeps[creep];
|
||||
}
|
||||
}
|
||||
if (Game.time % 100 === 25) {
|
||||
buildContainers(spawn.room);
|
||||
if (Game.time % 101 === 0) {
|
||||
Game.profiler.email(100);
|
||||
}
|
||||
if (Game.cpu.bucket === 10000) {
|
||||
Game.cpu.generatePixel();
|
||||
}
|
||||
}
|
||||
RoomPlanner(spawn.room);
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue