diff --git a/src/main.ts b/src/main.ts index 3fa79bb..eb3f024 100644 --- a/src/main.ts +++ b/src/main.ts @@ -9,11 +9,22 @@ declare global { Types added in this `global` block are in an ambient, global context. This is needed because `main.ts` is a module file (uses import or export). Interfaces matching on name from @types/screeps will be merged. This is how you can extend the 'built-in' interfaces from @types/screeps. */ + interface SourceState { + id: string; + pos: RoomPosition; + maxHarvesters: number|null; + currentHarvesters: number; + } + + interface GameState { + sourcesStates: { [sourceId: string]: SourceState }; + } + // Memory extension samples interface Memory { uuid: number; log: any; - spawnHandlers: { [name: string]: string }; + spawnStates: { [name: string]: GameState }; } interface CreepMemory { @@ -32,8 +43,13 @@ declare global { export const loop = () => { + Memory.spawnStates = Memory.spawnStates || {}; + for (const spawnName of Object.keys(Game.spawns)) { - // Run the handler - new SpawnHandler(Game.spawns[spawnName]).run(); + const spawnState = Memory.spawnStates[spawnName] || {}; + + const spawnHandler = new SpawnHandler(Game.spawns[spawnName]); + + Memory.spawnStates[spawnName] = spawnHandler.run(spawnState); } }; diff --git a/src/roleHandlers/harvesterHandler.ts b/src/roleHandlers/harvesterHandler.ts index 26f8d3e..6af0a8b 100644 --- a/src/roleHandlers/harvesterHandler.ts +++ b/src/roleHandlers/harvesterHandler.ts @@ -1,21 +1,50 @@ +import getSourceById from "utils/funcs/get_source_by_id"; import { RoleHandler } from "./roleHandler.interface"; class HarvesterHandler extends RoleHandler { - public static run(creep: Creep): void { + public static run(creep: Creep, state: GameState): GameState { + const source = this.findClosestSource(creep, state); + console.log(`Running HarvesterHandler for creep: ${creep.name}`); if (creep.store.getFreeCapacity() > 0) { - const sources = creep.room.find(FIND_SOURCES); - if (creep.harvest(sources[0]) === ERR_NOT_IN_RANGE) { - creep.moveTo(sources[0]); + if (creep.harvest(source) === ERR_NOT_IN_RANGE) { + creep.moveTo(source, { reusePath: true }); } } else { const spawn = Game.spawns['Spawn1']; if (creep.transfer(spawn, RESOURCE_ENERGY) === ERR_NOT_IN_RANGE) { - creep.moveTo(spawn); + creep.moveTo(spawn, { reusePath: true }); } } + + return state; + } + + private static findClosestSource(creep: Creep, state: GameState): Source|null { + for (const source of creep.room.find(FIND_SOURCES)) { + + } + + let closestSourceId = null; + for (const sourceId in state.sourcesStates) { + if (!closestSourceId) { + closestSourceId = sourceId; + } + const sourceInfo = state.sourcesStates[sourceId]; + const creepPos = creep.pos; + if (creepPos.getRangeTo(sourceInfo["pos"]) < creepPos.getRangeTo(state.sourcesStates[closestSourceId]["pos"])) { + closestSourceId = sourceId; + } + } + + if (!closestSourceId) { + console.warn(`No sources found for creep: ${creep.name}`); + return null; + } + + return getSourceById(closestSourceId); } } diff --git a/src/roleHandlers/roleHandler.interface.ts b/src/roleHandlers/roleHandler.interface.ts index 8453d2b..5378c6e 100644 --- a/src/roleHandlers/roleHandler.interface.ts +++ b/src/roleHandlers/roleHandler.interface.ts @@ -1,3 +1,3 @@ export abstract class RoleHandler { - static run(creep: Creep): void {}; + static run(creep: Creep, state: GameState): GameState {}; } diff --git a/src/spawnHandler.ts b/src/spawnHandler.ts index bde5cc5..ca7dc94 100644 --- a/src/spawnHandler.ts +++ b/src/spawnHandler.ts @@ -9,20 +9,42 @@ class SpawnHandler { return this.spawn.name; } - public run(): void { + public run(state: GameState): GameState { + this.updateSpawnState(state); + + for(const name in Game.creeps) { + const creep = Game.creeps[name]; + + const roleDefinition = CreepRoles[creep.memory.role as CreepRole]; + if (!roleDefinition) { + console.warn(`Creep ${creep.name} has an unknown role: ${creep.memory.role}`); + continue; + } + + state = roleDefinition.handler.run(creep, state); + } + this.validateSpawnState(); - for(const name in Game.creeps) { - const creep = Game.creeps[name]; + return state; + } - const roleDefinition = CreepRoles[creep.memory.role as CreepRole]; - if (!roleDefinition) { - console.warn(`Creep ${creep.name} has an unknown role: ${creep.memory.role}`); - continue; - } - - roleDefinition.handler.run(creep); + private updateSpawnState(state: GameState) { + const sources = this.spawn.room.find(FIND_SOURCES); + for (const source of sources) { + if (!state.sourcesStates) { + state.sourcesStates = {}; } + const sourceId = source.id.toString(); + if (!state.sourcesStates[sourceId]) { + state.sourcesStates[sourceId] = { + "id": sourceId, + "pos": source.pos, + "maxHarvesters": null, + "currentHarvesters": 0 + }; + } + } } private validateSpawnState() { diff --git a/src/types/gameConfig.ts b/src/types/gameConfig.ts index 21bc495..b8c4878 100644 --- a/src/types/gameConfig.ts +++ b/src/types/gameConfig.ts @@ -24,7 +24,7 @@ export type GameConfig = { export const DEFAULT_GAME_CONFIG: GameConfig = { maxCreeps: 15, minCreepsPerRole: { - harvester: 5, + harvester: 15, upgrader: 0, builder: 0 } diff --git a/src/utils/funcs/get_source_by_id.ts b/src/utils/funcs/get_source_by_id.ts new file mode 100644 index 0000000..e05082e --- /dev/null +++ b/src/utils/funcs/get_source_by_id.ts @@ -0,0 +1,17 @@ +const getSourceById = (sourceId: string): Source | null => { + if (!sourceId) { + console.warn("getSourceById called with an empty or undefined sourceId."); + return null; + } + + const source = Game.getObjectById(sourceId); + if (!source) { + console.warn(`No source found with ID: ${sourceId}`); + return null; + } + + return source; +} + + +export default getSourceById;