diff --git a/src/Actions/repairStructure.ts b/src/Actions/repairStructure.ts new file mode 100644 index 0000000..358e5ad --- /dev/null +++ b/src/Actions/repairStructure.ts @@ -0,0 +1,23 @@ +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; + } + } +}) \ No newline at end of file diff --git a/src/RoomPlanner/Blueprints/Extensions.ts b/src/RoomPlanner/Blueprints/Extensions.ts index b7b0bd6..5f7362f 100644 --- a/src/RoomPlanner/Blueprints/Extensions.ts +++ b/src/RoomPlanner/Blueprints/Extensions.ts @@ -6,13 +6,18 @@ 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 exts = extentionsAvailable(room.controller?.level ?? 0); + const terrain = room.getTerrain(); for (let x = -Math.floor(Math.sqrt(exts) / 2); x < Math.sqrt(exts) / 2; x++) { for (let y = -Math.floor(Math.sqrt(exts) / 2); y < Math.sqrt(exts) / 2; y++) { room.visual.circle(spawn.pos.x + x * 2, spawn.pos.y + y * 2); - if (!room.lookAt(spawn.pos.x + x * 2 - 1, spawn.pos.y + y * 2 - 1).includes({ type: 'terrain', terrain: 'wall'})) { + 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); diff --git a/src/RoomPlanner/Blueprints/Roads.ts b/src/RoomPlanner/Blueprints/Roads.ts index c9aa7d7..aa20256 100644 --- a/src/RoomPlanner/Blueprints/Roads.ts +++ b/src/RoomPlanner/Blueprints/Roads.ts @@ -4,9 +4,10 @@ export const buildRoads = (room: Room) => { } 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 sources) { + for (const source2 of (room.controller?.level ?? 0) > 4 ? sourcesAndMinerals : sources) { const path = source.pos.findPathTo(source2, { ignoreCreeps: true, ignoreRoads: true diff --git a/src/Workers/Constructor.ts b/src/Workers/Constructor.ts index bdb568f..c45ec02 100644 --- a/src/Workers/Constructor.ts +++ b/src/Workers/Constructor.ts @@ -1,17 +1,19 @@ import { Fail, 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 { withdrawEnergy } from "../Actions/withdrawEnergy"; import { WorkerDefinition } from "./worker"; export const Constructor: WorkerDefinition = { - runAction: (creep: Creep) => runAction(creep, withdrawEnergy(creep.pos.findClosestByRange(FIND_STRUCTURES, { filter: { structureType: STRUCTURE_CONTAINER }}) as StructureContainer | null)) + runAction: (creep: Creep) => runAction(creep, withdrawEnergy(creep.pos.findClosestByRange(FIND_STRUCTURES, { filter: (str: Structure) => str.structureType === STRUCTURE_CONTAINER && (str as StructureContainer).store.getUsedCapacity(RESOURCE_ENERGY) > 0 }) as StructureContainer | null)) .or(harvestFromClosestActiveSource()) .andThen(buildConstructionSite()) + .or(repairStructure()) .or(creep.room.controller ? upgradeController(creep.room.controller) : Fail) .repeat(), name: 'constructor', requiredCreeps: (room: Room) => room.find(FIND_MY_CONSTRUCTION_SITES).length / 5 + 1, - bodyDefinition: (energy: number) => new Array(Math.floor(energy / 300)).fill([WORK, MOVE, MOVE, CARRY, CARRY]).reduce((x, y) => x.concat(y), []) + bodyDefinition: (energy: number) => new Array(Math.floor(energy / 250)).fill([WORK, MOVE, CARRY, CARRY]).reduce((x, y) => x.concat(y), []) } \ No newline at end of file diff --git a/src/Workers/Miner.ts b/src/Workers/Miner.ts index b49d71b..2be4422 100644 --- a/src/Workers/Miner.ts +++ b/src/Workers/Miner.ts @@ -5,7 +5,7 @@ import { WorkerDefinition } from "./worker"; export const Miner: WorkerDefinition = { runAction: (creep: Creep) => runAction(creep, harvestFromClosestActiveSource()) - .andThen(transferEnergy(creep.pos.findClosestByRange(FIND_STRUCTURES, { filter: { structureType: STRUCTURE_CONTAINER }}) as StructureContainer | null)) + .andThen(transferEnergy(creep.pos.findClosestByRange(FIND_STRUCTURES, { filter: (str: Structure) => str.structureType === STRUCTURE_CONTAINER && (str as StructureContainer).store.getFreeCapacity(RESOURCE_ENERGY) > 0}) as StructureContainer | null)) .repeat(), name: 'miner', requiredCreeps: (room: Room) => room.find(FIND_STRUCTURES, { filter: { structureType: STRUCTURE_CONTAINER }}).length > 0 ? 4 : 0, diff --git a/src/Workers/Upgrader.ts b/src/Workers/Upgrader.ts index 42791f0..f192c77 100644 --- a/src/Workers/Upgrader.ts +++ b/src/Workers/Upgrader.ts @@ -6,7 +6,7 @@ import { withdrawEnergy } from "../Actions/withdrawEnergy"; import { WorkerDefinition } from "./worker"; export const Upgrader: WorkerDefinition = { - runAction: (creep: Creep, spawn: StructureSpawn) => runAction(creep, withdrawEnergy(creep.pos.findClosestByRange(FIND_STRUCTURES, { filter: { structureType: STRUCTURE_CONTAINER }}) as StructureContainer | null)) + runAction: (creep: Creep, spawn: StructureSpawn) => runAction(creep, withdrawEnergy(creep.pos.findClosestByRange(FIND_STRUCTURES, { filter: (str: Structure) => str.structureType === STRUCTURE_CONTAINER && (str as StructureContainer).store.getUsedCapacity(RESOURCE_ENERGY) > 0 }) as StructureContainer | null)) .or(harvestFromClosestActiveSource()) .andThen(transferEnergy(spawn)) .or(transferEnergy(creep.pos.findClosestByRange(FIND_MY_STRUCTURES, { filter: (structure: AnyOwnedStructure) => structure.structureType === STRUCTURE_EXTENSION && structure.store.getFreeCapacity(RESOURCE_ENERGY) > 0}) as StructureExtension | null)) diff --git a/src/index.ts b/src/index.ts index ebf5daf..7f15aee 100644 --- a/src/index.ts +++ b/src/index.ts @@ -17,7 +17,7 @@ export function loop() { if (!controller) { return; } - const workerTypes = [Constructor, Upgrader, Miner]; + const workerTypes = [Upgrader, Miner, Constructor]; spawnWorkers(spawn, workerTypes); runWorkers(spawn, workerTypes); if (Game.time % 100 === 0) {