Search code examples
javascriptscreeps

Screeps - filter containers by sources in range of 1 (container mining)


actually i want to find containers without sources next to them, so my lorries can transfer energy more flexibly around the base instead of having one giant storage. (my controller is far away)

// find all containers in room
var containers = creep.room.find(FIND_STRUCTURES, {
    filter: (s) => s.structureType == STRUCTURE_CONTAINER
});
// find all sources
var sources = creep.room.find(FIND_SOURCES);
// if there is no source next to the container
if (!(sources.length < 0)) {
}

this finishes without error but i cant manage to get the container id that has no source next to it.

i believe i have to include the logic for that in the filter most likely loop through every container?

i dont understand loops / iterations enough yet to get this working. i tried many things but by now i feel helpless trying to figure out this puzzle.


Solution

  • I think you can update your first filter to check for nearby sources like so:

        let containers = creep.room.find(FIND_STRUCTURES, {
            filter: (s) => s.structureType === STRUCTURE_CONTAINER && s.pos.findInRange(FIND_SOURCES, 2).length === 0
        });
    

    I used 2 for the range, but if your containers are always adjacent to your sources (or very far away), you could change that to 1.

    You would save on CPU if you store that result in Memory. I can give more information if you want to know how to do that.

    EDIT: For caching, you could create a property on the Room object like this (might need some debugging done on this - I wrote it but didn't test it):

    Object.defineProperty(Room.prototype, 'nonSourceContainers', {
        get: function () {
            if (this === Room.prototype || this === undefined) return undefined;
    
            const room = this;
    
            // If any containers have been constructed that don't have isNearSource defined, fix that first.
            let newContainers = room.find(FIND_STRUCTURES, {
                filter: (s) => s.structureType === STRUCTURE_CONTAINER && s.memory.isNearSource === undefined
            });
    
            // Found some new containers?
            if (newContainers.length) {
                for (let i = 0; i < newContainers.length; ++i) {
                    newContainers[i].memory.isNearSource = newContainers[i].pos.findInRange(FIND_SOURCES, 2).length > 0;
                }
    
                // Set the list of non-source container ids in the room's memory. This lasts forever.
                room.memory.nonSourceContainerIds = room.find(FIND_STRUCTURES, {filter: {isNearSource: false}});
    
                // Reset the cached set of containers.
                room._nonSourceContainers = undefined;
            }
    
            // If there is no cached list, create it. Caching will mean the following runs once per tick or less.
            if (!room._nonSourceContainers) {
                if (!room.memory.nonSourceContainerIds) {
                    room.memory.nonSourceContainerIds = [];
                }
    
                // Get the containers by their ids.
                room._nonSourceContainers = room.memory.nonSourceContainerIds.map(id => Game.getObjectById(id));
            }
    
            return room._nonSourceContainers;
        },
        enumerable: false,
        configurable: true
    });