diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 95e95f0..0000000 --- a/.eslintrc.js +++ /dev/null @@ -1,12 +0,0 @@ -module.exports = { - extends: ['eslint:recommended', 'plugin:@typescript-eslint/strict'], - parser: '@typescript-eslint/parser', - plugins: ['@typescript-eslint'], - root: true, - parserOptions: { - "project": ["tsconfig.json"] - }, - rules: { - 'no-unused-vars': "off" - } -}; \ No newline at end of file diff --git a/eslint.config.mts b/eslint.config.mts index 32d443b..d9991f8 100644 --- a/eslint.config.mts +++ b/eslint.config.mts @@ -21,7 +21,7 @@ export default defineConfig([ "@stylistic/max-len": ["error", { code: 80, tabWidth: 2 }], }, }, - tseslint.configs.recommended, + tseslint.configs.strictTypeChecked, tseslint.configs.stylisticTypeChecked, stylistic.configs.customize({ quotes: "double", diff --git a/src/Proto/index.ts b/src/Proto/index.ts index fc49a2f..620d6d5 100644 --- a/src/Proto/index.ts +++ b/src/Proto/index.ts @@ -1,6 +1,6 @@ declare global { interface RoomMemory { - sources: Record, SourceMemory>; + sources?: Record, SourceMemory>; spawn: Id | null; mineral: Id | null; _spawnCacheTimeout?: number; @@ -23,8 +23,8 @@ declare global { } Object.defineProperty(Room.prototype, "sources", { - get: function (this: Room) { - if (this == Room.prototype || this == undefined) return undefined; + get: function (this: Room | undefined): Source[] { + if (this == Room.prototype || this == undefined) return []; if (!this.memory.sources) { this.memory.sources = {}; const sources = this.find(FIND_SOURCES); @@ -34,14 +34,15 @@ Object.defineProperty(Room.prototype, "sources", { }; } } - return Object.keys(this.memory.sources).map(Game.getObjectById); + return Object.keys(this.memory.sources) + .map(s => Game.getObjectById(s as Id)) as Source[]; }, enumerable: true, configurable: true, }); Object.defineProperty(Room.prototype, "spawn", { - get: function (this: Room) { + get: function (this: Room | undefined) { if (this == Room.prototype || this == undefined) return undefined; if (!this.memory.spawn) { if (this.memory._spawnCacheTimeout == null @@ -64,7 +65,7 @@ Object.defineProperty(Room.prototype, "spawn", { }); Object.defineProperty(Room.prototype, "mineral", { - get: function (this: Room) { + get: function (this: Room | undefined) { if (this == Room.prototype || this == undefined) return undefined; if (!this.memory.mineral) { const minerals = this.find(FIND_MINERALS); @@ -82,9 +83,27 @@ Object.defineProperty(Room.prototype, "mineral", { Object.defineProperty(Source.prototype, "memory", { get: function (this: Source) { + if (!this.room.memory.sources) { + this.room.memory.sources = {}; + const sources = this.room.find(FIND_SOURCES); + for (const source of sources) { + this.room.memory.sources[source.id] = { + container: null, + }; + } + } return this.room.memory.sources[this.id]; }, set: function (this: Source, mem: SourceMemory) { + if (!this.room.memory.sources) { + this.room.memory.sources = {}; + const sources = this.room.find(FIND_SOURCES); + for (const source of sources) { + this.room.memory.sources[source.id] = { + container: null, + }; + } + } this.room.memory.sources[this.id] = mem; }, enumerable: false, @@ -99,7 +118,7 @@ Object.defineProperty(Source.prototype, "container", { filter: (s: Structure) => s.structureType === STRUCTURE_CONTAINER, }); if (containers.length > 0) { - this.memory.container = containers[0].id; + this.memory.container = containers[0].id as Id; } } return this.memory.container == null diff --git a/src/RoomPlanner/index.ts b/src/RoomPlanner/index.ts index 479a33f..43522d7 100644 --- a/src/RoomPlanner/index.ts +++ b/src/RoomPlanner/index.ts @@ -6,7 +6,7 @@ const UNSET = 999; declare global { interface RoomMemory { - _planner: string; + _planner?: string; } } const structureCoding: (BuildableStructureConstant | null)[] @@ -21,7 +21,7 @@ const getCoord = (x: number, y: number): number => { }; const distanceTransform = (mask: (0 | 999 | 1000)[]): number[] => { - const arr: number[] = new Array(...mask); + const arr = new Array(...mask) as number[]; 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++) { @@ -61,7 +61,10 @@ const distanceTransform = (mask: (0 | 999 | 1000)[]): number[] => { } */ const createBuildSites = (room: Room) => { - const structures = []; + if (room.memory._planner == null) { + return; + } + const structures = [] as (BuildableStructureConstant | null)[]; for (let i = 0; i < room.memory._planner.length; i++) { structures.push( structureCoding[(room.memory._planner.charCodeAt(i) - 32) & 0b11111], @@ -72,56 +75,57 @@ const createBuildSites = (room: Room) => { } for (let x = 0; x < roomSize; x++) { for (let y = 0; y < roomSize; y++) { + const struct = structures[getCoord(x, y)]; if ((room.controller?.level ?? 0) < 2 - && structures[getCoord(x, y)] != STRUCTURE_CONTAINER) { + && struct != 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)) { + && !(struct == STRUCTURE_CONTAINER + || struct == STRUCTURE_ROAD + || struct == 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)) { + && !(struct == STRUCTURE_CONTAINER + || struct == STRUCTURE_ROAD + || struct == STRUCTURE_EXTENSION + || struct == STRUCTURE_RAMPART + || struct == 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)) { + && !(struct == STRUCTURE_CONTAINER + || struct == STRUCTURE_ROAD + || struct == STRUCTURE_EXTENSION + || struct == STRUCTURE_RAMPART + || struct == STRUCTURE_TOWER + || struct == 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)) { + && !(struct == STRUCTURE_CONTAINER + || struct == STRUCTURE_ROAD + || struct == STRUCTURE_EXTENSION + || struct == STRUCTURE_RAMPART + || struct == STRUCTURE_TOWER + || struct == STRUCTURE_WALL + || struct == 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)) { + && !(struct == STRUCTURE_CONTAINER + || struct == STRUCTURE_ROAD + || struct == STRUCTURE_EXTENSION + || struct == STRUCTURE_RAMPART + || struct == STRUCTURE_TOWER + || struct == STRUCTURE_WALL + || struct == STRUCTURE_STORAGE + || struct == STRUCTURE_EXTRACTOR)) { continue; } - if (structures[getCoord(x, y)] != null) { - if (room.createConstructionSite(x, y, structures[getCoord(x, y)]) + if (struct != null) { + if (room.createConstructionSite(x, y, struct) === ERR_FULL) { return; } @@ -145,7 +149,7 @@ export default profiler.registerFN(function RoomPlanner(room: Room) { return; } const terrain = room.getTerrain(); - const mask: number[] = new Array(roomSize * roomSize).fill(0); + const mask = new Array(roomSize * roomSize).fill(0) as number[]; for (let x = 0; x < roomSize; x++) { for (let y = 0; y < roomSize; y++) { mask[getCoord(x, y)] = terrain.get(x, y); @@ -154,7 +158,7 @@ export default profiler.registerFN(function RoomPlanner(room: Room) { 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; + = room.controller.pos.x + room.controller.pos.y * roomSize; const controllerDistance = distanceTransform( mask.map((t, i) => i === controllerCoord @@ -168,7 +172,10 @@ export default profiler.registerFN(function RoomPlanner(room: Room) { (a, b) => b[0] - a[0])[0][1]; const buildCenterX = buildCenter % roomSize; const buildCenterY = Math.floor(buildCenter / roomSize); - const buildCenterPos = room.getPositionAt(buildCenterX, buildCenterY)!; + const buildCenterPos = room.getPositionAt(buildCenterX, buildCenterY); + if (buildCenterPos == null) { + return; + } /* room.visual.rect(buildCenterX - 0.5, buildCenterY - 0.5, 1, 1, { stroke: "#FF0000", }); */ @@ -178,22 +185,22 @@ export default profiler.registerFN(function RoomPlanner(room: Room) { // const structures: (BuildableStructureConstant | null)[] - = new Array(roomSize * roomSize); + = new Array(roomSize * roomSize) as (BuildableStructureConstant | null)[]; // 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 }))); + .concat([room.find(FIND_EXIT_TOP).at(0), + room.find(FIND_EXIT_LEFT).at(0), + room.find(FIND_EXIT_RIGHT).at(0), + room.find(FIND_EXIT_BOTTOM).at(0)] + .map(pos => pos != null ? ({ pos }) : null)); for (const target of roadTargets) { if (target == null) { continue; } const { path } = PathFinder.search(buildCenterPos, - { pos: target.pos, range: "highRange" in target ? 3 : 1 }, { + { pos: target.pos, range: 1 }, { swampCost: 10, plainCost: 2, roomCallback: function (roomName) { @@ -358,82 +365,86 @@ export default profiler.registerFN(function RoomPlanner(room: Room) { largestY = Math.min(48, largestY + 3); const centerLine = Math.floor(largestY / 2 + smallestY / 2); + const wallStart = room.getPositionAt(smallestX - 1, centerLine + 1); + const wallEnd = room.getPositionAt(smallestX - 1, centerLine - 1); + if (wallStart != null && wallEnd != null) { + const { path } = PathFinder.search(wallStart, wallEnd, + { + plainCost: 100, + swampCost: 100, - 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; + } - roomCallback: function (roomName) { - if (roomName != room.name) { - return false; - } - - 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) { - costs.set(x, y, 1); - } - if (structures[getCoord(x, y)] != null) { - if (structures[getCoord(x, y)] == STRUCTURE_ROAD) { - costs.set(x, y, 254); + 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) { + costs.set(x, y, 1); } - else { - costs.set(x, y, 255); + 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 = 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); } - } - for (let x = 0; x < smallestX; x++) { - costs.set(x, centerLine, 255); - } - return costs; - }, - }); + return costs; + }, + }); - path.push(room.getPositionAt(smallestX - 1, centerLine)!); - 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(pos.x, pos.y)] != TERRAIN_MASK_WALL) { - structures[getCoord(pos.x, pos.y)] = s; + const centerWallPiece = room.getPositionAt(smallestX - 1, centerLine); + if (centerWallPiece != null) { + path.push(centerWallPiece); } - else { - continue; - } - 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; + 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(pos.x, pos.y)] != TERRAIN_MASK_WALL) { + structures[getCoord(pos.x, pos.y)] = s; + } + else { + continue; + } + 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; + } } } @@ -457,4 +468,4 @@ export default profiler.registerFN(function RoomPlanner(room: Room) { } room.memory._planner = str; -}); +}) as (room: Room) => void; diff --git a/src/Tasks/Build.ts b/src/Tasks/Build.ts index 46c49b7..a79324d 100644 --- a/src/Tasks/Build.ts +++ b/src/Tasks/Build.ts @@ -10,24 +10,25 @@ export const Build data: {}, }); -export const runBuild = profiler.registerFN((creep: Creep): TaskStatus => { - const task = creep.task; - if (task == null) { - return TaskStatus.DONE; - } +export const runBuild = profiler.registerFN( + function runBuild(creep: Creep): TaskStatus { + const task = creep.task; + if (task == null) { + return TaskStatus.DONE; + } - if (creep.store.energy === 0) { - return TaskStatus.DONE; - } + if (creep.store.energy === 0) { + return TaskStatus.DONE; + } - const target = task.target as ConstructionSite; - if (target == null && task.targetPos.roomName === creep.room.name) { - return TaskStatus.DONE; - } + const target = task.target as ConstructionSite | null; + if (target == null && task.targetPos.roomName === creep.room.name) { + return TaskStatus.DONE; + } - if (target == null - || creep.build(target) === ERR_NOT_IN_RANGE) { - creep.travelTo(task.targetPos); - } - return TaskStatus.IN_PROGRESS; -}, "runBuild"); + if (target == null + || creep.build(target) === ERR_NOT_IN_RANGE) { + creep.travelTo(task.targetPos); + } + return TaskStatus.IN_PROGRESS; + }) as (creep: Creep) => TaskStatus; diff --git a/src/Tasks/Harvest.ts b/src/Tasks/Harvest.ts index ff8ef63..19fcb07 100644 --- a/src/Tasks/Harvest.ts +++ b/src/Tasks/Harvest.ts @@ -27,23 +27,24 @@ export const Harvest }, }); -export const runHarvest = profiler.registerFN((creep: Creep): TaskStatus => { - const task = creep.task; - if (task == null) { - return TaskStatus.DONE; - } +export const runHarvest = profiler.registerFN( + function runHarvest(creep: Creep): TaskStatus { + const task = creep.task; + if (task == null) { + return TaskStatus.DONE; + } - const target = task.target as Source | Mineral | null; - const opts = task.options as HarvestOptions; - const data = task.data as HarvestData; + const target = task.target as Source | Mineral | null; + const opts = task.options as HarvestOptions; + const data = task.data as HarvestData; - if (opts.stopWhenFull && creep.store.getFreeCapacity(data.resource) == 0) { - return TaskStatus.DONE; - } + if (opts.stopWhenFull && creep.store.getFreeCapacity(data.resource) == 0) { + return TaskStatus.DONE; + } - if (target == null - || creep.harvest(target) === ERR_NOT_IN_RANGE) { - creep.travelTo(task.targetPos); - } - return TaskStatus.IN_PROGRESS; -}, "runHarvest"); + if (target == null + || creep.harvest(target) === ERR_NOT_IN_RANGE) { + creep.travelTo(task.targetPos); + } + return TaskStatus.IN_PROGRESS; + }) as (creep: Creep) => TaskStatus; diff --git a/src/Tasks/Pickup.ts b/src/Tasks/Pickup.ts index 1737689..f54392c 100644 --- a/src/Tasks/Pickup.ts +++ b/src/Tasks/Pickup.ts @@ -1,3 +1,4 @@ +import profiler from "screeps-profiler"; import { TaskData, TaskStatus, TaskType } from "./Task"; export const Pickup @@ -9,27 +10,28 @@ export const Pickup 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; - } +export const runPickup = profiler.registerFN( + function 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; + const target = task.target as Resource | null; + const resource: ResourceConstant + = (task.data as { resource: ResourceConstant }).resource; - if (creep.store.getFreeCapacity(resource) == 0) { + 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; - } - - if (target == null - || creep.pickup(target) === ERR_NOT_IN_RANGE) { - creep.travelTo(task.targetPos); - return TaskStatus.IN_PROGRESS; - } - return TaskStatus.DONE; -}; + }) as (creep: Creep) => TaskStatus; diff --git a/src/Tasks/Repair.ts b/src/Tasks/Repair.ts index 41fcf98..438cb68 100644 --- a/src/Tasks/Repair.ts +++ b/src/Tasks/Repair.ts @@ -10,25 +10,26 @@ export const Repair data: {}, }); -export const runRepair = profiler.registerFN((creep: Creep): TaskStatus => { - const task = creep.task; - if (task == null) { - return TaskStatus.DONE; - } +export const runRepair = profiler.registerFN( + function runRepair(creep: Creep): TaskStatus { + const task = creep.task; + if (task == null) { + return TaskStatus.DONE; + } - if (creep.store.energy === 0) { - return TaskStatus.DONE; - } + if (creep.store.energy === 0) { + return TaskStatus.DONE; + } - const target = task.target as Structure; - if (target == null && task.targetPos.roomName === creep.room.name) { - return TaskStatus.DONE; - } + const target = task.target as Structure | null; + if (target == null && task.targetPos.roomName === creep.room.name) { + return TaskStatus.DONE; + } - if (target == null - || creep.repair(target) === ERR_NOT_IN_RANGE) { - creep.travelTo(task.targetPos); - return TaskStatus.IN_PROGRESS; - } - return TaskStatus.DONE; -}, "runRepair"); + if (target == null + || creep.repair(target) === ERR_NOT_IN_RANGE) { + creep.travelTo(task.targetPos); + return TaskStatus.IN_PROGRESS; + } + return TaskStatus.DONE; + }) as (creep: Creep) => TaskStatus; diff --git a/src/Tasks/Task.ts b/src/Tasks/Task.ts index 938aa6b..5040614 100644 --- a/src/Tasks/Task.ts +++ b/src/Tasks/Task.ts @@ -45,8 +45,10 @@ const packTaskData = (td: TaskData): string => + JSON.stringify({ o: td.options, d: td.data, t: td.target?.id }); const unpackTaskData = (s: string): TaskData => { - const { o: options, d: data, t: targetId } = JSON.parse(s.substring(3)); - const target = Game.getObjectById(targetId as Id); + const { o: options, d: data, t: targetId } + = JSON.parse(s.substring(3)) as { + o: object; d: object; t: Id; }; + const target = Game.getObjectById(targetId); return { type: s.charCodeAt(0) - 65, targetPos: unpackPos(s.substring(1, 3)), diff --git a/src/Tasks/Transfer.ts b/src/Tasks/Transfer.ts index 2e07d96..eab7041 100644 --- a/src/Tasks/Transfer.ts +++ b/src/Tasks/Transfer.ts @@ -1,3 +1,4 @@ +import profiler from "screeps-profiler"; import { TaskData, TaskStatus, TaskType } from "./Task"; interface TransferOptions { @@ -22,20 +23,21 @@ export const Transfer data: {}, }); -export const runTransfer = (creep: Creep): TaskStatus => { - const task = creep.task; - if (task == null) { +export const runTransfer = profiler.registerFN( + function runTransfer(creep: Creep): TaskStatus { + const task = creep.task; + if (task == null) { + return TaskStatus.DONE; + } + + const target = task.target as Structure | Creep | PowerCreep | null; + const opts = task.options as TransferOptions; + + if (target == null + || creep.transfer( + target, opts.resource, opts.amount ?? undefined) === ERR_NOT_IN_RANGE) { + creep.travelTo(task.targetPos); + return TaskStatus.IN_PROGRESS; + } return TaskStatus.DONE; - } - - const target = task.target as Structure | Creep | PowerCreep; - const opts = task.options as TransferOptions; - - if (target == null - || creep.transfer( - target, opts.resource, opts.amount ?? undefined) === ERR_NOT_IN_RANGE) { - creep.travelTo(task.targetPos); - return TaskStatus.IN_PROGRESS; - } - return TaskStatus.DONE; -}; + }) as (creep: Creep) => TaskStatus; diff --git a/src/Tasks/Upgrade.ts b/src/Tasks/Upgrade.ts index 5c2a4dd..86a66a1 100644 --- a/src/Tasks/Upgrade.ts +++ b/src/Tasks/Upgrade.ts @@ -10,21 +10,22 @@ export const Upgrade data: {}, }); -export const runUpgrade = profiler.registerFN((creep: Creep): TaskStatus => { - const task = creep.task; - if (task == null) { - return TaskStatus.DONE; - } +export const runUpgrade = profiler.registerFN( + function runUpgrade(creep: Creep): TaskStatus { + const task = creep.task; + if (task == null) { + return TaskStatus.DONE; + } - if (creep.store.energy === 0) { - return TaskStatus.DONE; - } + if (creep.store.energy === 0) { + return TaskStatus.DONE; + } - const target = task.target as StructureController | null; + const target = task.target as StructureController | null; - if (target == null - || creep.upgradeController(target) === ERR_NOT_IN_RANGE) { - creep.travelTo(task.targetPos); - } - return TaskStatus.IN_PROGRESS; -}, "runUpgrade"); + if (target == null + || creep.upgradeController(target) === ERR_NOT_IN_RANGE) { + creep.travelTo(task.targetPos); + } + return TaskStatus.IN_PROGRESS; + }) as (creep: Creep) => TaskStatus; diff --git a/src/Tasks/Withdraw.ts b/src/Tasks/Withdraw.ts index c78c999..3d2e849 100644 --- a/src/Tasks/Withdraw.ts +++ b/src/Tasks/Withdraw.ts @@ -1,3 +1,4 @@ +import profiler from "screeps-profiler"; import { TaskData, TaskStatus, TaskType } from "./Task"; interface WithdrawOptions { @@ -25,34 +26,35 @@ export const Withdraw data: {}, }); -export const runWithdraw = (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; - } +export const runWithdraw = profiler.registerFN( + function runWithdraw(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 Structure | Tombstone | Ruin; - const opts = task.options as WithdrawOptions; + const target = task.target as Structure | Tombstone | Ruin | null; + const opts = task.options as WithdrawOptions; - if (opts.limit != null - && creep.store.getUsedCapacity(opts.resource) >= opts.limit) { + if (opts.limit != null + && creep.store.getUsedCapacity(opts.resource) >= opts.limit) { + return TaskStatus.DONE; + } + const capacity = creep.store.getFreeCapacity(opts.resource); + const amount = Math.min(opts.amount ?? capacity, + opts.limit ?? capacity - creep.store.getUsedCapacity(opts.resource)); + + if (amount <= 0) { + return TaskStatus.DONE; + } + + if (target == null + || creep.withdraw(target, opts.resource, amount) === ERR_NOT_IN_RANGE) { + creep.travelTo(task.targetPos); + return TaskStatus.IN_PROGRESS; + } return TaskStatus.DONE; - } - const capacity = creep.store.getFreeCapacity(opts.resource); - const amount = Math.min(opts.amount ?? capacity, - opts.limit ?? capacity - creep.store.getUsedCapacity(opts.resource)); - - if (amount <= 0) { - return TaskStatus.DONE; - } - - if (target == null - || creep.withdraw(target, opts.resource, amount) === ERR_NOT_IN_RANGE) { - creep.travelTo(task.targetPos); - return TaskStatus.IN_PROGRESS; - } - return TaskStatus.DONE; -}; + }) as (creep: Creep) => TaskStatus; diff --git a/src/Tasks/index.ts b/src/Tasks/index.ts index cdebb87..e5252f8 100644 --- a/src/Tasks/index.ts +++ b/src/Tasks/index.ts @@ -35,7 +35,7 @@ const runTask = profiler.registerFN((creep: Creep): TaskStatus => { default: return TaskStatus.DONE; } -}, "runTask"); +}, "runTask") as (creep: Creep) => TaskStatus; Creep.prototype.run = function (generator?: (creep: Creep) => TaskData | null) { const status = runTask(this); diff --git a/src/Workers/Clerk.ts b/src/Workers/Clerk.ts index 3321887..3f7fed5 100644 --- a/src/Workers/Clerk.ts +++ b/src/Workers/Clerk.ts @@ -12,8 +12,10 @@ const assignTask = (creep: Creep) => { if (ext != null) { return Tasks.Transfer(ext); } - if (creep.room.spawn?.store.getFreeCapacity(RESOURCE_ENERGY) ?? 0 > 0) { - return Tasks.Transfer(creep.room.spawn!); + if ((creep.room.spawn?.store.getFreeCapacity(RESOURCE_ENERGY) ?? 0) > 0) { + if (creep.room.spawn != null) { + return Tasks.Transfer(creep.room.spawn); + } } const tower = closestTowerToFill(creep.pos); if (tower != null) { @@ -49,11 +51,12 @@ const assignTask = (creep: Creep) => { return null; }; -const body = (energy: number) => ( +const body = (energy: number): BodyPartConstant[] => ( energy < 100 ? [] - : [WORK].concat(new Array(Math.floor((energy - 100) / 150)) - .fill([MOVE, CARRY, CARRY]).reduce((x, y) => x.concat(y), [])) + : ([WORK] as BodyPartConstant[]).concat( + new Array(Math.floor((energy - 100) / 150)) + .fill([MOVE, CARRY, CARRY]).reduce((x, y) => x.concat(y), [])) ); export const Clerk: WorkerDefinition = { diff --git a/src/Workers/Constructor.ts b/src/Workers/Constructor.ts index 72d893d..874cfd7 100644 --- a/src/Workers/Constructor.ts +++ b/src/Workers/Constructor.ts @@ -49,7 +49,7 @@ const assignTask = (creep: Creep) => { }; const body = (energy: number) => - new Array(Math.floor(energy / 250)) + new Array(Math.floor(energy / 250)) .fill([WORK, MOVE, CARRY, CARRY]).reduce((x, y) => x.concat(y), []); export const Constructor: WorkerDefinition = { diff --git a/src/Workers/Upgrader.ts b/src/Workers/Upgrader.ts index fa6d274..7a0faa4 100644 --- a/src/Workers/Upgrader.ts +++ b/src/Workers/Upgrader.ts @@ -23,7 +23,7 @@ const assignTask = (creep: Creep) => { }; const body = (energy: number) => - new Array(Math.floor(energy / 300)) + new Array(Math.floor(energy / 300)) .fill([WORK, WORK, MOVE, CARRY]).reduce((x, y) => x.concat(y), []); export const Upgrader: WorkerDefinition = { diff --git a/src/Workers/Util.ts b/src/Workers/Util.ts index 8410165..e521ec6 100644 --- a/src/Workers/Util.ts +++ b/src/Workers/Util.ts @@ -1,43 +1,38 @@ export const closestTowerToFill = (pos: RoomPosition): StructureTower | null => pos.findClosestByRange(FIND_MY_STRUCTURES, { filter: structure => structure.structureType === STRUCTURE_TOWER - && (structure as StructureTower).store - .getFreeCapacity(RESOURCE_ENERGY) > 0, + && structure.store.getFreeCapacity(RESOURCE_ENERGY) > 0, }); export const closestExtensionToFill = (pos: RoomPosition): StructureExtension | null => pos.findClosestByRange(FIND_MY_STRUCTURES, { filter: structure => structure.structureType === STRUCTURE_EXTENSION - && (structure as StructureExtension).store - .getFreeCapacity(RESOURCE_ENERGY) > 0, + && structure.store.getFreeCapacity(RESOURCE_ENERGY) > 0, }); export const closestContainerWithEnergy = (pos: RoomPosition): StructureContainer | null => pos.findClosestByRange(FIND_STRUCTURES, { filter: structure => structure.structureType === STRUCTURE_CONTAINER - && (structure as StructureContainer).store - .getUsedCapacity(RESOURCE_ENERGY) > 0, + && structure.store.getUsedCapacity(RESOURCE_ENERGY) > 0, }); export const closestContainerToFill = (pos: RoomPosition): StructureContainer | null => pos.findClosestByRange(FIND_STRUCTURES, { filter: structure => structure.structureType === STRUCTURE_CONTAINER - && (structure as StructureContainer).store - .getFreeCapacity(RESOURCE_ENERGY) > 0, + && structure.store.getFreeCapacity(RESOURCE_ENERGY) > 0, }); export const closestStorageWithResource = (pos: RoomPosition, t: ResourceConstant): StructureStorage | null => pos.findClosestByRange(FIND_MY_STRUCTURES, { filter: structure => structure.structureType === STRUCTURE_STORAGE - && (structure as StructureStorage).store - .getUsedCapacity(t) > 0, + && structure.store.getUsedCapacity(t) > 0, }); export const closestStorageToFill = (pos: RoomPosition, t: ResourceConstant): StructureStorage | null => pos.findClosestByRange(FIND_MY_STRUCTURES, { filter: structure => structure.structureType === STRUCTURE_STORAGE - && (structure as StructureStorage).store.getFreeCapacity(t) > 0, + && structure.store.getFreeCapacity(t) > 0, }); diff --git a/src/Workers/worker.ts b/src/Workers/worker.ts index d8b3c19..b6aac4b 100644 --- a/src/Workers/worker.ts +++ b/src/Workers/worker.ts @@ -10,7 +10,7 @@ export interface WorkerDefinition { } export const spawnWorkers = profiler.registerFN( - (spawn: StructureSpawn, workers: WorkerDefinition[]): void => { + function spawnWorkers(spawn: StructureSpawn, workers: WorkerDefinition[]) { for (const worker of workers) { for (let i = 0; i < worker.requiredCreeps(spawn.room); i++) { const ret = spawn.spawnCreep( @@ -21,7 +21,7 @@ export const spawnWorkers = profiler.registerFN( } } } - }, "spawnWorkers"); + }) as (spawn: StructureSpawn, workers: WorkerDefinition[]) => void; export const runWorkers = profiler.registerFN( function runWorkers(workers: WorkerDefinition[]) { @@ -41,4 +41,4 @@ export const runWorkers = profiler.registerFN( } } } - }); + }) as (workers: WorkerDefinition[]) => void; diff --git a/src/index.ts b/src/index.ts index 7d565ae..c5016e2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -34,7 +34,7 @@ const runTowers = profiler.registerFN((spawn: StructureSpawn) => { console.log(tower.repair(str)); } }; -}, "runTowers"); +}, "runTowers") as (spawn: StructureSpawn) => void; profiler.enable(); export const loop = profiler.wrap(() => { @@ -52,6 +52,7 @@ export const loop = profiler.wrap(() => { for (const creep in Memory.creeps) { if (!(creep in Game.creeps)) { + // eslint-disable-next-line @typescript-eslint/no-dynamic-delete delete Memory.creeps[creep]; } }