You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
screeps/default/role.builder.js

130 lines
4.5 KiB

const common = require('common')
let idling = 0
let maxWallHits = 0
module.exports = {
name: 'builder',
prio: 5,
getCount: colonyRoom => {
return Math.min(
colonyRoom.controller.level + 2,
Math.ceil(colonyRoom.find(FIND_MY_CONSTRUCTION_SITES).reduce((total, el) => total + el.progressTotal - el.progress, 0) / 1000)
)
},
maxExpands: 4,
baseBody: [WORK, CARRY, MOVE, MOVE],
expandBody: [WORK, CARRY, MOVE, MOVE],
idling,
maxWallHits,
cleanup () {
for(let [id, creep] of Object.entries(Memory.repairers)) {
let repairable = Game.getObjectById(id)
if (!repairable
|| repairable.hits === repairable.hitsMax
|| !Game.creeps[creep]
|| ((repairable.structureType === STRUCTURE_WALL || repairable.structureType === STRUCTURE_RAMPART)
&& repairable.hits > maxWallHits)
) {
delete Memory.repairers[id]
}
}
},
tickInit () {
for (let room of Object.values(Game.rooms)) {
if (room.find(FIND_STRUCTURES, {filter: s => s.structureType === STRUCTURE_SPAWN}).length === 0) {
continue
}
let walls = room.find(FIND_STRUCTURES, {
filter: structure => (structure.structureType === STRUCTURE_WALL || structure.structureType === STRUCTURE_RAMPART)
})
let wallAvgHits = 0
if (walls.length > 0) {
wallAvgHits = walls.reduce((total, el) => total + el.hits, 0)
wallAvgHits = wallAvgHits / walls.length
}
maxWallHits = Math.min(wallAvgHits, 200000)
}
},
tick (creep) {
let harvest = common.harvestEnergy(creep)
if (harvest === common.consts.HARVESTING) {
return
}
if (creep.store.getFreeCapacity(RESOURCE_ENERGY)) {
let dropped = creep.pos.findInRange(FIND_DROPPED_RESOURCES, 1);
if (dropped.length > 0) {
creep.pickup(dropped[0])
}
let targets = creep.pos.findInRange(FIND_STRUCTURES, 1, {
filter: s => (s.structureType === STRUCTURE_CONTAINER || s.structureType === STRUCTURE_STORAGE)
&& s.store[RESOURCE_ENERGY] > Math.min(creep.store.getFreeCapacity(RESOURCE_ENERGY), 400)
})
if (targets.length) {
creep.withdraw(targets[0], RESOURCE_ENERGY)
}
}
let repairTarget = _.findKey(Memory.repairers, el => el === creep.name)
if (repairTarget) {
repairTarget = Game.getObjectById(repairTarget)
}
if (!repairTarget) {
repairTarget = creep.pos.findClosestByRange(FIND_STRUCTURES, {
filter: (structure) => {
return (
structure.structureType !== STRUCTURE_WALL && structure.structureType !== STRUCTURE_RAMPART
) && (
structure.hits < structure.hitsMax * 0.5 ||
structure.hitsMax - structure.hits >= creep.store.getCapacity(RESOURCE_ENERGY) * 100
) && !Memory.repairers[structure.id]
}
});
}
if (repairTarget) {
Memory.repairers[repairTarget.id] = creep.name
if(creep.repair(repairTarget) === ERR_NOT_IN_RANGE) {
creep.moveTo(repairTarget, {visualizePathStyle: {stroke: '#1a43cb'}});
}
return
}
let target = creep.pos.findClosestByPath(FIND_CONSTRUCTION_SITES, {
filter: (structure) => structure.structureType === STRUCTURE_EXTENSION // || structure.structureType == STRUCTURE_CONTAINER
})
if (!target) {
target = creep.pos.findClosestByPath(FIND_CONSTRUCTION_SITES);
}
if (target) {
let res = creep.build(target)
if (res === ERR_NOT_IN_RANGE) {
creep.moveTo(target, {visualizePathStyle: {stroke: '#729075'}});
}
else if (res === ERR_INVALID_TARGET) {
let cs = target.pos.findInRange(FIND_MY_CREEPS, 0)
if (cs.length > 0) {
cs[0].moveByPath(findWalkablePath(target.pos, [{pos: target.pos, range: 1}], {flee: true}).path)
}
}
return
}
let wallTarget = creep.pos.findClosestByRange(FIND_STRUCTURES, {
filter: structure => structure.hits < structure.hitsMax
&& structure.hits <= maxWallHits
&& (structure.structureType === STRUCTURE_WALL || structure.structureType === STRUCTURE_RAMPART)
})
if (wallTarget) {
if(creep.repair(wallTarget) === ERR_NOT_IN_RANGE) {
creep.moveTo(wallTarget, {visualizePathStyle: {stroke: '#4d4747'}});
}
return
}
creep.moveTo(creep.pos.findClosestByRange(FIND_FLAGS, {filter: flag => flag.name.startsWith('idle')}), {visualizePathStyle: {stroke: '#ff0000'}});
return 'idle'
}
}