Screeps: World
Wolfguarde Sep 23, 2017 @ 10:36pm
Help with tower code
I've run into a couple of issues with tower code as my base progresses, which I'm in a bit of a bind with. I'm using the base tutorial code with a couple of tweaks.

My points of interest are:

- How do I set this room's tower as my tower variable? Using the ID works for the moment, but I anticipate running into problems if I wind up with multiple towers in a room, or if the code isn't differentiating between towers/structures in specific rooms. I'd like to knock this one out early if I can.

- My tower currently only targets and repairs one structure (wall) to the specified cap. I'm not sure how to re-call or cycle closestDamagedStructure through the return values. The filter should order them from lowest to highest, but from a bit of experimentation, the variable isn't actually changing whether [0] is specified or not. What would be the optimal solution here?

My code:

var tower = Game.getObjectById('59c27f4df9d2040d42b03e1b'); if(tower) { var closestDamagedStructure = tower.pos.findClosestByRange(FIND_STRUCTURES, { filter: (structure) => structure.hits < structure.hitsMax }); if(closestDamagedStructure && closestDamagedStructure.hits <= 20000 && tower.energy >=500) { tower.repair(closestDamagedStructure); console.log("Tower now repairing: " + closestDamagedStructure); }
< >
Showing 1-4 of 4 comments
Mashee Sep 24, 2017 @ 1:31am 
You can find your (multiple) towers in your room like any other objects, then itterate through them. Long-term you might store these object ID's in a memory value so you don't have to use CPU to find them...but worry about that later.

(pseudo code)
const myTowers = Game / room [thisroom] / FIND_MY_STRUCTURES, filter STRUCTURE_TOWER ;

You can itterate through them using FOR/IN or with a traditional numeric increment.

(pseudo code)
for (tower in myTowers){ let repairTarget = myTowers[tower].pos. findClosestThingToRepair ...or some other criteria myTowers[tower].repair(repairTarget); }

Or a numeric itteration through an array can be found in the screeps docs at: http://docs.screeps.com/api/#Game.market.deal

I only point out a regular numeric/index itteration because javascript is so loose that for/in can cause problems if you're not on the ball. Miscellaneous object literals drive me bananas...I just want regular multi-dimensional arrays. :steamSad: See here for a run-down: http://www.sebarmeli.com/blog/2010/12/06/best-way-to-loop-through-an-array-in-javascript/ It also allows you to more easily skip elements with an additional i++; or easily allocate tasks (to each tower for instance) based on how many total exist. You may not want them all shooting the same target all the time...

Your filter only sorts the results for .hits not maxed. This is not a lowest-to-highest sort...it's just a list of not full HP results. Object.hits < Object.hitsMax is a numeric evaluation ( if 3 is less than 4, return true/object ) Web search for operators, or numeric operators. (Not trying to be condescending here, just trying to explain why your sort criteria isn't what you wanted )

Have a web search for the javascript function .sort. You can use it to bring your lowest hits object to the start of your results array, and then target[0]. Don't forget the loDash stuff is available throughout your screeps code too! https://lodash.com/docs/4.17.4

There's also a .sort sample at creep.repair() http://docs.screeps.com/api/#Creep.repair

:steamhappy:

Last edited by Mashee; Sep 24, 2017 @ 3:52pm
Wolfguarde Oct 12, 2017 @ 6:42am 
Sorry, dropped off the radar for a while to sort out some other stuff. This looks quite helpful, I'll dig into it and see what I can make of it. Don't worry about whether you sound condescending or not, I'm enough of a novice that anything you can offer is going to help. And I'm not going to take offence one way or the other to constructive criticism! Thank you once again for the pointers.

I have one other question to add to this, which will be useful down the track though it's redundant with the info you've provided in this scenario. Is it possible to create a filter that excludes results that meet certain criteria? For example, if I were to create a filter for sorting a return list of creeps in a room based on their parts, but wanted to exclude creeps that have more or less than a certain number of parts... is that possible?
Mashee Oct 13, 2017 @ 2:14pm 
Sure. Just use combinations of &&, and || to set your conditions. From the sample code: http://docs.screeps.com/api/#Creep.getActiveBodyparts

original Sample code:
const target = creep.pos.findClosestByRange(FIND_HOSTILE_CREEPS, { filter: function(object) { return object.getActiveBodyparts(ATTACK) == 0; } });

You might add in:
const target = creep.pos.findClosestByRange(FIND_HOSTILE_CREEPS, { filter: function(object) { return object.getActiveBodyparts(ATTACK) == 0 && object.getActiveBodyparts(WORK) < 5; } });
Last edited by Mashee; Oct 13, 2017 @ 2:22pm
Dragonissa Nov 28, 2017 @ 1:00am 
Repairs stuff and kill things. Probably gonna rewrite it soon.

I get the rooms via :

for(var spawns in Game.spawns) { var spawn = Game.spawns[spawns]; var room = spawn.room; console.log(room) } structureTower.run(room);


var structureTower = { /** * @param {Room} * roomName * */ run: function(roomName) { var hostiles = roomName.find(FIND_HOSTILE_CREEPS); if(hostiles.length > 0) { var username = hostiles[0].owner.username; Game.notify(`User ${username} spotted in room ${roomName}`); } var tower = roomName.find(FIND_MY_STRUCTURES, {filter: {structureType: STRUCTURE_TOWER}}); if(tower) { for(i = 0; i < tower.length; i++) { if(tower.energy > 500) {
var closestDamagedStructure = tower.pos.findClosestByRange(FIND_STRUCTURES, {
filter: (structure) => (structure.hits < (structure.hitsMax < 50000 ? structure.hitsMax : 50000))
});

if(closestDamagedStructure) {
if(closestDamagedStructure.hits < (closestDamagedStructure.hitsMax < 50000 ? closestDamagedStructure.hitsMax : 50000)) {
if(tower.energy > 500) {
tower.repair(closestDamagedStructure);
}
}
}
}
var closestHostile = tower.pos.findClosestByRange(FIND_HOSTILE_CREEPS);
if(closestHostile) {
tower.attack(closestHostile);
}
}
}
}
};
module.exports = structureTower;[/code]
< >
Showing 1-4 of 4 comments
Per page: 1530 50