My tower just keeps repairing a single piece of wall.



  • How to tell my tower to stop repairing a piece of a constructed wall if it is on 30k hits? Here's my code:

    var tower = Game.getObjectById('5c2796fa9da4b610294bbb8f');
    if (tower) {
        var closestDamagedWall = tower.pos.findClosestByRange(STRUCTURE_WALL, {
            filter: (structure) => structure.hits < 30000
        });
        var closestDamagedRampart = tower.pos.findClosestByRange(STRUCTURE_RAMPART, {
            filter: (structuere) => structure.hits < 30000
        });
        var closestDamagedStructure = tower.pos.findClosestByRange(FIND_STRUCTURES, {
            filter: (structure) => structure.hits < structure.hitsMax
        });
        if (closestDamagedWall) {
            tower.repair(closestDamagedWall);
        }
        if (closestDamagedRampart) {
            tower.repair(closestDamagedRampart);
        }
        if (closestDamagedStructure) {
            tower.repair(closestDamagedStructure)
        }
        var closestHostile = tower.pos.findClosestByRange(FIND_HOSTILE_CREEPS);
        if (closestHostile) {
            tower.attack(closestHostile);
        }
    }
    
    

  • TMB

    Please make your code a minimum readable.
    Place the code between triple quotes ``` and don't write everything on a single line.



  • Readable now?

    👍


  • I'm sorry I couldn't reply, I was raking leaves outside.


  • AYCE

    As long as the closest wall is not at max HP, you will have a structure for closestDamagedStructure. The last if (except attack) will "overwrite" your earlier repairs.

    This will probably fix it (using else if):

        if (closestDamagedWall) {
            tower.repair(closestDamagedWall);
        }
        else if (closestDamagedRampart) {
            tower.repair(closestDamagedRampart);
        }
        else if (closestDamagedStructure) {
            tower.repair(closestDamagedStructure)
        }
    
    👍


  • @Kasami has your answer.

    From: https://docs.screeps.com/simultaneous-actions.html#Methods-call-priority

    Methods call priority The sequence of calling commands for different methods in the code is irrelevant, only the aforementioned priorities matter. But if the same method is specified, the last call has the priority. For example:

    creep.moveTo(target); // will be ignored
    creep.move(RIGHT); // will be ignored
    creep.move(LEFT); // will be executed
    

    The creep will move to the left in this tick.



  • @ziton said in My tower just keeps repairing a single piece of wall.:

    var tower = Game.getObjectById('5c2796fa9da4b610294bbb8f'); 
    // as a generell advice don't use hard coded IDs that will really develop bad habits and annoy you later on
    
    if (tower) {
        var closestDamagedWall = tower.pos.findClosestByRange(STRUCTURE_WALL, {
            filter: (structure) => structure.hits < 30000
        }); // this works and is valid and saves the nearest wall
        
        var closestDamagedRampart = tower.pos.findClosestByRange(STRUCTURE_RAMPART, {
            filter: (structuere) => structure.hits < 30000 //<- structure has a typo
        }); // this also works and saves the nearest rampart
        
        var closestDamagedStructure = tower.pos.findClosestByRange(FIND_STRUCTURES, {
            filter: (structure) => structure.hits < structure.hitsMax
        }); // and this is totally legit too, but it is also what bites you since walls and ramparts are structures too
    
        if (closestDamagedWall) {
            tower.repair(closestDamagedWall);
        } // works as intended 
    
        if (closestDamagedRampart) {
            tower.repair(closestDamagedRampart);
        } // works as intended too, but overwrites the previous target
    
        if (closestDamagedStructure) {
            tower.repair(closestDamagedStructure)
        } // overwrites the previous two since as mentioned walls and ramparts are structures and this ignores your hit limit.
    
        var closestHostile = tower.pos.findClosestByRange(FIND_HOSTILE_CREEPS);
        if (closestHostile) {
            tower.attack(closestHostile);
        } // well the only thing that works 100% at the time since it is the last overwrite 
    }
    
    

    To summarize what those two above are talking about I commented your code 😉
    It is sometimes hard to spot what is for others obvious 😄

    Now you have different options to fix this:

    • Kasamis else if fix since it only evaluates the first true statement and ignores the rest
    • you could only search once for structures and adjust its filter
    • make a small function that evaluates your three values and returns the right target <- which is basically the filter above

    Cheers Faul 👋


  • TMB

    Something big hits me now that I see the code clearly.

    var closestDamagedWall    = findClosestByRange(STRUCTURE_WALL);
    var closestDamagedRampart = findClosestByRange(STRUCTURE_RAMPART);
    

    Those are not valid uses of the method: You must use a FIND_* constant as first argument. Here your two variables are always going to be null, so your code always falls back to the closestDamagedStructure bit.

    What you'd want to do instead is something more like this:

    var closestDamagedWall = tower.pos.findClosestByRange(FIND_STRUCTURES, {
            filter: (s) => s.hits < 30000 
            && (s.structureType==STRUCTURE_WALL || s.structureType==STRUCTURE_RAMPART)
        });
    
    💯


  • lol he is right, I didn't noticed that 😆
    That automatically confines you only to FIND_STRUCTURES and use the filter to sort it out. 🤦♂

    That is the beauty of the interwebs, there is always someone there to correct you (but it is still up to you if you believe him)



  • tower.pos.findClosestByRange(STRUCTURE_RAMPART, {
         filter: (structuere) => structure.hits < 30000
    });
    

    Maybe just replace "structuere" by "structure" I use this :

    room.find( FIND_STRUCTURES, { filter: ( f ) => {
         return ( f.hits < f.hitsMax )}}).sort( function( a, b ) {
              return +a.hits - +b.hits })[ 0 ]