Harvesting from multiple sources within a room



  • I cannot understand how to use a source's Id to create a designated team of harvesters to go to that resource instead of the one closest to my spawn. Currently, all my harvesters only go to the primary source using this code:

    run: function(creep) {
        if(creep.carry.energy < creep.carryCapacity) {
            var sources = creep.room.find(FIND_SOURCES);
            if(creep.harvest(sources[0]) == ERR_NOT_IN_RANGE) {
                creep.moveTo(sources[0], {visualizePathStyle: {stroke: '#ffaa00'}});
            }
        }
    

    Please, could someone help me understand how I can store a particular source's Id into memory and then instruct a separate team of harvesters to go to that source? I have created a new role - role.southharvester - but cannot formulate the code to get it to harvest the other source.



  • sources is a list. Your looking at the first item in the list. Try looking at the second one.

    sources[0] is the source you are minding from

    sources[1] is a diffrant source.

    sources[2] is yet a diffrant source (provided there is 3 sources in the room)



  • Source is the game object, each game object are contained id property. The room.find is returned list of Source objects. So you can get list of sources by code:

    var listSources = creep.room.find(FIND_SOURCES)
    

    Than you can save this id on the creep memory:

    creep1.memory.sourceID = listSources[0].id;
    creep2.memory.sourceID = listSources[1].id;
    

    After it your harvester function can look like this:

    run: function(creep) {
        if(creep.carry.energy < creep.carryCapacity) {
            var source = Game.getObjetcByID(creep.memory.sourceID)
            if(creep.harvest(source) == ERR_NOT_IN_RANGE) {
                creep.moveTo(source, {visualizePathStyle: {stroke: '#ffaa00'}});
            }
        }
    

    This is only sketch how it's can be look.



  • It's better not to worry about assigning sources directly with your code.

    My code will filter an array based on the source id. The miners will have the source id in their memory.

    so you have an array of miners myMiners = []; You place your miner creeps in them, filtering Game.creeps for the source id.

    For my code, I just have one miner per source...so if there isn't a miner, it'll spawn one.

        for(let sourceIndex in Game.rooms[homebase].memory.sources){
            myMiners = _.filter(Game.creeps, i => i.memory.sourceId === sourceIndex);
            if(myMiners.length < 1){
                Game.spawns[0].spawnCreep(minerBody, randomName, memory: {sourceId: 
                         sourceIndex})
            }
        }
    
    👍


  • Thanks a great deal for your help guys, I managed to use your advice to get the harvesters to use both sources in my room currently just be writing sources[1] but I will work on upgrading to a dedicated stationary miner soon. Currently, I am having trouble getting my distance harvester to reliably go to a neighbouring room and harvest a source there. It goes there sometimes (with some variations of the code below but not consistently). If anyone could give me any advice on how to tweak it I would be very grateful:

    var roleDistanceharvester = {

    /** @param {Creep} creep **/
    run: function(creep) {
        if(creep.carry.energy < creep.carryCapacity) {
            var prospect = creep.moveTo(new RoomPosition(20,1, 'W57S45'))};
            
            
            if((creep.pos.isEqualTo(20,1, 'W57S45') || creep.pos.isNearTo(20,1, 'W57S45')) && creep.carry.energy < creep.carryCapacity) {
                var sources = creep.room.find(FIND_SOURCES);
            if(creep.harvest(sources[0]) == ERR_NOT_IN_RANGE) {
                creep.moveTo(sources[0], {visualizePathStyle: {stroke: '#ffaa00'}});
            }
        }
    
        else {
            if(creep.carry.energy = creep.carryCapacity) {
            const stores = creep.pos.findClosestByPath(FIND_STRUCTURES, {
                    filter: (s) => (s.structureType == STRUCTURE_EXTENSION || s.structureType == STRUCTURE_SPAWN || s.structureType == STRUCTURE_CONTAINER || s.structureType == STRUCTURE_STORAGE) &&
                            s.energy < s.energyCapacity});
                            
            var targets = creep.moveTo(new RoomPosition(12,16, 'W57S44'));
            if(stores) {
                if(creep.transfer(stores, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
                    creep.moveTo(stores, {visualizePathStyle: {stroke: '#ffffff'}});
                }
            }
        }
     }
    

    } }; module.exports = roleDistanceharvester;



  • @nanocraft I would also recommend adding something like var creepRoom = creep.room.name and use creepRoom instead of 'W57S44' so that it doesnt break if you move to another room



  • @nanocraft in your else, your if(creep.carry.energy = creep.carryCapacity) is incorrect. It needs to be 2 or 3 equal signs, otherwise you're attempting to assign your carryCapacity to creep.carry.energy.

    You're also placing error code of your move command into targets and prospects, but not using that error code.

    As for why it's not working, I think your var sources = creep.room.find(FIND_SOURCES); command is limited by scope. It's under the if statement, and I believe that the var will become undefined after that if statement executes. I'm unsure, because I don't use var, I use let, so maybe var is global?

    Another thing is that if you call room.find(FIND_SOURCES), sometimes the order in which the sources appear in the array is not always the same...sometimes the source you receive might be rearranged.



  • @famine Thanks for pointing me in the right direction, I used let. The code is a bit-long winded - I am surprised it worked tbh - but it did 😄

    run: function(creep) {
    let prospect = new RoomPosition(34,4, 'W57S45');
    let home = new RoomPosition(16,34, 'W57S44');
        if(creep.memory.prospecting && (!creep.pos.isNearTo(prospect) || creep.carry.energy === creep.carryCapacity)) {
            creep.memory.prospecting = false;
            creep.say('⛏ seeking');
        }
        if(!creep.memory.prospecting && (creep.carry.energy < creep.carryCapacity && creep.pos.isNearTo(prospect))) {
            creep.memory.prospecting = true;
            creep.say('Container');
        }
            if(creep.memory.prospecting) {
       var sources = creep.room.find(FIND_SOURCES);
            if(creep.harvest(sources[0]) == ERR_NOT_IN_RANGE) {
                creep.moveTo(sources[0], {visualizePathStyle: {stroke: '#ffaa00'}});
            }
        }
         if(!creep.memory.prospecting && creep.carry.energy < creep.carryCapacity) {
            creep.moveTo(prospect)
        }
            else if (!creep.memory.prospecting && creep.carry.energy === creep.carryCapacity) {
                creep.moveTo(home);
            var targets = creep.pos.findClosestByPath(FIND_STRUCTURES, {
                    filter: (s) => (s.structureType == STRUCTURE_CONTAINER || s.structureType == STRUCTURE_STORAGE) &&
                            s.store.energy < s.storeCapacity
            });
            if(targets) {
                if(creep.transfer(targets, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) {
                    creep.moveTo(targets, {visualizePathStyle: {stroke: '#ffffff'}});
            }
        }
    }