From 4d0aec9bbe7326fbe5ac472f056243fc8c086d33 Mon Sep 17 00:00:00 2001 From: Arne Schauf Date: Thu, 1 Feb 2024 17:12:34 +0100 Subject: [PATCH] stuff --- default/common.js | 30 ++++++++++++++++ default/globals.js | 16 +++++++-- default/link.js | 24 ++++++++++--- default/main.js | 33 +++++++++++++++-- default/role.builder.js | 16 +++++++-- default/role.filler.js | 27 +++++++++++--- default/role.harvester.js | 6 ++-- default/role.hauler.js | 24 ++++++------- default/role.rangedAttacker.js | 4 +-- default/role.remoteHarvester.js | 31 ++++++++-------- default/role.transporter.js | 30 +++++----------- default/role.upgrader.js | 37 ++++++++++++------- default/spawn.js | 63 +++++++++++++++++++++++++++++++-- 13 files changed, 253 insertions(+), 88 deletions(-) diff --git a/default/common.js b/default/common.js index a1ba1f2..620d19a 100644 --- a/default/common.js +++ b/default/common.js @@ -3,9 +3,39 @@ const consts = { HARVESTING: 2, CONTINUE_ACTIVITY: 3, } +global.costMatrices = {} module.exports = { consts, + findWalkablePath (from, goals, opts) { + let roomCallback = roomName => { + if (costMatrices[roomName] || Game.time % 500 === 0) { + return costMatrices[roomName] + } + let room = Game.rooms[roomName]; + // In this example `room` will always exist, but since + // PathFinder supports searches which span multiple rooms + // you should be careful! + if (!room) return; + let costs = new PathFinder.CostMatrix; + + room.find(FIND_STRUCTURES).forEach(function(struct) { + if (struct.structureType === STRUCTURE_ROAD) { + // Favor roads over plain tiles + costs.set(struct.pos.x, struct.pos.y, 1); + } else if (struct.structureType !== STRUCTURE_CONTAINER && + (struct.structureType !== STRUCTURE_RAMPART || + !struct.my)) { + // Can't walk through non-walkable buildings + costs.set(struct.pos.x, struct.pos.y, 0xff); + } + }); + + costMatrices[roomName] = costs + return costs + } + return PathFinder.search(from, goals, Object.assign({roomCallback}, opts)) + }, harvestEnergy (creep) { if (!creep.memory.harvestingEnergy && creep.store[RESOURCE_ENERGY] > 0) { return consts.CONTINUE_ACTIVITY diff --git a/default/globals.js b/default/globals.js index 94ef0f1..b1d789d 100644 --- a/default/globals.js +++ b/default/globals.js @@ -10,6 +10,7 @@ const roleHauler = require('./role.hauler') const roleHealer = require('./role.healer') const roleFiller = require('./role.filler') const roleReserver = require('./role.reserver') +const {findWalkablePath} = require('./common') global.roleModules = [ roleHarvester, @@ -42,9 +43,18 @@ global.moveToRoom = function (creep, targetRoom) { return ALREADY_IN_ROOM } - const exitDir = Game.map.findExit(creep.room, targetRoom); - const exit = creep.pos.findClosestByRange(exitDir); - creep.moveTo(exit); + let target + if (Game.rooms[targetRoom]) { + target = Game.rooms[targetRoom].find(FIND_SOURCES) + if (target.length > 0) { + target = target[0] + } + } + if (!target) { + const exitDir = Game.map.findExit(creep.room, targetRoom); + target = creep.pos.findClosestByRange(exitDir); + } + creep.moveByPath(findWalkablePath(creep.pos, target, {}).path); creep.say(targetRoom) return MOVING } diff --git a/default/link.js b/default/link.js index fad94b7..de682e3 100644 --- a/default/link.js +++ b/default/link.js @@ -4,16 +4,32 @@ module.exports = { if (room.memory.controllerLink && !Game.getObjectById(room.memory.controllerLink)) { delete room.memory.controllerLink } + if (room.memory.storageLink && !Game.getObjectById(room.memory.storageLink)) { + delete room.memory.storageLink + } + if (!room.controller.my) { + continue + } + if (!room.memory.controllerLink) { + let links = room.controller.pos.findInRange(FIND_STRUCTURES, 5, {filter: s => s.structureType === STRUCTURE_LINK}) + if (links.length) { + room.memory.controllerLink = links[0].id + return + } + } + if (!room.memory.storageLink && room.storage) { + let links = room.storage.pos.findInRange(FIND_STRUCTURES, 2, {filter: s => s.structureType === STRUCTURE_LINK}) + if (links.length) { + room.memory.storageLink = links[0].id + return + } + } } }, tick (link) { if (link.room.memory.controllerLink === link.id) { return } - if (link.pos.findInRange(FIND_STRUCTURES, 5, {filter: s => s.structureType === STRUCTURE_CONTROLLER}).length) { - link.room.memory.controllerLink = link.id - return - } if (link.room.memory.controllerLink && !link.store.getFreeCapacity(RESOURCE_ENERGY)) { let targetLink = Game.getObjectById(link.room.memory.controllerLink) diff --git a/default/main.js b/default/main.js index 322bae5..cfcc2a0 100644 --- a/default/main.js +++ b/default/main.js @@ -3,8 +3,19 @@ const libSpawn = require('spawn') require('globals') +let lastTime = Game.cpu.getUsed() +function profilingDebug(label, noLog) { + let current = Game.cpu.getUsed() + let used = current-lastTime + if (!noLog) { + console.log(`${used.toFixed(2)} (${current.toFixed(2)}) [${label}]`) + } + lastTime = current + return used +} module.exports.loop = function () { + profilingDebug('Start') // Cleanups if (!Memory.repairers) { Memory.repairers = {} @@ -18,19 +29,23 @@ module.exports.loop = function () { } } libLink.tickInit() + profilingDebug('Link init') libSpawn.tickInit() + profilingDebug('Spawn init') // tickInit for (let role of roleModules) { role.idling = 0 if (role.tickInit) { role.tickInit() + profilingDebug(role.name + ' init') } } for (let role of roleModules) { if (role.cleanup) { role.cleanup() + profilingDebug(role.name + ' cleanup') } } @@ -70,8 +85,14 @@ module.exports.loop = function () { for (let link of spawn.room.find(FIND_STRUCTURES, {filter: s => s.structureType === STRUCTURE_LINK})) { libLink.tick(link) } + + let usedByRole = {} + let roleCount = {} for (let creep of Object.values(Game.creeps)) { if (creep.store.getFreeCapacity(RESOURCE_ENERGY) > 0) { + for (let target of creep.pos.findInRange(FIND_DROPPED_RESOURCES, 1)) { + creep.pickup(target) + } for (let target of creep.pos.findInRange(FIND_TOMBSTONES, 1, {filter: t => t.store[RESOURCE_ENERGY] > 0})) { creep.withdraw(target, RESOURCE_ENERGY) } @@ -88,14 +109,22 @@ module.exports.loop = function () { if (creep.fatigue > 0) { if (creep.pos.findInRange(FIND_STRUCTURES, 0, {filter: s => s.structureType === STRUCTURE_ROAD}).length === 0 - && creep.pos.findInRange(FIND_MY_CONSTRUCTION_SITES, 1, {filter: s => s.structureType === STRUCTURE_ROAD}).length === 0) { + && creep.pos.findInRange(FIND_MY_CONSTRUCTION_SITES, 0, {filter: s => s.structureType === STRUCTURE_ROAD}).length === 0) { creep.room.memory.fatigues[creep.pos.x + '_' + creep.pos.y] = (creep.room.memory.fatigues[creep.pos.x + '_' + creep.pos.y] || 0) + creep.fatigue } } + if (!usedByRole[creep.memory.role]) { + usedByRole[creep.memory.role] = 0 + roleCount[creep.memory.role] = 0 + } + usedByRole[creep.memory.role] += profilingDebug(creep.name + ' tick', true) + roleCount[creep.memory.role]++ } + Object.entries(usedByRole).forEach(([role, used]) => console.log(`${used.toFixed(2)} (${(used / roleCount[role]).toFixed(2)}) ${role} (${roleCount[role]})`)) libSpawn.tick(spawn) + profilingDebug('spawn tick') let towers = spawn.room.find(FIND_STRUCTURES, {filter: structure => structure.structureType === STRUCTURE_TOWER}) for (let tower of towers) { @@ -119,7 +148,7 @@ module.exports.loop = function () { // } spawn.room.visual.text( - `${Game.cpu.getUsed().toFixed(1)} / ${Game.cpu.tickLimit} (${Game.cpu.bucket})`, + `${Game.time}: ${Game.cpu.getUsed().toFixed(1)} / ${Game.cpu.tickLimit} (${Game.cpu.bucket})`, 1, 1, {align: 'left', opacity: 0.8}); diff --git a/default/role.builder.js b/default/role.builder.js index f311f86..3473e44 100644 --- a/default/role.builder.js +++ b/default/role.builder.js @@ -6,7 +6,10 @@ module.exports = { name: 'builder', prio: 5, getCount: colonyRoom => { - return Math.min(5, Math.max(1, colonyRoom.find(FIND_MY_CONSTRUCTION_SITES).length)) + 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], @@ -56,7 +59,7 @@ module.exports = { let targets = creep.pos.findInRange(FIND_STRUCTURES, 1, { filter: s => (s.structureType === STRUCTURE_CONTAINER || s.structureType === STRUCTURE_STORAGE) - && s.store[RESOURCE_ENERGY] > 0 + && s.store[RESOURCE_ENERGY] > Math.min(creep.store.getFreeCapacity(RESOURCE_ENERGY), 400) }) if (targets.length) { creep.withdraw(targets[0], RESOURCE_ENERGY) @@ -96,9 +99,16 @@ module.exports = { target = creep.pos.findClosestByPath(FIND_CONSTRUCTION_SITES); } if (target) { - if (creep.build(target) === ERR_NOT_IN_RANGE) { + 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 } diff --git a/default/role.filler.js b/default/role.filler.js index f13a6c6..013f100 100644 --- a/default/role.filler.js +++ b/default/role.filler.js @@ -3,7 +3,15 @@ const common = require('common') module.exports = { name: 'filler', prio: 4, - count: 2, + getCount: colonyRoom => { + if (colonyRoom.memory.spawnContainers.length === 0) { + return 0 + } + if (colonyRoom.controller.level < 5) { + return 1 + } + return 2 + }, minRcl: 2, bodies: [ [CARRY, CARRY, MOVE], @@ -15,7 +23,7 @@ module.exports = { if (creep.store.getFreeCapacity(RESOURCE_ENERGY) === 0) { creep.memory.loading = false } - else if (creep.store[RESOURCE_ENERGY] === 0) { + else if (creep.store[RESOURCE_ENERGY] < 50) { creep.memory.loading = true } @@ -31,7 +39,10 @@ module.exports = { creep.moveTo(target, {visualizePathStyle: {stroke: '#f7e180'}}) } } else { - creep.moveTo(creep.pos.findClosestByRange(FIND_FLAGS, {filter: flag => flag.name.startsWith('idle')}), {visualizePathStyle: {stroke: '#ff0000'}}); + // creep.moveTo(creep.pos.findClosestByRange(FIND_FLAGS, {filter: flag => flag.name.startsWith('idle')}), {visualizePathStyle: {stroke: '#ff0000'}}); + if (creep.store[RESOURCE_ENERGY] > 0) { + creep.memory.loading = false + } return 'idle' } } @@ -44,14 +55,20 @@ module.exports = { && s.store.getFreeCapacity(RESOURCE_ENERGY) > 0 }) if (!target && creep.room.storage && creep.room.storage.store[RESOURCE_ENERGY] > 1e5) { - target = creep.room.storage.pos.findClosestByRange(FIND_STRUCTURES, {filter: s => s.structureType === STRUCTURE_LINK}) + target = Game.getObjectById(creep.room.memory.storageLink) + if (target && target.store.getFreeCapacity(RESOURCE_ENERGY) === 0 && creep.pos.getRangeTo(target) === 1) { + target = undefined + } } if (target) { if (creep.transfer(target, RESOURCE_ENERGY) === ERR_NOT_IN_RANGE) { creep.moveTo(target, {visualizePathStyle: {stroke: '#00ff0f'}}); } } else { - creep.moveTo(creep.pos.findClosestByRange(FIND_FLAGS, {filter: flag => flag.name.startsWith('idle')}), {visualizePathStyle: {stroke: '#ff0000'}}); + // creep.moveTo(creep.pos.findClosestByRange(FIND_FLAGS, {filter: flag => flag.name.startsWith('idle')}), {visualizePathStyle: {stroke: '#ff0000'}}); + if (creep.store.getFreeCapacity(RESOURCE_ENERGY) > 0) { + creep.memory.loading = true + } return 'idle' } } diff --git a/default/role.harvester.js b/default/role.harvester.js index 4c90bea..879c27d 100644 --- a/default/role.harvester.js +++ b/default/role.harvester.js @@ -6,6 +6,7 @@ module.exports = { count: 3, bodies: [ [WORK, WORK, CARRY, MOVE], + [WORK, WORK, WORK, CARRY, MOVE], [WORK, WORK, WORK, WORK, WORK, CARRY, MOVE], [WORK, WORK, WORK, WORK, WORK, CARRY, MOVE, MOVE], [WORK, WORK, WORK, WORK, WORK, CARRY, MOVE, MOVE, MOVE], @@ -22,8 +23,7 @@ module.exports = { filter: tc => tc.store.getFreeCapacity(RESOURCE_ENERGY) && tc.memory.role !== 'harvester' }); if (targetCreeps.length > 0) { - let tc = _.sortBy(targetCreeps, el => el.store.getFreeCapacity(RESOURCE_ENERGY))[targetCreeps.length - 1] - creep.transfer(tc, RESOURCE_ENERGY) + creep.transfer(targetCreeps[0], RESOURCE_ENERGY) } else { let targets = creep.pos.findInRange(FIND_STRUCTURES, 1, { @@ -57,7 +57,7 @@ module.exports = { let target = Game.getObjectById(creep.memory.source) let actionResult = creep.harvest(target) if (actionResult === ERR_NOT_IN_RANGE) { - creep.moveTo(target, {visualizePathStyle: {stroke: '#ffaa00'}}); + creep.moveTo(target, {reusePath: false, visualizePathStyle: {stroke: '#ffaa00'}}); } if (actionResult !== OK) { return 'idle' diff --git a/default/role.hauler.js b/default/role.hauler.js index 8af76d9..f1e8bd2 100644 --- a/default/role.hauler.js +++ b/default/role.hauler.js @@ -1,8 +1,11 @@ +global.hostileCreepCount = {} + module.exports = { name: 'hauler', prio: 11, tickInit () { for (let room of Object.values(Game.rooms)) { + hostileCreepCount[room.name] = room.find(FIND_HOSTILE_CREEPS, {filter: c => creepIsAttacker(c)}).length if (!room.memory.hauler) { room.memory.hauler = {} } @@ -15,7 +18,7 @@ module.exports = { room.memory.hauler.targetCount = 0 continue } - room.memory.hauler.targetCount = Math.max(filledContainers.length, harvesters.length) * 6 + room.memory.hauler.targetCount = Math.max(filledContainers.length, harvesters.length) * 4 } }, nextSpawn (spawn, roleCreeps) { @@ -29,12 +32,7 @@ module.exports = { } }, tick (creep) { - let targetRoom = Game.rooms[creep.memory.room] - let hostileCreeps = [1] - if (targetRoom) { - hostileCreeps = targetRoom.find(FIND_HOSTILE_CREEPS, {filter: c => creepIsAttacker(c)}) - } - if (creep.store.getFreeCapacity(RESOURCE_ENERGY) > 0 && hostileCreeps.length === 0) { + if (creep.store.getFreeCapacity(RESOURCE_ENERGY) > 0 && hostileCreepCount[creep.memory.room] === 0) { if (moveToRoom(creep, creep.memory.room) === MOVING) { return } @@ -44,7 +42,7 @@ module.exports = { creep.pickup(dropped[0]) } - dropped = creep.pos.findClosestByPath(FIND_DROPPED_RESOURCES, {filter: r => r.amount >= 100}); + dropped = creep.pos.findClosestByRange(FIND_DROPPED_RESOURCES, {filter: r => r.amount >= 100}); if (dropped) { if (creep.pickup(dropped) === ERR_NOT_IN_RANGE) { creep.moveTo(dropped) @@ -52,18 +50,18 @@ module.exports = { } } - let target = creep.pos.findClosestByPath(FIND_TOMBSTONES, { + let target = creep.pos.findClosestByRange(FIND_TOMBSTONES, { filter: (structure) => structure.store[RESOURCE_ENERGY] > 0 }) if (!target) { - target = creep.pos.findClosestByPath(FIND_RUINS, { + target = creep.pos.findClosestByRange(FIND_RUINS, { filter: (structure) => structure.store[RESOURCE_ENERGY] > 0 }) } if (!target) { - target = creep.pos.findClosestByPath(FIND_STRUCTURES, { + target = creep.pos.findClosestByRange(FIND_STRUCTURES, { filter: s => { - return s.structureType === STRUCTURE_CONTAINER + return s.structureType === STRUCTURE_CONTAINER && s.store[RESOURCE_ENERGY] > creep.store.getFreeCapacity(RESOURCE_ENERGY) } }) } @@ -99,7 +97,7 @@ module.exports = { if (creep.transfer(target, RESOURCE_ENERGY) === ERR_NOT_IN_RANGE) { creep.moveTo(target) } - } else if (moveToRoom(creep,creep.memory.colony) === MOVING) { + } else if (moveToRoom(creep, creep.memory.colony) === MOVING) { return } else { creep.moveTo(creep.pos.findClosestByRange(FIND_FLAGS, {filter: flag => flag.name.startsWith('idle')}), {visualizePathStyle: {stroke: '#ff0000'}}); diff --git a/default/role.rangedAttacker.js b/default/role.rangedAttacker.js index 8b2f187..8c5178e 100644 --- a/default/role.rangedAttacker.js +++ b/default/role.rangedAttacker.js @@ -26,7 +26,7 @@ module.exports = { tick (creep) { let room = Game.rooms[creep.memory.room] let targetRoomName = creep.memory.room - if (creep.memory.colony === creep.pos.roomName + /*if (creep.memory.colony === creep.pos.roomName && (_.filter(Game.creeps, {memory: {role: 'healer', room: targetRoomName}, spawning: false}).length < Memory.rooms[targetRoomName].healer.targetCount || _.filter(Game.creeps, {memory: {role: 'attacker', room: targetRoomName}, spawning: false}).length < Memory.rooms[targetRoomName].attacker.targetCount || _.filter(Game.creeps, {memory: {role: 'rangedAttacker', room: targetRoomName}, spawning: false}).length < Memory.rooms[targetRoomName].rangedAttacker.targetCount) @@ -40,7 +40,7 @@ module.exports = { })) } return - } + }*/ if (!room || targetRoomName !== creep.pos.roomName) { creep.moveTo(new RoomPosition(25, 25, creep.memory.room)) return diff --git a/default/role.remoteHarvester.js b/default/role.remoteHarvester.js index c5940e7..21095f3 100644 --- a/default/role.remoteHarvester.js +++ b/default/role.remoteHarvester.js @@ -24,23 +24,21 @@ module.exports = { return } } else { - let targetCreeps = creep.pos.findInRange(FIND_MY_CREEPS, 1, { - filter: tc => tc.store.getFreeCapacity(RESOURCE_ENERGY) && tc.memory.role !== 'remoteHarvester' + let targets = creep.pos.findInRange(FIND_STRUCTURES, 1, { + filter: (structure) => structure.store && structure.store.getFreeCapacity(RESOURCE_ENERGY) > 0 }); - if (targetCreeps.length > 0) { - creep.transfer(targetCreeps[0], RESOURCE_ENERGY) + if (targets.length > 0) { + creep.transfer(_.min(targets, el => el.store[RESOURCE_ENERGY]), RESOURCE_ENERGY) } else { - let targets = creep.pos.findInRange(FIND_STRUCTURES, 1, { - filter: (structure) => structure.store && structure.store.getFreeCapacity(RESOURCE_ENERGY) > 0 + let targetCreeps = creep.pos.findInRange(FIND_MY_CREEPS, 1, { + filter: tc => tc.store.getFreeCapacity(RESOURCE_ENERGY) && tc.memory.role !== 'remoteHarvester' }); - if (targets.length > 0) { - creep.transfer(_.min(targets, el => el.store[RESOURCE_ENERGY]), RESOURCE_ENERGY) - } else { - if (creep.store[RESOURCE_ENERGY] >= creep.getActiveBodyparts(WORK) * 5) { - let buildTargets = creep.pos.findInRange(FIND_MY_CONSTRUCTION_SITES, 1); - if (buildTargets.length > 0 && creep.build(buildTargets[0]) === OK) { - return - } + if (targetCreeps.length > 0) { + creep.transfer(targetCreeps[0], RESOURCE_ENERGY) + } else if (creep.store[RESOURCE_ENERGY] >= creep.getActiveBodyparts(WORK) * 5) { + let buildTargets = creep.pos.findInRange(FIND_MY_CONSTRUCTION_SITES, 1); + if (buildTargets.length > 0 && creep.build(buildTargets[0]) === OK) { + return } } } @@ -49,7 +47,10 @@ module.exports = { let target = Game.getObjectById(creep.memory.source) let actionResult = creep.harvest(target) if (actionResult === ERR_NOT_IN_RANGE) { - creep.moveTo(target, {visualizePathStyle: {stroke: '#ffaa00'}}); + creep.moveTo(target, {visualizePathStyle: {stroke: '#ffaa00'}}) + } + else if (actionResult === ERR_INVALID_TARGET) { + moveToRoom(creep, creep.memory.room) } } }; diff --git a/default/role.transporter.js b/default/role.transporter.js index 6d6af50..fcc66c1 100644 --- a/default/role.transporter.js +++ b/default/role.transporter.js @@ -16,9 +16,6 @@ module.exports = { ], tickInit () { for (let room of Object.values(Game.rooms)) { - if (!room.memory.spawnContainers) { - room.memory.spawnContainers = [] - } if (!room.memory.sourceContainers) { room.memory.sourceContainers = [] } @@ -28,14 +25,6 @@ module.exports = { room.memory.controllerContainer = containers[0].id } - room.memory.spawnContainers = [] - for (let spawn of room.find(FIND_STRUCTURES, {filter: s => s.structureType === STRUCTURE_SPAWN})) { - containers = spawn.pos.findInRange(FIND_STRUCTURES, 4, {filter: s => s.structureType === STRUCTURE_CONTAINER}) - if (containers.length > 0) { - containers.forEach(el => room.memory.spawnContainers.push(el.id)) - } - } - room.memory.sourceContainers = [] for (let spawn of room.find(FIND_SOURCES)) { containers = spawn.pos.findInRange(FIND_STRUCTURES, 2, {filter: s => s.structureType === STRUCTURE_CONTAINER}) @@ -119,7 +108,7 @@ module.exports = { target = creep.pos.findClosestByPath(FIND_STRUCTURES, { filter: s => { return s.structureType === STRUCTURE_STORAGE - && s.store[RESOURCE_ENERGY] > 100 + && s.store[RESOURCE_ENERGY] > Math.min(creep.store.getFreeCapacity(RESOURCE_ENERGY), 400) } }) } @@ -150,22 +139,19 @@ module.exports = { if (target) { target = Game.getObjectById(target) } - if (!target) { + if (!target && _.filter(Game.creeps, {memory: {role: 'filler', colony: creep.memory.colony}}).length === 0) { target = creep.pos.findClosestByPath(FIND_STRUCTURES, { - filter: s => ( - s.structureType === STRUCTURE_EXTENSION - || s.structureType === STRUCTURE_SPAWN - || s.structureType === STRUCTURE_TOWER - ) + filter: s => (s.structureType === STRUCTURE_EXTENSION + || s.structureType === STRUCTURE_SPAWN) && s.store.getFreeCapacity(RESOURCE_ENERGY) > 0 && !Memory.refillers[s.id] }) } if (!target) { target = creep.pos.findClosestByPath(FIND_STRUCTURES, { - filter: s => { - return s.structureType === STRUCTURE_LINK && s.store.getFreeCapacity(RESOURCE_ENERGY) > Math.min(creep.store[RESOURCE_ENERGY], 400) - } + filter: s => s.structureType === STRUCTURE_TOWER + && s.store.getFreeCapacity(RESOURCE_ENERGY) > 0 + && !Memory.refillers[s.id] }) } if (!target) { @@ -202,7 +188,7 @@ module.exports = { creep.moveTo(creep.pos.findClosestByRange(FIND_FLAGS, {filter: flag => flag.name.startsWith('idle')}), {visualizePathStyle: {stroke: '#ff0000'}}); } if (creep.memory.idling) { - creep.say('idle ' + creep.memory.idling) + creep.say('i' + creep.memory.idling) } creep.memory.idling++ return 'idle' diff --git a/default/role.upgrader.js b/default/role.upgrader.js index f4905c4..e555892 100644 --- a/default/role.upgrader.js +++ b/default/role.upgrader.js @@ -7,13 +7,20 @@ module.exports = { prio: 6, getCount: colonyRoom => { let cc = Game.getObjectById(colonyRoom.memory.controllerContainer) - if(colonyRoom.storage) { - return Math.ceil(colonyRoom.storage.store[RESOURCE_ENERGY] / 100000) + let cl = Game.getObjectById(colonyRoom.memory.controllerLink) + if(colonyRoom.storage && cl) { + return Math.ceil(colonyRoom.storage.store[RESOURCE_ENERGY] / 50000) } - else if (colonyRoom.controller.level + cc.store) { - return Math.ceil(cc.store[RESOURCE_ENERGY] / 500) + else if(colonyRoom.storage && cc) { + return Math.ceil(colonyRoom.storage.store[RESOURCE_ENERGY] / 100000) + Math.ceil(cc.store[RESOURCE_ENERGY] / 500) + (cc.store[RESOURCE_ENERGY] > 1900 ? 2 : 0) } - return colonyRoom.controller.level + else if(colonyRoom.storage) { + return Math.ceil(colonyRoom.storage.store[RESOURCE_ENERGY] / 50000) + } + else if (cc) { + return Math.ceil(cc.store[RESOURCE_ENERGY] / 500) + (cc.store[RESOURCE_ENERGY] > 1900 ? 2 : 0) + } + return Math.min(colonyRoom.controller.level, 2) }, maxExpands: 4, baseBody: [WORK, CARRY, MOVE], @@ -34,16 +41,22 @@ module.exports = { } if (!target) { targets = creep.pos.findInRange(FIND_STRUCTURES, 1, { - filter: s => s.store && s.store[RESOURCE_ENERGY] > 0 + filter: s => (s.structureType === STRUCTURE_CONTAINER || s.structureType === STRUCTURE_LINK || s.structureType === STRUCTURE_STORAGE) + && s.store[RESOURCE_ENERGY] > 0 }) if (targets.length) { target = targets[0] } } if (!target && creep.store[RESOURCE_ENERGY] === 0) { - target = creep.room.controller.pos.findClosestByRange(FIND_STRUCTURES, { - filter: s => s.store && s.store.getCapacity(RESOURCE_ENERGY) > 0 - }) + if (creep.room.memory.controllerLink) { + target = Game.getObjectById(creep.room.memory.controllerLink) + } else { + target = creep.room.controller.pos.findClosestByRange(FIND_STRUCTURES, { + filter: s => (s.structureType === STRUCTURE_CONTAINER || s.structureType === STRUCTURE_LINK || s.structureType === STRUCTURE_STORAGE) + && s.store[RESOURCE_ENERGY] > 0 + }) + } } if (target) { if (creep.withdraw(target, RESOURCE_ENERGY) === ERR_NOT_IN_RANGE) { @@ -53,13 +66,11 @@ module.exports = { } } - if (creep.pos.getRangeTo(creep.room.controller) > 3) { - creep.moveTo(creep.room.controller, {visualizePathStyle: {stroke: '#ffffff'}}) - return - } let actionResult = creep.upgradeController(creep.room.controller) if (actionResult === OK) { return + } else if (actionResult === ERR_NOT_IN_RANGE) { + creep.moveTo(creep.room.controller, {visualizePathStyle: {stroke: '#ffffff'}}) } return 'idle' diff --git a/default/spawn.js b/default/spawn.js index 381ad5e..cd56d53 100644 --- a/default/spawn.js +++ b/default/spawn.js @@ -29,6 +29,9 @@ module.exports = { for (let room of Object.values(Game.rooms)) { let spawns = room.find(FIND_MY_SPAWNS) room.memory.spawingRoom = spawns.length > 0 + if (!room.memory.spawnContainers) { + room.memory.spawnContainers = [] + } if (!room.memory.harvestingSpots) { room.memory.harvestingSpots = {} } @@ -51,6 +54,45 @@ module.exports = { ).map(el => el.structure.id) } + + if (Game.time % 10 === 0 && room.controller.my) { + room.memory.spawnContainers = [] + for (let spawn of spawns) { + let containers = spawn.pos.findInRange(FIND_STRUCTURES, 4, {filter: s => s.structureType === STRUCTURE_CONTAINER}) + if (containers.length > 0) { + containers.forEach(el => room.memory.spawnContainers.push(el.id)) + } + let storagesInLevel = { + 1: 0, + 2: 1, + 3: 2, + } + if (containers.length < storagesInLevel[room.controller.level] + && spawn.pos.findInRange(FIND_MY_CONSTRUCTION_SITES, 4, {filter: s => s.structureType === STRUCTURE_CONTAINER}).length === 0){ + let ring = 2 + let x = spawn.pos.x + let y = spawn.pos.y + let result = ERR_INVALID_TARGET + while (ring <= 4 && result === ERR_INVALID_TARGET) { + if (ring % 2 === 0 && (x === spawn.pos.x || y === spawn.pos.y)) { + result = room.createConstructionSite(x, y, STRUCTURE_CONTAINER) + } + x += 2 + if (x > spawn.pos.x + ring) { + x = spawn.pos.x - ring + y += 2 + } + if (y > spawn.pos.y + ring) { + ring += 2 + x = spawn.pos.x - ring + y = spawn.pos.y - ring + } + } + } + } + } + + if (!room.memory.sourcesData) { room.memory.sourcesData = {} } @@ -66,14 +108,25 @@ module.exports = { } } } - if (spawns.length > 0 && (Game.time + 5) % 100 === 0 && room.find(FIND_MY_CONSTRUCTION_SITES).length === 0) { + + if (spawns.length > 0 && (Game.time + 5) % 10 === 0 + && room.find( + FIND_MY_CONSTRUCTION_SITES, + {filter: s => s.structureType === STRUCTURE_EXTENSION}).length === 0 + ) { let spawn = spawns[0] let extensions = room.find(FIND_MY_STRUCTURES, {filter: s => s.structureType === STRUCTURE_EXTENSION}) if (CONTROLLER_STRUCTURES.extension[room.controller.level] > extensions.length) { let ring = 0 let x = spawn.pos.x let y = spawn.pos.y - while (ring < 10 && room.createConstructionSite(x, y, STRUCTURE_EXTENSION) === ERR_INVALID_TARGET) { + let result = ERR_INVALID_TARGET + while (ring < 10 && result === ERR_INVALID_TARGET) { + if (ring === 2 && y === spawn.pos.y) { + result = room.createConstructionSite(x, y, STRUCTURE_CONTAINER) + } else { + result = room.createConstructionSite(x, y, STRUCTURE_EXTENSION) + } x += 2 if (x > spawn.pos.x + ring) { x = spawn.pos.x - ring @@ -124,7 +177,11 @@ module.exports = { } } else if (roleName === 'harvester') { - for (let source of spawn.room.find(FIND_SOURCES)) { + for (let [sourceId, sourceData] of _.sortBy(Object.entries(spawn.room.memory.sourcesData), el => el[1].spawnDistance * -1)) { + let source = Game.getObjectById(sourceId) + if (!source) { + continue + } let spots = spawn.room.memory.harvestingSpots[source.id] let harvestingCapacity = 0 let sourceHarvesters = _.filter(roleCreeps, {memory: {source: source.id}})