var idler = require('idle.base'); // Finds a new spot for the harvester to mine var find_spot = function(creep) { var sources = creep.room.find(FIND_SOURCES); var possible_spots = {}; var num_spots = {}; var open_spots = {} for(let source of sources) { for (let x of [-1, 0, 1]) { for (let y of [-1, 0, 1]) { if(!(x == 0 && y == 0)){ var pos = new RoomPosition(source.pos.x + x, source.pos.y + y, source.pos.roomName); if(pos.lookFor(LOOK_TERRAIN) == "plain"){ if(num_spots[source.id] == undefined) { num_spots[source.id] = 0; } num_spots[source.id] += 1; if(pos.lookFor(LOOK_CREEPS).length == 0) { if(possible_spots[source.id] == undefined) { possible_spots[source.id] = []; } possible_spots[source.id].push([pos.x, pos.y, pos.roomName, source.id]); if(open_spots[source.id] == undefined) { open_spots[source.id] = 0; } open_spots[source.id] += 1; } } } } } } var best_source = null; var best_occupied = null; for (let source of sources) { if (num_spots[source.id] != undefined && open_spots[source.id] != undefined){ var occupied = num_spots[source.id] - open_spots[source.id]; if ((best_occupied == null || occupied < best_occupied) && possible_spots[source.id] != undefined && possible_spots[source.id].length > 0) { best_occupied = occupied; best_source = source; } } } if (possible_spots[best_source.id].length > 0){ return possible_spots[best_source.id][0]; } return null; } // Finds the container near the current spot of the creep var find_container = function(creep) { if (creep.memory.spot) { for (let x of [-1, 0, 1]) { for (let y of [-1, 0, 1]) { if(!(x == 0 && y == 0)){ var pos = new RoomPosition(creep.memory.spot[0] + x, creep.memory.spot[1] + y, creep.memory.spot[2]); var structs = pos.lookFor(LOOK_STRUCTURES); for(let struct of structs) { if (struct.structureType == STRUCTURE_CONTAINER || struct.structureType == STRUCTURE_STORAGE) { return struct.id; } } } } } } return null; } var roleHarvester = { /** @param {Creep} creep @param {int} behaviourLevel **/ run: function(creep, behaviourLevel) { switch (creep.memory.state) { case "idle": idler.do_idle(creep); if(creep.memory.idle_time == undefined){ creep.memory.idle_time = 0; } creep.memory.idle_time += 1; // If we've been idling for a while, check if there is a spot available if (creep.memory.idle_time > 10) { idler.clear_idle(creep); delete creep.memory.idle_time; creep.memory.state = "find_spot"; creep.say("Looking..."); } break; case "find_spot": // If we don't have a spot yet, find one if (!creep.memory.spot) { creep.memory.spot = find_spot(creep); creep.memory.container = find_container(creep); } // If no spot was found, go back to idling if (!creep.memory.spot) { creep.memory.state = "idle"; creep.say("No spot!"); } else { creep.memory.state = "walk_to_spot"; creep.say("Walking..."); } break; case "walk_to_spot": if (creep.memory.spot) { if (creep.pos.x != creep.memory.spot[0] || creep.pos.y != creep.memory.spot[1]) { creep.moveTo(creep.memory.spot[0], creep.memory.spot[1], {visualizePathStyle: {stroke: '#0044aa'}}) // Check if our spot is still available if ((new RoomPosition(creep.memory.spot[0], creep.memory.spot[1], creep.memory.spot[2])).lookFor(LOOK_CREEPS).length > 0){ creep.memory.spot = null; creep.memory.container = null; creep.memory.state = "idle"; creep.say("Occupied:("); } } else { // We arrived! Start mining. creep.memory.state = "mine_energy"; creep.say("Mining..."); } } else { // We don't have a spot creep.memory.state = "find_spot"; creep.say("Looking..."); } break; case "mine_energy": if (creep.memory.spot) { var source = Game.getObjectById(creep.memory.spot[3]); if (source) { if(creep.store.getFreeCapacity() > 0) { if(creep.harvest(source) == ERR_NOT_IN_RANGE) { // Source is gone? creep.memory.spot = null; creep.memory.container = null; creep.memory.state = "find_spot"; creep.say("Looking..."); } } else { // We are full, dump the energy into the container creep.memory.state = "dump_energy"; creep.say("Dumping..."); } } else { // No source? creep.memory.spot = null; creep.memory.container = null; creep.memory.state = "find_spot"; creep.say("Looking..."); } } else { // We don't have a spot creep.memory.state = "find_spot"; creep.say("Looking..."); } break; case "dump_energy": if (creep.memory.container) { var container = Game.getObjectById(creep.memory.container); if (container) { if (container.store.getFreeCapacity(RESOURCE_ENERGY) > 0 && creep.store.getUsedCapacity() > 0) { creep.transfer(container, RESOURCE_ENERGY); } } else { // No container? creep.memory.spot = null; creep.memory.container = null; creep.memory.state = "find_spot"; creep.say("Looking..."); } if (creep.store.getUsedCapacity() == 0) { // Everything dumped, go back to mining creep.memory.state = "mine_energy"; creep.say("Mining..."); } } else { // No container? creep.memory.spot = null; creep.memory.container = null; creep.memory.state = "find_spot"; creep.say("Looking..."); } break; default: creep.memory.state = "find_spot"; creep.say('Looking...'); } } }; module.exports = roleHarvester;