main
Arne Schauf 8 months ago
parent a741cd8352
commit 493a1e0bad
  1. 85
      default/globals.js
  2. 49
      default/main.js
  3. 85
      default/role.attacker.js
  4. 13
      default/role.builder.js
  5. 58
      default/role.filler.js
  6. 13
      default/role.harvester.js
  7. 101
      default/role.hauler.js
  8. 88
      default/role.healer.js
  9. 90
      default/role.rangedAttacker.js
  10. 54
      default/role.remoteHarvester.js
  11. 31
      default/role.reserver.js
  12. 27
      default/role.scout.js
  13. 14
      default/role.transporter.js
  14. 7
      default/role.upgrader.js
  15. 107
      default/spawn.js

@ -1,47 +1,50 @@
const roleHarvester = require('./role.harvester')
const roleRemoteHarvester = require('./role.remoteHarvester')
const roleTransporter = require('./role.transporter')
const roleBuilder = require('./role.builder')
const roleUpgrader = require('./role.upgrader')
const roleScout = require('./role.scout')
const roleAttacker = require('./role.attacker')
const roleRangedAttacker = require('./role.rangedAttacker')
const roleHauler = require('./role.hauler')
const roleHealer = require('./role.healer')
const roleFiller = require('./role.filler')
const roleReserver = require('./role.reserver')
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],
},
global.roleModules = [
roleHarvester,
roleRemoteHarvester,
roleBuilder,
roleTransporter,
roleUpgrader,
roleScout,
roleRangedAttacker,
roleHauler,
roleAttacker,
roleHealer,
roleFiller,
roleReserver,
]
global.ROLES = {}
for (let mod of roleModules) {
ROLES[mod.name] = mod
}
global.creepIsAttacker = creep => creep.getActiveBodyparts(ATTACK) + creep.getActiveBodyparts(RANGED_ATTACK) > 0
global.activeRemotes = ['E8S4', 'E8S5', 'E9S5', 'E8S3']
global.ALREADY_IN_ROOM = 'alreadyInRoom'
global.MOVING = 'moving'
global.moveToRoom = function (creep, targetRoom) {
if (creep.pos.roomName === targetRoom) {
return ALREADY_IN_ROOM
}
const exitDir = Game.map.findExit(creep.room, targetRoom);
const exit = creep.pos.findClosestByRange(exitDir);
creep.moveTo(exit);
creep.say(targetRoom)
return MOVING
}

@ -1,7 +1,3 @@
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')
@ -24,18 +20,17 @@ module.exports.loop = function () {
libLink.tickInit()
libSpawn.tickInit()
for (let room of Object.values(Game.rooms)) {
// tickInit
for (let role of Object.values(ROLES)) {
for (let role of roleModules) {
role.idling = 0
if (role.module.tickInit) {
role.module.tickInit(room)
if (role.tickInit) {
role.tickInit()
}
}
for (let role of Object.values(ROLES)) {
if (role.module.cleanup) {
role.module.cleanup()
for (let role of roleModules) {
if (role.cleanup) {
role.cleanup()
}
}
@ -64,7 +59,7 @@ module.exports.loop = function () {
if (!creep.memory.role) {
creep.memory.role = 'harvester'
}
if (ROLES[creep.memory.role].module.tick(creep) === 'idle') {
if (ROLES[creep.memory.role].tick(creep) === 'idle') {
ROLES[creep.memory.role].idling++
}
}
@ -96,9 +91,37 @@ module.exports.loop = function () {
`${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()
}
/*
PathFinder.search(
new RoomPosition(11, 7, 'E8S4'),
new RoomPosition(8, 11, 'E9S4'),
{roomCallback: 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);
}
});
return costs;
}}
).path.forEach(el => new RoomVisual(el.roomName).circle(el))
*/
}

@ -0,0 +1,85 @@
module.exports = {
name: 'attacker',
prio: 10,
tickInit () {
for (let room of Object.values(Game.rooms)) {
if (!room.memory.attacker) {
room.memory.attacker = {}
}
if (room.find(FIND_STRUCTURES, {filter: s => s.structureType === STRUCTURE_TOWER}).length > 0) {
room.memory.attacker.targetCount = 0
continue
}
room.memory.attacker.targetCount = Math.min(room.find(FIND_HOSTILE_CREEPS).length, 2)
}
},
nextSpawn (spawn, roleCreeps) {
for (let room of Object.values(Game.rooms)) {
if (_.filter(roleCreeps, {memory: {room: room.name}}).length < room.memory.attacker.targetCount) {
return [
[ATTACK, MOVE, ATTACK, MOVE, ATTACK, MOVE, ATTACK, MOVE, ATTACK, MOVE, ATTACK, MOVE],
{room: room.name}
]
}
}
},
tick (creep) {
let room = Game.rooms[creep.memory.room]
let targetRoomName = creep.memory.room
if (targetRoomName !== 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)
) {
if (creep.ticksToLive < 1200) {
creep.moveTo(creep.pos.findClosestByPath(FIND_MY_SPAWNS))
}
else {
creep.moveTo(creep.pos.findClosestByPath(FIND_FLAGS, {
filter: el => el.name.startsWith('gather'),
visualizePathStyle: {stroke: '#0017ff'}
}))
}
return
}
if (!room || targetRoomName !== creep.pos.roomName) {
creep.moveTo(new RoomPosition(25, 25, creep.memory.room))
return
}
if (creep.pos.x <= 1) {
creep.move(RIGHT)
} else if (creep.pos.y <= 1) {
creep.move(BOTTOM)
} else if (creep.pos.x >= 48) {
creep.move(LEFT)
} else if (creep.pos.y >= 48) {
creep.move(TOP)
}
let targetCreep
if (creep.memory.lastTarget) {
targetCreep = Game.getObjectById(creep.memory.lastTarget)
if (targetCreep && targetCreep.pos.roomName !== targetRoomName) {
delete creep.memory.lastTarget
targetCreep = undefined
}
}
if (targetCreep && !creepIsAttacker(targetCreep)) {
let closeAttackers = creep.pos.findInRange(FIND_HOSTILE_CREEPS, 3, {filter: c => c.getActiveBodyparts(ATTACK) > 0 && c.pos.roomName === targetRoomName})
if (closeAttackers.length > 0) {
targetCreep = closeAttackers[0]
}
}
if (!targetCreep) {
targetCreep = creep.pos.findClosestByRange(FIND_HOSTILE_CREEPS, {filter: c => (creepIsAttacker(c) || c.getActiveBodyparts(CARRY) >= 2) && c.pos.roomName === targetRoomName})
}
if (targetCreep) {
creep.memory.lastTarget = targetCreep.id
if (creep.attack(targetCreep) === ERR_NOT_IN_RANGE) {
creep.moveTo(targetCreep.pos)
}
}
},
}

@ -3,6 +3,12 @@ let idling = 0
let maxWallHits = 0
module.exports = {
name: 'builder',
prio: 5,
count: 1,
maxExpands: 4,
baseBody: [WORK, CARRY, MOVE, MOVE],
expandBody: [WORK, CARRY, MOVE, MOVE],
idling,
maxWallHits,
cleanup () {
@ -18,7 +24,11 @@ module.exports = {
}
}
},
tickInit (room) {
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)
})
@ -28,6 +38,7 @@ module.exports = {
wallAvgHits = wallAvgHits / walls.length
}
maxWallHits = Math.min(wallAvgHits, 200000)
}
},
tick (creep) {
let harvest = common.harvestEnergy(creep)

@ -0,0 +1,58 @@
const common = require('common')
module.exports = {
name: 'filler',
prio: 4,
count: 2,
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],
],
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.memory.loading) {
let target = creep.pos.findClosestByPath(FIND_STRUCTURES, {
filter: s => {
return (s.structureType === STRUCTURE_STORAGE || s.structureType === STRUCTURE_CONTAINER)
&& s.store[RESOURCE_ENERGY] > Math.min(creep.store.getFreeCapacity(RESOURCE_ENERGY), 100)
}
})
if (target) {
if (creep.withdraw(target, RESOURCE_ENERGY) === ERR_NOT_IN_RANGE) {
creep.moveTo(target, {visualizePathStyle: {stroke: '#f7e180'}})
}
} else {
creep.moveTo(creep.pos.findClosestByRange(FIND_FLAGS, {filter: flag => flag.name.startsWith('idle')}), {visualizePathStyle: {stroke: '#ff0000'}});
return 'idle'
}
}
else {
let target = creep.pos.findClosestByPath(FIND_STRUCTURES, {
filter: s => (
s.structureType === STRUCTURE_EXTENSION
|| s.structureType === STRUCTURE_SPAWN
)
&& 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})
}
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'}});
return 'idle'
}
}
}
};

@ -1,8 +1,17 @@
let common = require('common')
let idling = 0
module.exports = {
idling,
name: 'harvester',
prio: 3,
count: 3,
bodies: [
[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],
[WORK, WORK, WORK, WORK, WORK, CARRY, CARRY, MOVE, MOVE, MOVE],
[WORK, WORK, WORK, WORK, WORK, CARRY, CARRY, MOVE, MOVE, MOVE, MOVE],
],
tick (creep) {
let dropped = creep.pos.findInRange(FIND_DROPPED_RESOURCES, 1);
if (dropped.length > 0) {

@ -0,0 +1,101 @@
module.exports = {
name: 'hauler',
prio: 11,
tickInit () {
for (let room of Object.values(Game.rooms)) {
if (!room.memory.hauler) {
room.memory.hauler = {}
}
let harvesters = room.find(FIND_MY_CREEPS, {filter: c => c.memory.role === 'remoteHarvester' && c.memory.room === room.name})
let filledContainers = room.find(FIND_STRUCTURES, {filter: s => s.structureType === STRUCTURE_CONTAINER && s.store[RESOURCE_ENERGY] > 0})
if (room.find(FIND_STRUCTURES, {filter: s => s.structureType === STRUCTURE_TOWER || s.structureType === STRUCTURE_SPAWN}).length > 0
|| (filledContainers.length === 0 && harvesters.length === 0)
|| room.find(FIND_HOSTILE_CREEPS, {filter: c => creepIsAttacker(c)}).length > 0
) {
room.memory.hauler.targetCount = 0
continue
}
room.memory.hauler.targetCount = Math.max(filledContainers.length, harvesters.length) * 6
}
},
nextSpawn (spawn, roleCreeps) {
for (let room of Object.values(Game.rooms)) {
if (_.filter(roleCreeps, {memory: {room: room.name}}).length < room.memory.hauler.targetCount) {
return [
[CARRY, MOVE, CARRY, MOVE, CARRY, MOVE, CARRY, MOVE],
{room: room.name}
]
}
}
},
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 (moveToRoom(creep, creep.memory.room) === MOVING) {
return
}
let dropped = creep.pos.findInRange(FIND_DROPPED_RESOURCES, 1);
if (dropped.length > 0) {
creep.pickup(dropped[0])
}
dropped = creep.pos.findClosestByPath(FIND_DROPPED_RESOURCES, {filter: r => r.amount >= 100});
if (dropped) {
if (creep.pickup(dropped) === ERR_NOT_IN_RANGE) {
creep.moveTo(dropped)
return
}
}
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
}
})
}
if (target) {
if (creep.withdraw(target, RESOURCE_ENERGY) === ERR_NOT_IN_RANGE) {
creep.moveTo(target, {visualizePathStyle: {stroke: '#f7e180'}})
}
} else {
if (!target) {
target = creep.pos.findClosestByRange(FIND_MY_CREEPS, {
filter: s => {
return s.store[RESOURCE_ENERGY] >= s.store.getCapacity(RESOURCE_ENERGY) * 0.5
&& s.memory.role === 'remoteHarvester'
}
})
}
if (target) {
if (creep.pos.getRangeTo(target) > 1) {
creep.moveTo(target, {visualizePathStyle: {stroke: '#f7e180'}})
}
}
}
} else if (creep.store[RESOURCE_ENERGY] > 0) {
let storage = Game.rooms[creep.memory.colony].storage
if (creep.transfer(storage, RESOURCE_ENERGY) === ERR_NOT_IN_RANGE) {
creep.moveTo(storage)
}
} 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'}});
return 'idle'
}
},
}

@ -0,0 +1,88 @@
module.exports = {
name: 'healer',
prio: 10,
tickInit () {
for (let room of Object.values(Game.rooms)) {
if (!room.memory.healer) {
room.memory.healer = {}
}
if (room.find(FIND_STRUCTURES, {filter: s => s.structureType === STRUCTURE_TOWER}).length > 0) {
room.memory.healer.targetCount = 0
continue
}
room.memory.healer.targetCount = Math.min(room.find(FIND_HOSTILE_CREEPS).length, 1)
}
},
nextSpawn (spawn, roleCreeps) {
for (let room of Object.values(Game.rooms)) {
if (_.filter(roleCreeps, {memory: {room: room.name}}).length < room.memory.healer.targetCount) {
return [
[MOVE, MOVE, MOVE, MOVE, HEAL, HEAL, HEAL, HEAL],
{room: room.name}
]
}
}
},
tick (creep) {
let room = Game.rooms[creep.memory.room]
let targetRoomName = creep.memory.room
if (creep.memory.room !== 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)
) {
creep.moveTo(creep.pos.findClosestByPath(FIND_FLAGS, {filter: el => el.name.startsWith('gather'), visualizePathStyle: {stroke: '#0017ff'}}))
return
}
if (!room || creep.memory.room !== creep.pos.roomName) {
creep.moveTo(new RoomPosition(25, 25, creep.memory.room))
return
}
if (creep.pos.x <= 2) {
creep.move(RIGHT)
} else if (creep.pos.y <= 2) {
creep.move(BOTTOM)
} else if (creep.pos.x >= 47) {
creep.move(LEFT)
} else if (creep.pos.y >= 47) {
creep.move(TOP)
}
let targetCreep
if (creep.memory.lastTarget) {
targetCreep = Game.getObjectById(creep.memory.lastTarget)
}
let closeAttackers = creep.pos.findInRange(FIND_HOSTILE_CREEPS, 4, {filter: c => c.getActiveBodyparts(ATTACK) > 0 && c.pos.roomName === targetRoomName})
if (closeAttackers.length > 0) {
creep.moveByPath(PathFinder.search(creep.pos, closeAttackers.map(el => {return {pos: el.pos, range: 3}}), {flee: true, maxRooms: 1}).path)
}
if (creep.hits < creep.hitsMax) {
creep.heal(creep)
return
}
let healTargets = creep.pos.findInRange(FIND_MY_CREEPS, 1, {filter: c => c.hits < c.hitsMax && c.pos.roomName === targetRoomName})
if (healTargets.length > 0) {
creep.heal(healTargets[0])
return
}
let rangedHealTarget = creep.pos.findClosestByRange(FIND_MY_CREEPS, {filter: c => c.hits < c.hitsMax && c.pos.roomName === targetRoomName})
if (rangedHealTarget) {
creep.rangedHeal(rangedHealTarget)
creep.moveTo(rangedHealTarget, {visualizePathStyle: {stroke: '#00ff0f'}})
return
}
let possibleTarget = creep.pos.findClosestByPath(FIND_MY_CREEPS, {filter: c => creepIsAttacker(c) && c.pos.roomName === targetRoomName})
let range = creep.pos.getRangeTo(possibleTarget)
if (range === 1) {
creep.moveByPath(PathFinder.search(creep.pos, {pos: possibleTarget.pos, range: 2}, {flee: true, maxRooms: 1}).path)
}
else if (range > 3) {
creep.moveTo(possibleTarget, {visualizePathStyle: {stroke: '#00ff0f'}})
}
},
}

@ -0,0 +1,90 @@
module.exports = {
name: 'rangedAttacker',
prio: 10,
tickInit () {
for (let room of Object.values(Game.rooms)) {
if (!room.memory.rangedAttacker) {
room.memory.rangedAttacker = {}
}
if (room.find(FIND_STRUCTURES, {filter: s => s.structureType === STRUCTURE_TOWER}).length > 0) {
room.memory.rangedAttacker.targetCount = 0
continue
}
room.memory.rangedAttacker.targetCount = Math.min(room.find(FIND_HOSTILE_CREEPS).length, 2)
}
},
nextSpawn (spawn, roleCreeps) {
for (let [roomName, roomMemory] of Object.entries(Memory.rooms)) {
if (_.filter(roleCreeps, {memory: {room: roomName}}).length < roomMemory.rangedAttacker.targetCount) {
return [
[RANGED_ATTACK, MOVE, RANGED_ATTACK, MOVE, RANGED_ATTACK, MOVE, RANGED_ATTACK, MOVE, RANGED_ATTACK, MOVE],
{room: roomName}
]
}
}
},
tick (creep) {
let room = Game.rooms[creep.memory.room]
let targetRoomName = creep.memory.room
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)
) {
if (creep.ticksToLive < 1200) {
creep.moveTo(creep.pos.findClosestByPath(FIND_MY_SPAWNS))
} else {
creep.moveTo(creep.pos.findClosestByPath(FIND_FLAGS, {
filter: el => el.name.startsWith('gather'),
visualizePathStyle: {stroke: '#0017ff'}
}))
}
return
}
if (!room || targetRoomName !== creep.pos.roomName) {
creep.moveTo(new RoomPosition(25, 25, creep.memory.room))
return
}
if (creep.pos.x <= 2) {
creep.move(RIGHT)
} else if (creep.pos.y <= 2) {
creep.move(BOTTOM)
} else if (creep.pos.x >= 47) {
creep.move(LEFT)
} else if (creep.pos.y >= 47) {
creep.move(TOP)
}
let targetCreep
if (creep.memory.lastTarget) {
targetCreep = Game.getObjectById(creep.memory.lastTarget)
}
let closeAttackers = creep.pos.findInRange(FIND_HOSTILE_CREEPS, 3, {filter: c => creepIsAttacker(c)})
if (closeAttackers.length > 0) {
creep.moveByPath(PathFinder.search(creep.pos, closeAttackers.map(el => {return {pos: el.pos, range: 2}}), {flee: true, maxRooms: 1}).path)
targetCreep = closeAttackers[0]
}
if (!targetCreep) {
targetCreep = creep.pos.findClosestByRange(FIND_HOSTILE_CREEPS, {filter: c => creepIsAttacker(c) || c.getActiveBodyparts(CARRY) >= 2})
}
if (targetCreep) {
let targetIsAttacker = creepIsAttacker(targetCreep)
creep.memory.lastTarget = targetCreep.id
let range = creep.pos.getRangeTo(targetCreep.pos)
if (range <= 3) {
creep.rangedAttack(targetCreep)
}
else {
let driveByTargets = creep.pos.findInRange(FIND_HOSTILE_CREEPS, 3, {filter: c => creepIsAttacker(c) || c.getActiveBodyparts(CARRY) >= 2})
if (driveByTargets.length > 0) {
creep.rangedAttack(driveByTargets[0])
}
}
let distanceToKeep = targetIsAttacker ? 3 : 2
creep.moveByPath(PathFinder.search(creep.pos, [{pos: targetCreep.pos, range: distanceToKeep}], {maxRooms: 1, flee: range < distanceToKeep}).path)
}
},
}

@ -0,0 +1,54 @@
let common = require('common')
module.exports = {
name: 'remoteHarvester',
prio: 10,
bodies: [
[WORK, WORK, WORK, CARRY, MOVE, MOVE, MOVE, MOVE],
[WORK, WORK, WORK, WORK, WORK, WORK, CARRY, MOVE, MOVE, MOVE, MOVE, MOVE, MOVE, MOVE],
[WORK, WORK, WORK, WORK, WORK, WORK, CARRY, CARRY, MOVE, MOVE, MOVE, MOVE, MOVE, MOVE, MOVE, MOVE],
],
tick (creep) {
let dropped = creep.pos.findInRange(FIND_DROPPED_RESOURCES, 1);
if (dropped.length > 0) {
creep.pickup(dropped[0])
}
let repairTargets = creep.pos.findInRange(
FIND_STRUCTURES,
3,
{filter: s => s.structureType === STRUCTURE_CONTAINER && s.hits + creep.getActiveBodyparts(WORK) * 100 <= s.hitsMax});
if (repairTargets.length > 0) {
if (creep.store[RESOURCE_ENERGY] >= creep.getActiveBodyparts(WORK) * 10 && creep.repair(repairTargets[0]) === OK) {
return
}
} else {
let targetCreeps = creep.pos.findInRange(FIND_MY_CREEPS, 1, {
filter: tc => tc.store.getFreeCapacity(RESOURCE_ENERGY) && tc.memory.role !== 'remoteHarvester'
});
if (targetCreeps.length > 0) {
creep.transfer(targetCreeps[0], RESOURCE_ENERGY)
} else {
let 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 {
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
}
}
}
}
}
let target = Game.getObjectById(creep.memory.source)
let actionResult = creep.harvest(target)
if (actionResult === ERR_NOT_IN_RANGE) {
creep.moveTo(target, {visualizePathStyle: {stroke: '#ffaa00'}});
}
}
};

@ -0,0 +1,31 @@
module.exports = {
name: 'reserver',
prio: 20,
nextSpawn (spawn, roleCreeps) {
for (let roomName of activeRemotes) {
let room = Game.rooms[roomName]
if (!room) {
continue
}
if (!room.controller.owner
&& _.filter(roleCreeps, {memory: {room: roomName}}).length === 0 && (
!room.controller.reservation
|| (room.controller.reservation.username === 'NativeException' && room.controller.reservation.ticksToEnd < 3000)
)) {
return [
[CLAIM, CLAIM, MOVE, MOVE],
{room: roomName}
]
}
}
},
tick (creep) {
if (moveToRoom(creep, creep.memory.room) === MOVING) {
return
}
let room = Game.rooms[creep.memory.room]
if (creep.reserveController(room.controller) === ERR_NOT_IN_RANGE) {
creep.moveTo(room.controller)
}
},
}

@ -1,5 +1,30 @@
module.exports = {
name: 'scout',
count: 1,
prio: 15,
bodies: [[MOVE]],
nextSpawn (spawn, roleCreeps) {
for (let roomName of activeRemotes) {
if (!Game.rooms[roomName] && _.filter(roleCreeps, {memory: {room: roomName}}).length === 0) {
return [
[MOVE],
{room: roomName}
]
}
}
},
tick (creep) {
let room = Game.rooms[creep.memory.room]
if (!room) {
for (let remoteRoom of activeRemotes) {
if (!Game.rooms[remoteRoom]) {
creep.memory.room = remoteRoom
}
}
}
let pos = new RoomPosition(25, 25, creep.memory.room)
if (moveToRoom(creep, creep.memory.room) === ALREADY_IN_ROOM && creep.pos.getRangeTo(pos) > 10) {
creep.moveByPath(PathFinder.search(creep.pos, {pos, range: 10}).path)
}
},
}

@ -1,6 +1,15 @@
const common = require('common')
module.exports = {
name: 'transporter',
prio: 4,
count: 1,
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],
],
tick (creep) {
if (creep.store.getFreeCapacity(RESOURCE_ENERGY) === 0) {
creep.memory.loading = false
@ -12,9 +21,8 @@ module.exports = {
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
return (s.structureType === STRUCTURE_SPAWN
|| s.structureType === STRUCTURE_EXTENSION)
&& s.store.getFreeCapacity(RESOURCE_ENERGY) > 0
}
})

@ -3,6 +3,13 @@ let idling = 0
module.exports = {
idling,
name: 'upgrader',
prio: 6,
count: 1,
getCount: colonyRoom => colonyRoom.storage ? Math.ceil(colonyRoom.storage.store[RESOURCE_ENERGY] / 100000) : 1,
maxExpands: 4,
baseBody: [WORK, CARRY, MOVE],
expandBody: [WORK, WORK, MOVE],
tick (creep) {
if (creep.store.getFreeCapacity(RESOURCE_ENERGY) > 0) {
let dropped = creep.pos.findInRange(FIND_DROPPED_RESOURCES, 1);

@ -3,13 +3,10 @@ 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++) {
for (let x = source.pos.x - 1; x <= source.pos.x + 1; x++) {
for (let y = source.pos.y - 1; y <= source.pos.y + 1; y++) {
if (terrain.get(x, y) !== TERRAIN_MASK_WALL) {
spots.push([x, y])
}
@ -42,13 +39,25 @@ module.exports = {
if (!room.memory.lastEnergy) {
room.memory.lastEnergy = 0
}
if (!room.memory.energyStructuresPriority || Game.time % 100 === 0) {
room.memory.energyStructuresPriority = _.sortBy(
room.find(
FIND_MY_STRUCTURES,
{filter: s => s.structureType === STRUCTURE_EXTENSION || s.structureType === STRUCTURE_SPAWN}
).map(el => {return {structure: el, range: el.pos.getRangeTo(room.storage)}}),
'range'
).map(el => el.structure.id)
}
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}
if (!room.memory.harvestingSpots[source.id] || Game.time % 10 === 0) {
room.memory.harvestingSpots[source.id] = getHarvestingSpots(source)
}
if (!room.memory.sourcesData[source.id] || Game.time % 10 === 0) {
room.memory.sourcesData[source.id] = {spawnDistance: 0, energyCapacity: source.energyCapacity}
let spawn = source.pos.findClosestByPath(FIND_MY_SPAWNS)
if (spawn) {
room.memory.sourcesData[source.id].spawnDistance = source.pos.findPathTo(spawn.pos, {ignoreCreeps: true}).length
@ -62,8 +71,9 @@ module.exports = {
if (spawn.spawning) {
spawn.room.memory.spawnIdle = 0
let spawningCreep = Game.creeps[spawn.spawning.name];
let room = spawningCreep.memory.room || ''
spawn.room.visual.text(
'🛠' + spawningCreep.memory.role,
'🛠' + spawningCreep.memory.role + ' ' + room,
spawn.pos.x + 1,
spawn.pos.y,
{align: 'left', opacity: 0.8});
@ -71,7 +81,7 @@ module.exports = {
else {
let newCreep, prio
for (let [roleName, role] of Object.entries(ROLES)) {
let roleCreeps = _.filter(Game.creeps, (creep) => creep.memory.role === roleName);
let roleCreeps = _.filter(Game.creeps, {memory: {role: roleName, colony: spawn.room.name}});
if (minRoleCount === undefined || minRoleCount > roleCreeps.length) {
minRoleCount = roleCreeps.length
}
@ -80,10 +90,16 @@ module.exports = {
}
let newName = roleName + Game.time;
let body = []
let memory = {role: roleName}
if (roleName === 'harvester') {
let memory = {role: roleName, colony: spawn.room.name}
if (role.nextSpawn) {
let nextSpawn = role.nextSpawn(spawn, roleCreeps)
if (nextSpawn) {
[body, memory] = nextSpawn
}
}
else if (roleName === 'harvester') {
for (let source of spawn.room.find(FIND_SOURCES)) {
let spots = getHarvestingSpots(source)
let spots = spawn.room.memory.harvestingSpots[source.id]
let harvestingCapacity = 0
let sourceHarvesters = _.filter(Game.creeps, {memory: {role: 'harvester', source: source.id}})
if (sourceHarvesters.length >= spots.length) {
@ -94,8 +110,8 @@ module.exports = {
harvestingCapacity += harvester.getActiveBodyparts(WORK) * 2 * 300
}
}
if (harvestingCapacity <= source.energyCapacity) {
for (let b of ROLES.harvester.bodies) {
if (harvestingCapacity < source.energyCapacity) {
for (let b of role.bodies) {
if (getBodyCost(b) <= (spawn.room.memory.emergency ? spawn.room.energyAvailable : spawn.room.energyCapacityAvailable)) {
body = b
memory.source = source.id
@ -106,7 +122,41 @@ module.exports = {
}
}
}
else if (roleCreeps.length < role.count && role.idling === 0) {
else if (roleName === 'remoteHarvester') {
for (let roomName of activeRemotes) {
let roomMemory = Memory.rooms[roomName]
if (roomMemory) {
for (let [sourceId, sourceData] of Object.entries(roomMemory.sourcesData)) {
let spots = roomMemory.harvestingSpots[sourceId]
let harvestingCapacity = 0
let sourceHarvesters = _.filter(Game.creeps, {memory: {role: 'remoteHarvester', source: sourceId}})
if (sourceHarvesters.length >= spots.length) {
continue
}
for (let harvester of sourceHarvesters) {
if (harvester.ticksToLive > harvester.body.length * 3 + sourceData.spawnDistance) {
harvestingCapacity += harvester.getActiveBodyparts(WORK) * 2 * 300
}
}
if (harvestingCapacity < sourceData.energyCapacity) {
for (let b of role.bodies) {
if (getBodyCost(b) <= spawn.room.energyCapacityAvailable) {
body = b
memory.source = sourceId
memory.room = roomName
if (_.filter(b, WORK).length * 2 * 300 > sourceData.energyCapacity) {
break
}
} else {
break
}
}
}
}
}
}
}
else if (roleCreeps.length < (role.getCount ? role.getCount(spawn.room) : 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)) {
@ -119,15 +169,26 @@ module.exports = {
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 >= role.baseBody.length + role.expandBody.length * role.maxExpands) {
break
}
}
}
}
memory.role = roleName
memory.colony = spawn.room.name
if (body.length && (!prio || role.prio * (roleCreeps.length + 1) < prio)) {
newCreep = [body, newName, {memory}]
prio = role.prio * (roleCreeps.length + 1)
}
}
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 (newCreep) {
newCreep[2].energyStructures = spawn.room.memory.energyStructuresPriority.map(el => Game.getObjectById(el))
spawn.spawnCreep(...newCreep)
spawn.room.memory.spawnIdle++
spawn.room.visual.text(
@ -135,17 +196,11 @@ module.exports = {
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
EMERGENCY_MODE_TIMEOUT - (Game.time - spawn.room.memory.energyIncreasedAt)
)
if (timeToEmergency <= 0) {
spawn.room.memory.emergency = true
@ -156,12 +211,18 @@ module.exports = {
{align: 'left', opacity: 0.8});
} else if (timeToEmergency <= 50) {
spawn.room.visual.text(
'Emergency in ' + (EMERGENCY_MODE_TIMEOUT - spawn.room.memory.spawnIdle),
'Emergency in ' + timeToEmergency,
spawn.pos.x + 1,
spawn.pos.y,
{align: 'left', opacity: 0.8});
}
}
}/* else {
let renewableCreeps = spawn.pos.findInRange(FIND_MY_CREEPS, 1, {filter: c => c.ticksToLive < 1200})
if (renewableCreeps.length > 0) {
spawn.renewCreep(renewableCreeps[0])
}
}*/
}
},
}

Loading…
Cancel
Save