main
Arne Schauf 8 months ago
commit a741cd8352
  1. 1
      .gitignore
  2. 46
      default/common.js
  3. 47
      default/globals.js
  4. 25
      default/link.js
  5. 104
      default/main.js
  6. 107
      default/role.builder.js
  7. 57
      default/role.harvester.js
  8. 5
      default/role.scout.js
  9. 160
      default/role.transporter.js
  10. 52
      default/role.upgrader.js
  11. 167
      default/spawn.js

1
.gitignore vendored

@ -0,0 +1 @@
.sync

@ -0,0 +1,46 @@
const consts = {
FINISHED: 1,
HARVESTING: 2,
CONTINUE_ACTIVITY: 3,
}
module.exports = {
consts,
harvestEnergy (creep) {
if (!creep.memory.harvestingEnergy && creep.store[RESOURCE_ENERGY] > 0) {
return consts.CONTINUE_ACTIVITY
}
creep.memory.harvestingEnergy = creep.store.getFreeCapacity() > 0
if (!creep.memory.harvestingEnergy) {
return consts.FINISHED
}
// if (creep.store[RESOURCE_ENERGY] === 0) {
// creep.say('🔄 fetch');
// }
let target
if (!target) {
target = creep.pos.findClosestByRange(FIND_STRUCTURES, {
filter: s => (s.structureType === STRUCTURE_CONTAINER || s.structureType === STRUCTURE_STORAGE)
&& s.store[RESOURCE_ENERGY] >= creep.store.getFreeCapacity(RESOURCE_ENERGY)
});
}
if(target) {
let result = creep.withdraw(target, RESOURCE_ENERGY)
if (result === ERR_NOT_IN_RANGE) {
creep.moveTo(target, {visualizePathStyle: {stroke: '#ffaa00'}});
}
else if (result === OK) {
return consts.FINISHED
}
}
else {
let target = creep.pos.findClosestByRange(FIND_MY_CREEPS, {
filter: creep => creep.memory.role === 'harvester' && creep.store[RESOURCE_ENERGY] > 0
});
if (target) {
creep.moveTo(target, {visualizePathStyle: {stroke: '#ffaa00'}});
}
}
return consts.HARVESTING
}
}

@ -0,0 +1,47 @@
const roleHarvester = require('./role.harvester')
const roleTransporter = require('./role.transporter')
const roleBuilder = require('./role.builder')
const roleUpgrader = require('./role.upgrader')
global.ROLES = {
harvester: {
prio: 3,
count: 3,
module: roleHarvester,
bodies: [
[WORK, WORK, CARRY, MOVE],
[WORK, WORK, WORK, WORK, WORK, WORK, CARRY, MOVE],
[WORK, WORK, WORK, WORK, WORK, WORK, CARRY, MOVE, MOVE],
[WORK, WORK, WORK, WORK, WORK, WORK, CARRY, MOVE, MOVE, MOVE],
[WORK, WORK, WORK, WORK, WORK, WORK, CARRY, CARRY, MOVE, MOVE, MOVE],
[WORK, WORK, WORK, WORK, WORK, WORK, CARRY, CARRY, MOVE, MOVE, MOVE, MOVE],
]
},
transporter: {
prio: 4,
count: 2,
module: roleTransporter,
bodies: [
[CARRY, CARRY, MOVE],
[CARRY, CARRY, MOVE, CARRY, CARRY, MOVE],
[CARRY, CARRY, MOVE, CARRY, CARRY, MOVE, CARRY, CARRY, MOVE],
[CARRY, CARRY, MOVE, CARRY, CARRY, MOVE, CARRY, CARRY, MOVE, CARRY, CARRY, MOVE],
]
},
builder: {
prio: 5,
count: 2,
maxExpands: 4,
module: roleBuilder,
baseBody: [WORK, CARRY, MOVE, MOVE],
expandBody: [WORK, CARRY, MOVE, MOVE],
},
upgrader: {
prio: 6,
count: 2,
maxExpands: 4,
module: roleUpgrader,
baseBody: [WORK, CARRY, MOVE],
expandBody: [WORK, WORK, MOVE],
},
}

@ -0,0 +1,25 @@
module.exports = {
tickInit () {
for (let room of Object.values(Game.rooms)) {
if (room.memory.controllerLink && !Game.getObjectById(room.memory.controllerLink)) {
delete room.memory.controllerLink
}
}
},
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)
if (targetLink.store.getFreeCapacity(RESOURCE_ENERGY) > 770) {
link.transferEnergy(targetLink)
}
}
}
}

@ -0,0 +1,104 @@
const roleHarvester = require('role.harvester')
const roleBuilder = require('role.builder')
const roleTransporter = require('role.transporter')
const roleUpgrader = require('role.upgrader')
const libLink = require('link')
const libSpawn = require('spawn')
require('globals')
module.exports.loop = function () {
// Cleanups
if (!Memory.repairers) {
Memory.repairers = {}
}
if (!Memory.refillers) {
Memory.refillers = {}
}
for (let name in Memory.creeps) {
if (!Game.creeps[name]) {
delete Memory.creeps[name];
}
}
libLink.tickInit()
libSpawn.tickInit()
for (let room of Object.values(Game.rooms)) {
// tickInit
for (let role of Object.values(ROLES)) {
role.idling = 0
if (role.module.tickInit) {
role.module.tickInit(room)
}
}
for (let role of Object.values(ROLES)) {
if (role.module.cleanup) {
role.module.cleanup()
}
}
for (let [id, creep] of Object.entries(Memory.refillers)) {
let target = Game.getObjectById(id)
if (!target || target.store.getFreeCapacity(RESOURCE_ENERGY) === 0 || !Game.creeps[creep]) {
delete Memory.refillers[id]
}
}
let spawn = Game.spawns['Spawn1']
// Run modules
for (let link of spawn.room.find(FIND_STRUCTURES, {filter: s => s.structureType === STRUCTURE_LINK})) {
libLink.tick(link)
}
for (let creep of Object.values(Game.creeps)) {
if (creep.store.getFreeCapacity(RESOURCE_ENERGY) > 0) {
for (let target of creep.pos.findInRange(FIND_TOMBSTONES, 1, {filter: t => t.store[RESOURCE_ENERGY] > 0})) {
creep.withdraw(target, RESOURCE_ENERGY)
}
for (let target of creep.pos.findInRange(FIND_RUINS, 1, {filter: t => t.store[RESOURCE_ENERGY] > 0})) {
creep.withdraw(target, RESOURCE_ENERGY)
}
}
if (!creep.memory.role) {
creep.memory.role = 'harvester'
}
if (ROLES[creep.memory.role].module.tick(creep) === 'idle') {
ROLES[creep.memory.role].idling++
}
}
libSpawn.tick(spawn)
let towers = spawn.room.find(FIND_STRUCTURES, {filter: structure => structure.structureType === STRUCTURE_TOWER})
for (let tower of towers) {
// var closestDamagedStructure = tower.pos.findClosestByRange(FIND_STRUCTURES, {
// filter: (structure) => structure.hits < structure.hitsMax
// });
// if(closestDamagedStructure) {
// tower.repair(closestDamagedStructure);
// }
let closestHostile = tower.pos.findClosestByRange(FIND_HOSTILE_CREEPS);
if (closestHostile) {
tower.attack(closestHostile);
}
}
// for (let [role, values] of Object.entries(ROLES)) {
// if (values.idling > 0) {
// console.log(`${values.idling} ${role}s idling`)
// }
// }
spawn.room.visual.text(
`${Game.cpu.getUsed().toFixed(1)} / ${Game.cpu.tickLimit} (${Game.cpu.bucket})`,
1, 1,
{align: 'left', opacity: 0.8});
}
if (Game.cpu.generatePixel && Game.cpu.bucket === 10000) {
Game.cpu.generatePixel()
}
}

@ -0,0 +1,107 @@
const common = require('common')
let idling = 0
let maxWallHits = 0
module.exports = {
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 (room) {
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] > 0
})
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) {
if (creep.build(target) === ERR_NOT_IN_RANGE) {
creep.moveTo(target, {visualizePathStyle: {stroke: '#729075'}});
}
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'
}
}

@ -0,0 +1,57 @@
let common = require('common')
let idling = 0
module.exports = {
idling,
tick (creep) {
let dropped = creep.pos.findInRange(FIND_DROPPED_RESOURCES, 1);
if (dropped.length > 0) {
creep.pickup(dropped[0])
}
let targetCreeps = creep.pos.findInRange(FIND_MY_CREEPS, 1, {
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)
}
else {
let targets = creep.pos.findInRange(FIND_STRUCTURES, 1, {
filter: (structure) => structure.store
&& structure.store.getFreeCapacity(RESOURCE_ENERGY) > 0
&& structure.structureType === STRUCTURE_EXTENSION
});
if (targets.length === 0) {
targets = creep.pos.findInRange(FIND_STRUCTURES, 1, {
filter: (structure) => structure.store && structure.store.getFreeCapacity(RESOURCE_ENERGY) > 0
});
}
if (targets.length > 0) {
creep.transfer(_.min(targets, el => el.store[RESOURCE_ENERGY]), RESOURCE_ENERGY)
} else {
let targetCreeps = creep.pos.findInRange(FIND_MY_CREEPS, 1, {
filter: tc => tc.store.getFreeCapacity(RESOURCE_ENERGY)
});
if (targetCreeps.length > 0) {
let tc = targetCreeps[0]
creep.transfer(tc, RESOURCE_ENERGY, tc.memory.role === 'harvester' ? tc.store.getFreeCapacity(RESOURCE_ENERGY) * 0.5 : creep.store[RESOURCE_ENERGY])
} else {
let buildTargets = creep.pos.findInRange(FIND_MY_CONSTRUCTION_SITES, 1);
if (buildTargets.length > 0 && creep.build(buildTargets[0]) === OK) {
return
}
}
}
}
let target = Game.getObjectById(creep.memory.source)
let actionResult = creep.harvest(target)
if (actionResult === ERR_NOT_IN_RANGE) {
creep.moveTo(target, {visualizePathStyle: {stroke: '#ffaa00'}});
}
if (actionResult !== OK) {
return 'idle'
}
}
};

@ -0,0 +1,5 @@
module.exports = {
tick (creep) {
}
}

@ -0,0 +1,160 @@
const common = require('common')
module.exports = {
tick (creep) {
if (creep.store.getFreeCapacity(RESOURCE_ENERGY) === 0) {
creep.memory.loading = false
}
else if (creep.store[RESOURCE_ENERGY] === 0) {
creep.memory.loading = true
}
if (creep.store[RESOURCE_ENERGY] >= 50) {
let quickfillTargets = creep.pos.findInRange(FIND_STRUCTURES, 2, {
filter: s => {
return s.store
&& s.structureType !== STRUCTURE_CONTAINER
&& s.structureType !== STRUCTURE_STORAGE
&& s.store.getFreeCapacity(RESOURCE_ENERGY) > 0
}
})
if (quickfillTargets.length > 0) {
delete creep.memory.idling
let quickfillTarget = creep.pos.findClosestByRange(quickfillTargets)
if (creep.transfer(quickfillTarget, RESOURCE_ENERGY) === ERR_NOT_IN_RANGE) {
creep.moveTo(quickfillTarget, {visualizePathStyle: {stroke: '#729075'}});
return
}
}
}
if (creep.store.getFreeCapacity(RESOURCE_ENERGY) > 0) {
let dropped = creep.pos.findInRange(FIND_DROPPED_RESOURCES, 1);
if (dropped.length > 0) {
creep.pickup(dropped[0])
}
let quickloadTargets = creep.pos.findInRange(FIND_STRUCTURES, 2, {
filter: s => {
return s.structureType === STRUCTURE_CONTAINER
&& s.store[RESOURCE_ENERGY] > creep.store.getFreeCapacity(RESOURCE_ENERGY)
}
})
if (quickloadTargets.length > 0) {
delete creep.memory.idling
let quickloadTarget = creep.pos.findClosestByPath(quickloadTargets)
if (creep.withdraw(quickloadTarget, RESOURCE_ENERGY) === ERR_NOT_IN_RANGE) {
creep.moveTo(quickloadTarget, {visualizePathStyle: {stroke: '#729075'}});
return
}
}
}
if (creep.memory.loading) {
let target = creep.pos.findClosestByPath(FIND_TOMBSTONES, {
filter: (structure) => structure.store[RESOURCE_ENERGY] > 0
})
if (!target) {
target = creep.pos.findClosestByPath(FIND_RUINS, {
filter: (structure) => structure.store[RESOURCE_ENERGY] > 0
})
}
if (!target) {
target = creep.pos.findClosestByPath(FIND_STRUCTURES, {
filter: s => {
return s.structureType === STRUCTURE_CONTAINER
&& s.store[RESOURCE_ENERGY] > 100
}
})
}
if (!target) {
target = creep.pos.findClosestByPath(FIND_STRUCTURES, {
filter: s => {
return s.structureType === STRUCTURE_STORAGE
&& s.store[RESOURCE_ENERGY] > 100
}
})
}
if (target) {
if (creep.withdraw(target, RESOURCE_ENERGY) === ERR_NOT_IN_RANGE) {
creep.moveTo(target, {visualizePathStyle: {stroke: '#f7e180'}})
}
delete creep.memory.idling
return
}
if (!target) {
target = creep.pos.findClosestByPath(FIND_MY_CREEPS, {
filter: c => {
return c.memory.role === 'harvester' && c.store[RESOURCE_ENERGY] > 0
}
})
if (target) {
if (!creep.pos.inRangeTo(target, 1)) {
creep.moveTo(target, {visualizePathStyle: {stroke: '#f7e180'}})
}
delete creep.memory.idling
return
}
}
}
else {
let target = _.findKey(Memory.refillers, el => el === creep.name)
if (target) {
target = Game.getObjectById(target)
}
if (!target) {
target = creep.pos.findClosestByPath(FIND_STRUCTURES, {
filter: s => (
s.structureType === STRUCTURE_EXTENSION
|| s.structureType === STRUCTURE_SPAWN
|| s.structureType === STRUCTURE_TOWER
)
&& 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)
}
})
}
if (!target) {
target = creep.pos.findClosestByPath(FIND_STRUCTURES, {
filter: s => {
return s.structureType === STRUCTURE_STORAGE
&& s.store.getFreeCapacity(RESOURCE_ENERGY) > 0
}
})
}
if (target) {
if (target.store.getCapacity(RESOURCE_ENERGY) <= creep.store.getCapacity(RESOURCE_ENERGY)) {
Memory.refillers[target.id] = creep.name
}
if (creep.transfer(target, RESOURCE_ENERGY) === ERR_NOT_IN_RANGE) {
creep.moveTo(target, {visualizePathStyle: {stroke: '#00ff0f'}});
}
delete creep.memory.idling
return
}
}
if (!creep.memory.idling) {
creep.memory.idling = 0
}
if (creep.memory.idling > 3) {
if (creep.store[RESOURCE_ENERGY] > 10) {
creep.memory.loading = false
}
else if (creep.store.getFreeCapacity(RESOURCE_ENERGY) > 10) {
creep.memory.loading = true
}
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.memory.idling++
return 'idle'
}
};

@ -0,0 +1,52 @@
const common = require('common')
let idling = 0
module.exports = {
idling,
tick (creep) {
if (creep.store.getFreeCapacity(RESOURCE_ENERGY) > 0) {
let dropped = creep.pos.findInRange(FIND_DROPPED_RESOURCES, 1);
if (dropped.length > 0) {
creep.pickup(dropped[0])
}
let target
let targets = creep.pos.findInRange(FIND_TOMBSTONES, 1, {
filter: t => t.store[RESOURCE_ENERGY] > 0
})
if (targets.length) {
target = targets[0]
}
if (!target) {
targets = creep.pos.findInRange(FIND_STRUCTURES, 1, {
filter: s => s.store && s.store[RESOURCE_ENERGY] > 0
})
if (targets.length) {
target = targets[0]
}
}
if (!target) {
target = creep.room.controller.pos.findClosestByRange(FIND_STRUCTURES, {
filter: s => s.store && s.store.getCapacity(RESOURCE_ENERGY) > 0
})
}
if (target) {
if (creep.withdraw(target, RESOURCE_ENERGY) === ERR_NOT_IN_RANGE) {
creep.moveTo(target)
return
}
}
}
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
}
return 'idle'
}
};

@ -0,0 +1,167 @@
require('globals')
const EMERGENCY_MODE_TIMEOUT = 100
function getHarvestingSpots (source) {
if (source.room.memory.harvestingSpots[source.id]) {
return source.room.memory.harvestingSpots[source.id]
}
let spots = []
let terrain = source.room.getTerrain()
for (let x = source.pos.x; x <= source.pos.x + 1; x++) {
for (let y = source.pos.y; y <= source.pos.y + 1; y++) {
if (terrain.get(x, y) !== TERRAIN_MASK_WALL) {
spots.push([x, y])
}
}
}
source.room.memory.harvestingSpots[source.id] = spots
return spots
}
function getBodyCost(body) {
let cost = 0
for (let part of body) {
cost = cost + BODYPART_COST[part]
}
return cost
}
module.exports = {
tickInit () {
for (let room of Object.values(Game.rooms)) {
if (!room.memory.harvestingSpots) {
room.memory.harvestingSpots = {}
}
if (!room.memory.spawnIdle) {
room.memory.spawnIdle = 0
}
if (!room.memory.energyIncreasedAt) {
room.memory.energyIncreasedAt = Game.time
}
if (!room.memory.lastEnergy) {
room.memory.lastEnergy = 0
}
if (!room.memory.sourcesData) {
room.memory.sourcesData = {}
}
for (let source of room.find(FIND_SOURCES)) {
if (!room.memory.sourcesData[source.id]) {
room.memory.sourcesData[source.id] = {spawnDistance: 0}
let spawn = source.pos.findClosestByPath(FIND_MY_SPAWNS)
if (spawn) {
room.memory.sourcesData[source.id].spawnDistance = source.pos.findPathTo(spawn.pos, {ignoreCreeps: true}).length
}
}
}
}
},
tick (spawn) {
let minRoleCount
if (spawn.spawning) {
spawn.room.memory.spawnIdle = 0
let spawningCreep = Game.creeps[spawn.spawning.name];
spawn.room.visual.text(
'🛠' + spawningCreep.memory.role,
spawn.pos.x + 1,
spawn.pos.y,
{align: 'left', opacity: 0.8});
}
else {
let newCreep, prio
for (let [roleName, role] of Object.entries(ROLES)) {
let roleCreeps = _.filter(Game.creeps, (creep) => creep.memory.role === roleName);
if (minRoleCount === undefined || minRoleCount > roleCreeps.length) {
minRoleCount = roleCreeps.length
}
if (roleCreeps.length > 0 && spawn.room.memory.emergency && spawn.room.energyAvailable < spawn.room.energyCapacityAvailable) {
continue
}
let newName = roleName + Game.time;
let body = []
let memory = {role: roleName}
if (roleName === 'harvester') {
for (let source of spawn.room.find(FIND_SOURCES)) {
let spots = getHarvestingSpots(source)
let harvestingCapacity = 0
let sourceHarvesters = _.filter(Game.creeps, {memory: {role: 'harvester', source: source.id}})
if (sourceHarvesters.length >= spots.length) {
continue
}
for (let harvester of sourceHarvesters) {
if (harvester.ticksToLive > harvester.body.length * 3 + source.room.memory.sourcesData[source.id].spawnDistance) {
harvestingCapacity += harvester.getActiveBodyparts(WORK) * 2 * 300
}
}
if (harvestingCapacity <= source.energyCapacity) {
for (let b of ROLES.harvester.bodies) {
if (getBodyCost(b) <= (spawn.room.memory.emergency ? spawn.room.energyAvailable : spawn.room.energyCapacityAvailable)) {
body = b
memory.source = source.id
} else {
break
}
}
}
}
}
else if (roleCreeps.length < role.count && role.idling === 0) {
if (Array.isArray(role.bodies)) {
for (let b of role.bodies) {
if (getBodyCost(b) <= (spawn.room.memory.emergency ? spawn.room.energyAvailable : spawn.room.energyCapacityAvailable)) {
body = b
} else {
break
}
}
} else {
body = role.baseBody
while (getBodyCost(body) + getBodyCost(role.expandBody) <= (spawn.room.memory.emergency ? spawn.room.energyAvailable : spawn.room.energyCapacityAvailable)) {
body = body.concat(role.expandBody)
}
}
}
if (body.length && (!prio || role.prio * (roleCreeps.length + 1) < prio)) {
newCreep = [body, newName, {memory}]
prio = role.prio * (roleCreeps.length + 1)
}
}
if (newCreep) {
spawn.spawnCreep(...newCreep)
spawn.room.memory.spawnIdle++
spawn.room.visual.text(
`Next: ${newCreep[1]}`,
spawn.pos.x + 1,
spawn.pos.y,
{align: 'left', opacity: 0.8, size: 0.3});
}
if (spawn.room.memory.lastEnergy !== spawn.room.energyAvailable) {
spawn.room.memory.energyIncreasedAt = Game.time
spawn.room.memory.lastEnergy = spawn.room.energyAvailable
}
spawn.room.memory.emergency = false
if (minRoleCount === 0) {
let timeToEmergency = Math.max(
EMERGENCY_MODE_TIMEOUT - spawn.room.memory.spawnIdle,
EMERGENCY_MODE_TIMEOUT - Game.time - spawn.room.memory.energyIncreasedAt
)
if (timeToEmergency <= 0) {
spawn.room.memory.emergency = true
spawn.room.visual.text(
`Prio${prio} emergency spawn ${newCreep[1]} (${newCreep[0]})`,
spawn.pos.x + 1,
spawn.pos.y,
{align: 'left', opacity: 0.8});
} else if (timeToEmergency <= 50) {
spawn.room.visual.text(
'Emergency in ' + (EMERGENCY_MODE_TIMEOUT - spawn.room.memory.spawnIdle),
spawn.pos.x + 1,
spawn.pos.y,
{align: 'left', opacity: 0.8});
}
}
}
},
}
Loading…
Cancel
Save