diff --git a/src/main.js b/src/main.js new file mode 100644 index 0000000..f1453e2 --- /dev/null +++ b/src/main.js @@ -0,0 +1,35 @@ +// import modules +require('prototype.creep'); +require('prototype.tower'); +require('prototype.spawn'); + +module.exports.loop = function() { + // check for memory entries of died creeps by iterating over Memory.creeps + for (let name in Memory.creeps) { + // and checking if the creep is still alive + if (Game.creeps[name] == undefined) { + // if not, delete the memory entry + delete Memory.creeps[name]; + } + } + + // for each creeps + for (let name in Game.creeps) { + // run creep logic + Game.creeps[name].runRole(); + } + + // find all towers + var towers = _.filter(Game.structures, s => s.structureType == STRUCTURE_TOWER); + // for each tower + for (let tower of towers) { + // run tower logic + tower.defend(); + } + + // for each spawn + for (let spawnName in Game.spawns) { + // run spawn logic + Game.spawns[spawnName].spawnCreepsIfNecessary(); + } +}; \ No newline at end of file diff --git a/src/prototype.creep.js b/src/prototype.creep.js new file mode 100644 index 0000000..74fad63 --- /dev/null +++ b/src/prototype.creep.js @@ -0,0 +1,52 @@ +var roles = { + harvester: require('role.harvester'), + upgrader: require('role.upgrader'), + builder: require('role.builder'), + repairer: require('role.repairer'), + wallRepairer: require('role.wallRepairer'), + longDistanceHarvester: require('role.longDistanceHarvester'), + claimer: require('role.claimer'), + miner: require('role.miner'), + lorry: require('role.lorry') +}; + +Creep.prototype.runRole = + function () { + roles[this.memory.role].run(this); + }; + +/** @function + @param {bool} useContainer + @param {bool} useSource */ +Creep.prototype.getEnergy = + function (useContainer, useSource) { + /** @type {StructureContainer} */ + let container; + // if the Creep should look for containers + if (useContainer) { + // find closest container + container = this.pos.findClosestByPath(FIND_STRUCTURES, { + filter: s => (s.structureType == STRUCTURE_CONTAINER || s.structureType == STRUCTURE_STORAGE) && + s.store[RESOURCE_ENERGY] > 0 + }); + // if one was found + if (container != undefined) { + // try to withdraw energy, if the container is not in range + if (this.withdraw(container, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) { + // move towards it + this.moveTo(container); + } + } + } + // if no container was found and the Creep should look for Sources + if (container == undefined && useSource) { + // find closest source + var source = this.pos.findClosestByPath(FIND_SOURCES_ACTIVE); + + // try to harvest energy, if the source is not in range + if (this.harvest(source) == ERR_NOT_IN_RANGE) { + // move towards it + this.moveTo(source); + } + } + }; \ No newline at end of file diff --git a/src/prototype.spawn.js b/src/prototype.spawn.js new file mode 100644 index 0000000..019234d --- /dev/null +++ b/src/prototype.spawn.js @@ -0,0 +1,201 @@ +var listOfRoles = ['harvester', 'lorry', 'claimer', 'upgrader', 'repairer', 'builder', 'wallRepairer']; + +// create a new function for StructureSpawn +StructureSpawn.prototype.spawnCreepsIfNecessary = + function () { + /** @type {Room} */ + let room = this.room; + // find all creeps in room + /** @type {Array.} */ + let creepsInRoom = room.find(FIND_MY_CREEPS); + + // count the number of creeps alive for each role in this room + // _.sum will count the number of properties in Game.creeps filtered by the + // arrow function, which checks for the creep being a specific role + /** @type {Object.} */ + let numberOfCreeps = {}; + for (let role of listOfRoles) { + numberOfCreeps[role] = _.sum(creepsInRoom, (c) => c.memory.role == role); + } + let maxEnergy = room.energyCapacityAvailable; + let name = undefined; + + // if no harvesters are left AND either no miners or no lorries are left + // create a backup creep + if (numberOfCreeps['harvester'] == 0 && numberOfCreeps['lorry'] == 0) { + // if there are still miners or enough energy in Storage left + if (numberOfCreeps['miner'] > 0 || + (room.storage != undefined && room.storage.store[RESOURCE_ENERGY] >= 150 + 550)) { + // create a lorry + name = this.createLorry(150); + } + // if there is no miner and not enough energy in Storage left + else { + // create a harvester because it can work on its own + name = this.createCustomCreep(room.energyAvailable, 'harvester'); + } + } + // if no backup creep is required + else { + // check if all sources have miners + let sources = room.find(FIND_SOURCES); + // iterate over all sources + for (let source of sources) { + // if the source has no miner + if (!_.some(creepsInRoom, c => c.memory.role == 'miner' && c.memory.sourceId == source.id)) { + // check whether or not the source has a container + /** @type {Array.StructureContainer} */ + let containers = source.pos.findInRange(FIND_STRUCTURES, { + filter: s => s.structureType == STRUCTURE_CONTAINER + }); + + //console.log(containers.length); + // if there is a container next to the source + if (containers.length > 0) { + // spawn a miner + name = this.createMiner(source.id); + break; + } + } + } + } + + // if none of the above caused a spawn command check for other roles + if (name == undefined) { + for (let role of listOfRoles) { + // check for claim order + if (role == 'claimer' && this.memory.claimRoom != undefined) { + //console.log("need claimer "+this.memory.claimRoom); + // try to spawn a claimer + name = this.createClaimer(this.memory.claimRoom); + // if that worked + if (name != undefined && _.isString(name)) { + // delete the claim order + delete this.memory.claimRoom; + } + } + // if no claim order was found, check other roles + else if (numberOfCreeps[role] < this.memory.minCreeps[role]) { + if (role == 'lorry') { + name = this.createLorry(150); + } + else { + name = this.createCustomCreep(maxEnergy, role); + } + break; + } + } + } + + // if none of the above caused a spawn command check for LongDistanceHarvesters + /** @type {Object.} */ + let numberOfLongDistanceHarvesters = {}; + if (name == undefined) { + + // count the number of long distance harvesters globally + for (let roomName in this.memory.minLongDistanceHarvesters) { + numberOfLongDistanceHarvesters[roomName] = _.sum(Game.creeps, (c) => + c.memory.role == 'longDistanceHarvester' && c.memory.target == roomName) + if (numberOfLongDistanceHarvesters[roomName] < this.memory.minLongDistanceHarvesters[roomName]) { + name = this.createLongDistanceHarvester(maxEnergy, 3, room.name, roomName, 0); + } + } + } + + // print name to console if spawning was a success + if (name != undefined && _.isString(name)) { + console.log(this.name + " spawned new creep: " + name + " (" + Game.creeps[name].memory.role + ")"); + for (let role of listOfRoles) { + console.log(role + ": " + numberOfCreeps[role]); + } + for (let roomName in numberOfLongDistanceHarvesters) { + console.log("LongDistanceHarvester" + roomName + ": " + numberOfLongDistanceHarvesters[roomName]); + } + } + }; + +// create a new function for StructureSpawn +StructureSpawn.prototype.createCustomCreep = + function (energy, roleName) { + // create a balanced body as big as possible with the given energy + var numberOfParts = Math.floor(energy / 200); + // make sure the creep is not too big (more than 50 parts) + numberOfParts = Math.min(numberOfParts, Math.floor(50 / 3)); + var body = []; + for (let i = 0; i < numberOfParts; i++) { + body.push(WORK); + } + for (let i = 0; i < numberOfParts; i++) { + body.push(CARRY); + } + for (let i = 0; i < numberOfParts; i++) { + body.push(MOVE); + } + + // create creep with the created body and the given role + return this.createCreep(body, undefined, { role: roleName, working: false }); + }; + +// create a new function for StructureSpawn +StructureSpawn.prototype.createLongDistanceHarvester = + function (energy, numberOfWorkParts, home, target, sourceIndex) { + // create a body with the specified number of WORK parts and one MOVE part per non-MOVE part + var body = []; + for (let i = 0; i < numberOfWorkParts; i++) { + body.push(WORK); + } + + // 150 = 100 (cost of WORK) + 50 (cost of MOVE) + energy -= 150 * numberOfWorkParts; + + var numberOfParts = Math.floor(energy / 100); + // make sure the creep is not too big (more than 50 parts) + numberOfParts = Math.min(numberOfParts, Math.floor((50 - numberOfWorkParts * 2) / 2)); + for (let i = 0; i < numberOfParts; i++) { + body.push(CARRY); + } + for (let i = 0; i < numberOfParts + numberOfWorkParts; i++) { + body.push(MOVE); + } + + // create creep with the created body + return this.createCreep(body, undefined, { + role: 'longDistanceHarvester', + home: home, + target: target, + sourceIndex: sourceIndex, + working: false + }); + }; + +// create a new function for StructureSpawn +StructureSpawn.prototype.createClaimer = + function (target) { + return this.createCreep([CLAIM,CLAIM,MOVE], undefined, { role: 'claimer', target: target, home: this.name }); + }; + +// create a new function for StructureSpawn +StructureSpawn.prototype.createMiner = + function (sourceId) { + return this.createCreep([WORK, WORK, WORK, WORK, WORK, MOVE], undefined, + { role: 'miner', sourceId: sourceId }); + }; + +// create a new function for StructureSpawn +StructureSpawn.prototype.createLorry = + function (energy) { + // create a body with twice as many CARRY as MOVE parts + var numberOfParts = Math.floor(energy / 150); + // make sure the creep is not too big (more than 50 parts) + numberOfParts = Math.min(numberOfParts, Math.floor(50 / 3)); + var body = []; + for (let i = 0; i < numberOfParts * 2; i++) { + body.push(CARRY); + } + for (let i = 0; i < numberOfParts; i++) { + body.push(MOVE); + } + + // create creep with the created body and the role 'lorry' + return this.createCreep(body, undefined, { role: 'lorry', working: false }); + }; \ No newline at end of file diff --git a/src/prototype.tower.js b/src/prototype.tower.js new file mode 100644 index 0000000..db0e7af --- /dev/null +++ b/src/prototype.tower.js @@ -0,0 +1,18 @@ +StructureTower.prototype.defend = + function () { + // find closes hostile creep + var target = this.pos.findClosestByRange(FIND_HOSTILE_CREEPS); + // if one is found... + if (target != undefined) { + // ...FIRE! + this.attack(target); + } + + var closestDamagedStructure = this.pos.findClosestByRange(FIND_STRUCTURES, { + filter: (structure) => structure.hits < structure.hitsMax + }); + + if(closestDamagedStructure) { + this.repair(closestDamagedStructure); + } + }; \ No newline at end of file diff --git a/src/role.builder.js b/src/role.builder.js new file mode 100644 index 0000000..065f1b1 --- /dev/null +++ b/src/role.builder.js @@ -0,0 +1,60 @@ +var roleUpgrader = require('role.upgrader'); + +module.exports = { + // a function to run the logic for this role + /** @param {Creep} creep */ + run: function (creep) { + // if target is defined and creep is not in target room + if (creep.memory.target != undefined && creep.room.name != creep.memory.target) { + // find exit to target room + var exit = creep.room.findExitTo(creep.memory.target); + // move to exit + creep.moveTo(creep.pos.findClosestByRange(exit)); + // return the function to not do anything else + return; + } + + // if creep is trying to complete a constructionSite but has no energy left + if (creep.memory.working == true && creep.carry.energy == 0) { + var time = creep.memory.ttl - creep.ticksToLive; + console.log(creep.name + " : " + creep.memory.role + " > " + time); + + if(creep.ticksToLive < 100) { + console.log(creep.name + " suicide for ttl : " + creep.ticksToLive); + creep.suicide(); + } + // switch state + creep.memory.ttl = creep.ticksToLive; + // switch state + creep.memory.working = false; + } + // if creep is harvesting energy but is full + else if (creep.memory.working == false && creep.carry.energy == creep.carryCapacity) { + // switch state + creep.memory.working = true; + } + + // if creep is supposed to complete a constructionSite + if (creep.memory.working == true) { + // find closest constructionSite + var constructionSite = creep.pos.findClosestByPath(FIND_CONSTRUCTION_SITES); + // if one is found + if (constructionSite != undefined) { + // try to build, if the constructionSite is not in range + if (creep.build(constructionSite) == ERR_NOT_IN_RANGE) { + // move towards the constructionSite + creep.moveTo(constructionSite); + } + } + // if no constructionSite is found + else { + // go upgrading the controller + roleUpgrader.run(creep); + } + } + // if creep is supposed to get energy + else { + creep.getEnergy(true, true); + } + } +}; \ No newline at end of file diff --git a/src/role.claimer.js b/src/role.claimer.js new file mode 100644 index 0000000..c9adc4c --- /dev/null +++ b/src/role.claimer.js @@ -0,0 +1,33 @@ +module.exports = { + // a function to run the logic for this role + run: function(creep) { + // if in target room + if(creep.memory.mission != true && creep.ticksToLive < 5) { + console.log("I need a new claimer on " + creep.memory.target); + Game.spawns[creep.memory.home].memory.claimRoom = creep.memory.target; + creep.memory.mission = true; + } + + if (creep.room.name != creep.memory.target) { + // find exit to target room + var exit = creep.room.findExitTo(creep.memory.target); + // move to exit + creep.moveTo(creep.pos.findClosestByRange(exit)); + } else if (cl == OK) { + creep.memory.mission = true; + } else { + // try to claim controller + var cl = creep.claimController(creep.room.controller); + + if (cl == ERR_NOT_IN_RANGE) { + // move towards the controller + creep.moveTo(creep.room.controller); + } else if (cl == ERR_GCL_NOT_ENOUGH) { + var re = creep.reserveController(creep.room.controller); + if(re == ERR_NOT_IN_RANGE) { + creep.moveTo(creep.room.controller); + } + } + } + } +}; \ No newline at end of file diff --git a/src/role.harvester.js b/src/role.harvester.js new file mode 100644 index 0000000..7402144 --- /dev/null +++ b/src/role.harvester.js @@ -0,0 +1,61 @@ +module.exports = { + // a function to run the logic for this role + /** @param {Creep} creep */ + run: function(creep) { + // if creep is bringing energy to a structure but has no energy left + if (creep.memory.working == true && creep.carry.energy == 0) { + var time = creep.memory.ttl - creep.ticksToLive; + console.log(creep.name + " : " + creep.memory.role + " > " + time); + + if(creep.ticksToLive < 100) + creep.suicide(); + // switch state + creep.memory.ttl = creep.ticksToLive; + creep.memory.working = false; + } + // if creep is harvesting energy but is full + else if (creep.memory.working == false && creep.carry.energy == creep.carryCapacity) { + // switch state + creep.memory.working = true; + } + + // if creep is supposed to transfer energy to a structure + if (creep.memory.working == true) { + // find closest spawn, extension or tower which is not full + var structure = creep.pos.findClosestByPath(FIND_MY_STRUCTURES, { + // the second argument for findClosestByPath is an object which takes + // a property called filter which can be a function + // we use the arrow operator to define it + filter: (s) => (s.structureType == STRUCTURE_SPAWN + || s.structureType == STRUCTURE_EXTENSION + || s.structureType == STRUCTURE_TOWER + || s.structureType == STRUCTURE_LAB) + && s.energy < s.energyCapacity + }); + + if (structure == undefined) { + structure = creep.room.storage; + } + + // if we found one + if (structure != undefined) { + // try to transfer energy, if it is not in range + if (creep.transfer(structure, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) { + // move towards it + creep.moveTo(structure); + } + } + + if (structure == undefined && (creep.ticksToLive < 50 || creep.carry.energy%50 != 0)) { + if (creep.upgradeController(creep.room.controller) == ERR_NOT_IN_RANGE) { + // if not in range, move towards the controller + creep.moveTo(creep.room.controller); + } + } + } + // if creep is supposed to harvest energy from source + else { + creep.getEnergy(false, true); + } + } +}; \ No newline at end of file diff --git a/src/role.longDistanceHarvester.js b/src/role.longDistanceHarvester.js new file mode 100644 index 0000000..36c8210 --- /dev/null +++ b/src/role.longDistanceHarvester.js @@ -0,0 +1,90 @@ +module.exports = { + // a function to run the logic for this role + /** @param {Creep} creep */ + run: function(creep) { + // if creep is bringing energy to a structure but has no energy left + if (creep.memory.working == true && creep.carry.energy == 0) { + var time = creep.memory.ttl - creep.ticksToLive; + console.log(creep.name + " : " + creep.memory.role + " > " + time); + + if(creep.ticksToLive < 200) { + console.log(creep.name + " suicide for ttl : " + creep.ticksToLive); + creep.suicide(); + } + creep.memory.ttl = creep.ticksToLive; + // switch state + creep.memory.working = false; + } + // if creep is harvesting energy but is full + else if (creep.memory.working == false && creep.carry.energy == creep.carryCapacity) { + // switch state + creep.memory.working = true; + } + + // if creep is supposed to transfer energy to a structure + if (creep.memory.working == true) { + // if in home room + if (creep.room.name == creep.memory.home) { + // find closest spawn, extension or tower which is not full + var structure = creep.pos.findClosestByPath(FIND_MY_STRUCTURES, { + // the second argument for findClosestByPath is an object which takes + // a property called filter which can be a function + // we use the arrow operator to define it + filter: (s) => (s.structureType == STRUCTURE_SPAWN + || s.structureType == STRUCTURE_EXTENSION + || s.structureType == STRUCTURE_TOWER) + && s.energy < s.energyCapacity + }); + + if (structure == undefined) { + structure = creep.room.storage; + } + + // if we found one + if (structure != undefined) { + // try to transfer energy, if it is not in range + if (creep.transfer(structure, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) { + // move towards it + creep.moveTo(structure); + } + } + + + if (structure == undefined) { + if (creep.upgradeController(creep.room.controller) == ERR_NOT_IN_RANGE) { + // if not in range, move towards the controller + creep.moveTo(creep.room.controller); + } + } + } + // if not in home room... + else { + // find exit to home room + var exit = creep.room.findExitTo(creep.memory.home); + // and move to exit + creep.moveTo(creep.pos.findClosestByRange(exit)); + } + } + // if creep is supposed to harvest energy from source + else { + // if in target room + if (creep.room.name == creep.memory.target) { + // find source + var source = creep.room.find(FIND_SOURCES)[creep.memory.sourceIndex]; + + // try to harvest energy, if the source is not in range + if (creep.harvest(source) == ERR_NOT_IN_RANGE) { + // move towards the source + creep.moveTo(source); + } + } + // if not in target room + else { + // find exit to target room + var exit = creep.room.findExitTo(creep.memory.target); + // move to exit + creep.moveTo(creep.pos.findClosestByRange(exit)); + } + } + } +}; \ No newline at end of file diff --git a/src/role.lorry.js b/src/role.lorry.js new file mode 100644 index 0000000..3b45646 --- /dev/null +++ b/src/role.lorry.js @@ -0,0 +1,63 @@ +module.exports = { + // a function to run the logic for this role + /** @param {Creep} creep */ + run: function(creep) { + // if creep is bringing energy to a structure but has no energy left + if (creep.memory.working == true && creep.carry.energy == 0) { + // switch state + creep.memory.working = false; + } + // if creep is harvesting energy but is full + else if (creep.memory.working == false && creep.carry.energy == creep.carryCapacity) { + // switch state + creep.memory.working = true; + } + + // if creep is supposed to transfer energy to a structure + if (creep.memory.working == true) { + // find closest spawn, extension or tower which is not full + var structure = creep.pos.findClosestByPath(FIND_MY_STRUCTURES, { + // the second argument for findClosestByPath is an object which takes + // a property called filter which can be a function + // we use the arrow operator to define it + filter: (s) => (s.structureType == STRUCTURE_SPAWN + || s.structureType == STRUCTURE_EXTENSION + || s.structureType == STRUCTURE_TOWER) + && s.energy < s.energyCapacity + }); + + if (structure == undefined) { + structure = creep.room.storage; + } + + // if we found one + if (structure != undefined) { + // try to transfer energy, if it is not in range + if (creep.transfer(structure, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) { + // move towards it + creep.moveTo(structure); + } + } + } + // if creep is supposed to get energy + else { + // find closest container + let container = creep.pos.findClosestByPath(FIND_STRUCTURES, { + filter: s => s.structureType == STRUCTURE_CONTAINER && s.store[RESOURCE_ENERGY] > 0 + }); + + if (container == undefined) { + container = creep.room.storage; + } + + // if one was found + if (container != undefined) { + // try to withdraw energy, if the container is not in range + if (creep.withdraw(container, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) { + // move towards it + creep.moveTo(container); + } + } + } + } +}; \ No newline at end of file diff --git a/src/role.miner.js b/src/role.miner.js new file mode 100644 index 0000000..e45e49c --- /dev/null +++ b/src/role.miner.js @@ -0,0 +1,22 @@ +module.exports = { + // a function to run the logic for this role + run: function (creep) { + // get source + let source = Game.getObjectById(creep.memory.sourceId); + // find container next to source + let container = source.pos.findInRange(FIND_STRUCTURES, 1, { + filter: s => s.structureType == STRUCTURE_CONTAINER + })[0]; + + // if creep is on top of the container + if (creep.pos.isEqualTo(container.pos)) { + // harvest source + creep.harvest(source); + } + // if creep is not on top of the container + else { + // move towards it + creep.moveTo(container); + } + } +}; \ No newline at end of file diff --git a/src/role.repairer.js b/src/role.repairer.js new file mode 100644 index 0000000..44d227e --- /dev/null +++ b/src/role.repairer.js @@ -0,0 +1,59 @@ +var roleBuilder = require('role.builder'); + +module.exports = { + // a function to run the logic for this role + /** @param {Creep} creep */ + run: function(creep) { + // if creep is trying to repair something but has no energy left + if (creep.memory.working == true && creep.carry.energy == 0) { + var time = creep.memory.ttl - creep.ticksToLive; + console.log(creep.name + " : " + creep.memory.role + " > " + time); + + if(creep.ticksToLive < 150) { + console.log(creep.name + " suicide for ttl : " + creep.ticksToLive); + creep.suicide(); + } + // switch state + creep.memory.ttl = creep.ticksToLive; + + // switch state + creep.memory.working = false; + } + // if creep is harvesting energy but is full + else if (creep.memory.working == false && creep.carry.energy == creep.carryCapacity) { + // switch state + creep.memory.working = true; + } + + // if creep is supposed to repair something + if (creep.memory.working == true) { + // find closest structure with less than max hits + // Exclude walls because they have way too many max hits and would keep + // our repairers busy forever. We have to find a solution for that later. + var structure = creep.pos.findClosestByPath(FIND_STRUCTURES, { + // the second argument for findClosestByPath is an object which takes + // a property called filter which can be a function + // we use the arrow operator to define it + filter: (s) => s.hits < s.hitsMax && s.structureType != STRUCTURE_WALL + }); + + // if we find one + if (structure != undefined) { + // try to repair it, if it is out of range + if (creep.repair(structure) == ERR_NOT_IN_RANGE) { + // move towards it + creep.moveTo(structure); + } + } + // if we can't fine one + else { + // look for construction sites + roleBuilder.run(creep); + } + } + // if creep is supposed to get energy + else { + creep.getEnergy(true, true); + } + } +}; \ No newline at end of file diff --git a/src/role.upgrader.js b/src/role.upgrader.js new file mode 100644 index 0000000..57cfdbe --- /dev/null +++ b/src/role.upgrader.js @@ -0,0 +1,41 @@ +module.exports = { + // a function to run the logic for this role + /** @param {Creep} creep */ + run: function(creep) { + // if creep is bringing energy to the controller but has no energy left + if (creep.memory.working == true && creep.carry.energy == 0) { + var time = creep.memory.ttl - creep.ticksToLive; + console.log(creep.name + " : " + creep.memory.role + " > " + time); + + if(creep.ticksToLive < 100) { + console.log(creep.name + " suicide for ttl : " + creep.ticksToLive); + creep.suicide(); + } + // switch state + creep.memory.ttl = creep.ticksToLive; + // switch state + creep.memory.working = false; + } + // if creep is harvesting energy but is full + else if (creep.memory.working == false && creep.carry.energy == creep.carryCapacity) { + // switch state + creep.memory.working = true; + } + + // if creep is supposed to transfer energy to the controller + if (creep.memory.working == true) { + // instead of upgraderController we could also use: + // if (creep.transfer(creep.room.controller, RESOURCE_ENERGY) == ERR_NOT_IN_RANGE) { + + // try to upgrade the controller + if (creep.upgradeController(creep.room.controller) == ERR_NOT_IN_RANGE) { + // if not in range, move towards the controller + creep.moveTo(creep.room.controller); + } + } + // if creep is supposed to get energy + else { + creep.getEnergy(true, true); + } + } +}; \ No newline at end of file diff --git a/src/role.wallReprairer.js b/src/role.wallReprairer.js new file mode 100644 index 0000000..c202086 --- /dev/null +++ b/src/role.wallReprairer.js @@ -0,0 +1,72 @@ +var roleBuilder = require('role.builder'); + +module.exports = { + // a function to run the logic for this role + /** @param {Creep} creep */ + run: function(creep) { + // if creep is trying to repair something but has no energy left + if (creep.memory.working == true && creep.carry.energy == 0) { + var time = creep.memory.ttl - creep.ticksToLive; + console.log(creep.name + " : " + creep.memory.role + " > " + time); + + if(creep.ticksToLive < 100) { + console.log(creep.name + " suicide for ttl : " + creep.ticksToLive); + creep.suicide(); + } + // switch state + creep.memory.ttl = creep.ticksToLive; + // switch state + creep.memory.working = false; + } + // if creep is harvesting energy but is full + else if (creep.memory.working == false && creep.carry.energy == creep.carryCapacity) { + // switch state + creep.memory.working = true; + } + + // if creep is supposed to repair something + if (creep.memory.working == true) { + // find all walls in the room + var walls = creep.room.find(FIND_STRUCTURES, { + filter: (s) => s.structureType == STRUCTURE_WALL + }); + + var target = undefined; + + // loop with increasing percentages + for (let percentage = 0.0001; percentage <= 1; percentage = percentage + 0.0001){ + // find a wall with less than percentage hits + for (let wall of walls) { + if (wall.hits / wall.hitsMax < percentage) { + target = wall; + break; + } + } + + // if there is one + if (target != undefined) { + // break the loop + break; + } + } + + // if we find a wall that has to be repaired + if (target != undefined) { + // try to repair it, if not in range + if (creep.repair(target) == ERR_NOT_IN_RANGE) { + // move towards it + creep.moveTo(target); + } + } + // if we can't fine one + else { + // look for construction sites + roleBuilder.run(creep); + } + } + // if creep is supposed to get energy + else { + creep.getEnergy(true, true); + } + } +}; \ No newline at end of file