diff --git a/src/creep/builder.ts b/src/creep/builder.ts index 21d2744..9316423 100644 --- a/src/creep/builder.ts +++ b/src/creep/builder.ts @@ -9,6 +9,7 @@ export function runAsBuilder(creep: Creep) { if (memory.building && creep.store[RESOURCE_ENERGY] === 0) { memory.building = false; + memory.repairTargetId = ''; } if (!memory.building && creep.store.getFreeCapacity() === 0) { @@ -52,26 +53,49 @@ function build(creep: Creep): boolean { return true; } +/** + * Починить. + * + * Если цель нужно чинить, то дойти до цели и произвести починку. + * Если цель починена, найти ближайшую цель в радиусе починки и чинить ее. + * + * @param creep + */ function repair(creep: Creep) { - const target = findRepairTarget(creep); - if (!target) { + const memory = creep.memory as BuilderMemory; + let repairTarget; + // Если уже установлена цель, то получаем объект, + // иначе ищем подходящую цель для ремонта. + if (memory.repairTargetId) { + repairTarget = Game.getObjectById(memory.repairTargetId); + } else { + repairTarget = findBestRepairTarget(creep); + memory.repairTargetId = repairTarget ? repairTarget.id : ''; + } + // Если цель ремонта не найдена, то ничего не делаем. + if (!repairTarget) { + memory.repairTargetId = ''; return false; } - if (creep.repair(target) == ERR_NOT_IN_RANGE) { - creep.say('🚧 repair'); - creep.moveTo(target, { visualizePathStyle: { stroke: '#ffffff' } }); + if (repairTarget.hits < repairTarget.hitsMax) { + if (creep.repair(repairTarget) == ERR_NOT_IN_RANGE) { + creep.say('🚧 repair'); + creep.moveTo(repairTarget, { visualizePathStyle: { stroke: '#ffffff' } }); + } + } else { + const closestRepairTarget = findClosestRepairTarget(creep); + if (closestRepairTarget) { + if (creep.repair(closestRepairTarget) !== OK) { + memory.repairTargetId = ''; + } + } else { + memory.repairTargetId = ''; + } } return true; } -function findRepairTarget(creep: Creep): Structure | undefined { - const nearest = creep.pos.findInRange(FIND_STRUCTURES, 3, { - filter: (t) => t.hits < t.hitsMax && t.structureType !== STRUCTURE_ROAD - }); - if (nearest.length > 0) { - nearest.sort((t1, t2) => t1.hits - t2.hits); - return nearest[0]; - } +function findBestRepairTarget(creep: Creep): Structure | undefined { const targets = creep.room.find(FIND_STRUCTURES, { filter: (t) => t.hits < t.hitsMax && t.structureType !== STRUCTURE_ROAD }); @@ -81,3 +105,10 @@ function findRepairTarget(creep: Creep): Structure | undefined { } return undefined; } + +function findClosestRepairTarget(creep: Creep): Structure | undefined { + const targets = creep.pos.findInRange(FIND_STRUCTURES, 3, { + filter: (t) => t.hits < t.hitsMax && t.structureType !== STRUCTURE_ROAD + }); + return _.first(targets); +} diff --git a/src/main.ts b/src/main.ts index c95f605..bc420fe 100644 --- a/src/main.ts +++ b/src/main.ts @@ -27,12 +27,13 @@ function makeCreep(role: CreepRole, count: number) { memory, directions: [BOTTOM, BOTTOM_RIGHT, RIGHT, BOTTOM_LEFT, LEFT] }); - console.log(`Make creep "${role}"`, 'err', err); + console.log(`Make creep "${role}"`, 'body', calcBodyCost(body), 'err', err); } } function selectBody(capacity: number): Array { const bodies = [ + [WORK, WORK, CARRY, CARRY, CARRY, CARRY, MOVE, MOVE, MOVE, MOVE], [WORK, WORK, CARRY, CARRY, CARRY, MOVE, MOVE, MOVE], [WORK, WORK, CARRY, CARRY, MOVE, MOVE], [WORK, CARRY, CARRY, MOVE, MOVE] diff --git a/src/types.d.ts b/src/types.d.ts index 5bebc00..f57585f 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -15,6 +15,10 @@ interface CreepMemory { * Идентификатор источника энергии для крипа. */ sourceId: Id | ''; + /** + * Цель для починки. + */ + repairTargetId: Id | ''; room: string; working: boolean; }