-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Move all but one transporter source into dispatcher system.
- Loading branch information
Showing
8 changed files
with
360 additions
and
242 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
import TaskProvider from 'dispatcher/task-provider'; | ||
import { ENEMY_STRENGTH_NONE } from 'room-defense'; | ||
import { getDangerMatrix } from 'utils/cost-matrix'; | ||
|
||
interface DropSourceTask extends ResourceSourceTask { | ||
type: 'drop'; | ||
target: Id<Resource>; | ||
} | ||
|
||
export default class DropSource extends TaskProvider<DropSourceTask, ResourceSourceContext> { | ||
constructor(readonly room: Room) { | ||
super(); | ||
} | ||
|
||
getType(): 'drop' { | ||
return 'drop'; | ||
} | ||
|
||
getHighestPriority() { | ||
return 5; | ||
} | ||
|
||
getTasks(context: ResourceSourceContext) { | ||
const options: DropSourceTask[] = []; | ||
|
||
this.addDroppedResourceOptions(options, context); | ||
|
||
return options; | ||
} | ||
|
||
private addDroppedResourceOptions(options: DropSourceTask[], context: ResourceSourceContext) { | ||
const creep = context.creep; | ||
|
||
// Look for dropped resources. | ||
const targets = this.room.find(FIND_DROPPED_RESOURCES, { | ||
filter: resource => { | ||
if (resource.amount < 10) return false; | ||
|
||
const result = PathFinder.search(creep.pos, resource.pos); | ||
if (result.incomplete) return false; | ||
|
||
return true; | ||
}, | ||
}); | ||
|
||
for (const target of targets) { | ||
if (context.resourceType && context.resourceType !== target.resourceType) return; | ||
|
||
const option: DropSourceTask = { | ||
priority: 4, | ||
weight: target.amount / (target.resourceType === RESOURCE_ENERGY ? 100 : 30), // @todo Also factor in distance. | ||
type: this.getType(), | ||
target: target.id, | ||
resourceType: target.resourceType, | ||
}; | ||
|
||
if (target.resourceType === RESOURCE_POWER) { | ||
option.priority++; | ||
} | ||
else if (target.resourceType === RESOURCE_ENERGY) { | ||
// Get storage location, since that is a low priority source for transporters. | ||
const storagePosition = creep.room.getStorageLocation(); | ||
|
||
if (storagePosition && target.pos.x === storagePosition.x && target.pos.y === storagePosition.y) { | ||
option.priority = creep.memory.role === 'transporter' ? (this.getStoragePriority(creep) + ((creep.room.storage || creep.room.terminal) ? 1 : 0)) : 5; | ||
} | ||
else { | ||
if (target.amount < 100) option.priority--; | ||
if (target.amount < 200) option.priority--; | ||
|
||
// If spawn / extensions need filling, transporters should not pick up | ||
// energy from random targets as readily, instead prioritize storage. | ||
if (creep.room.energyAvailable < creep.room.energyCapacityAvailable && creep.room.getCurrentResourceAmount(RESOURCE_ENERGY) > 5000 && creep.memory.role === 'transporter') option.priority -= 2; | ||
|
||
if (creep.room.storage && creep.room.getFreeStorage() < target.amount && creep.room.getEffectiveAvailableEnergy() > 20_000) { | ||
// If storage is super full, try leaving stuff on the ground. | ||
option.priority -= 2; | ||
} | ||
|
||
} | ||
|
||
} | ||
|
||
if (creep.room.getFreeStorage() < target.amount) { | ||
// If storage is super full, try leaving stuff on the ground. | ||
continue; | ||
} | ||
|
||
if (target.amount < creep.store.getCapacity() * 2) { | ||
// We only need to limit the number of creeps picking up resources if the amount is small. | ||
option.priority -= this.room.getCreepsWithOrder('drop', target.id).length * 2; | ||
} | ||
|
||
options.push(option); | ||
} | ||
} | ||
|
||
getStoragePriority(creep: Creep): number { | ||
const room = creep.room; | ||
if (room.energyAvailable < room.energyCapacityAvailable * 0.9) { | ||
// Spawning is important, so get energy when needed. | ||
return 4; | ||
} | ||
|
||
if (room.terminal && room.storage && room.storage.store.energy > 5000 && room.terminal.store.energy < room.storage.store.energy * 0.05 && !room.isClearingTerminal()) { | ||
// Take some energy out of storage to put into terminal from time to time. | ||
// @todo This really should be in the resource destination for the terminal. | ||
return 2; | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
isValid(task: DropSourceTask, context: ResourceSourceContext): boolean { | ||
const resource = Game.getObjectById(task.target); | ||
if (!resource) return false; | ||
if (resource.amount === 0) return false; | ||
if (context.creep.store.getFreeCapacity(resource.resourceType) === 0) return false; | ||
if (!this.isSafePosition(context.creep, resource.pos)) return false; | ||
|
||
const terminal = this.room.terminal; | ||
const terminalNeedsSpaceForEnergy = terminal && (terminal.store.getFreeCapacity() + terminal.store.getUsedCapacity(RESOURCE_ENERGY)) < 5000; | ||
if (task.resourceType !== RESOURCE_ENERGY && terminalNeedsSpaceForEnergy) return false; | ||
|
||
return true; | ||
} | ||
|
||
isSafePosition(creep: Creep | PowerCreep, pos: RoomPosition): boolean { | ||
if (!creep.room.isMine()) return true; | ||
if (creep.room.defense.getEnemyStrength() === ENEMY_STRENGTH_NONE) return true; | ||
|
||
const matrix = getDangerMatrix(creep.room.name); | ||
if (matrix.get(pos.x, pos.y) > 0) return false; | ||
|
||
return true; | ||
} | ||
|
||
execute(task: DropSourceTask, context: ResourceSourceContext): void { | ||
const creep = context.creep; | ||
const target = Game.getObjectById(task.target); | ||
|
||
creep.whenInRange(1, target, () => { | ||
creep.pickup(target); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
import TaskProvider from "dispatcher/task-provider"; | ||
import { ENEMY_STRENGTH_NONE } from "room-defense"; | ||
import { getDangerMatrix } from "utils/cost-matrix"; | ||
import { getResourcesIn } from "utils/store"; | ||
|
||
interface GraveSourceTask extends ResourceSourceTask { | ||
type: 'grave'; | ||
target: Id<Tombstone | Ruin>; | ||
} | ||
|
||
export default class GraveSource extends TaskProvider<GraveSourceTask, ResourceSourceContext> { | ||
constructor(readonly room: Room) { | ||
super(); | ||
} | ||
|
||
getType(): 'grave' { | ||
return 'grave'; | ||
} | ||
|
||
getHighestPriority() { | ||
return 5; | ||
} | ||
|
||
getTasks(context: ResourceSourceContext) { | ||
const options: GraveSourceTask[] = []; | ||
|
||
this.addGraveResourceOptions(options, context); | ||
|
||
return options; | ||
} | ||
|
||
private addGraveResourceOptions(options: GraveSourceTask[], context: ResourceSourceContext) { | ||
const creep = context.creep; | ||
|
||
// Look for tombstones and ruins with resources. | ||
const targets = (this.room.find(FIND_TOMBSTONES) as Array<Tombstone | Ruin>) | ||
.concat(this.room.find(FIND_RUINS)) | ||
.filter(target => { | ||
return target.store.getUsedCapacity() > 10; | ||
}); | ||
|
||
for (const target of targets) { | ||
// @todo It might be more effective to only create one task per tombstone / ruin and pick up all resources at once. | ||
for (const resourceType of getResourcesIn(target.store)) { | ||
if (context.resourceType && resourceType !== context.resourceType) continue; | ||
|
||
const amount = target.store.getUsedCapacity(resourceType); | ||
const option: GraveSourceTask = { | ||
priority: 4, | ||
weight: amount / (resourceType === RESOURCE_ENERGY ? 100 : 30), // @todo Also factor in distance. | ||
type: this.getType(), | ||
target: target.id, | ||
resourceType: resourceType, | ||
}; | ||
|
||
if (resourceType === RESOURCE_POWER) { | ||
option.priority++; | ||
} | ||
else if (resourceType === RESOURCE_ENERGY) { | ||
if (amount < 100) option.priority--; | ||
if (amount < 200) option.priority--; | ||
|
||
// If spawn / extensions need filling, transporters should not pick up | ||
// energy from random targets as readily, instead prioritize storage. | ||
if (creep.room.energyAvailable < creep.room.energyCapacityAvailable && creep.room.getCurrentResourceAmount(RESOURCE_ENERGY) > 5000 && creep.memory.role === 'transporter') option.priority -= 2; | ||
|
||
if (creep.room.storage && creep.room.getFreeStorage() < amount && creep.room.getEffectiveAvailableEnergy() > 20_000) { | ||
// If storage is super full, try leaving stuff on the ground. | ||
option.priority -= 2; | ||
} | ||
} | ||
|
||
if (creep.room.getFreeStorage() < target.store.getUsedCapacity(resourceType)) { | ||
// If storage is super full, try leaving stuff on the ground. | ||
continue; | ||
} | ||
|
||
if (target.store.getUsedCapacity() < creep.store.getCapacity() * 2) { | ||
// We only need to limit the number of creeps picking up resources if the amount is small. | ||
option.priority -= this.room.getCreepsWithOrder('grave', target.id).length * 2; | ||
} | ||
|
||
options.push(option); | ||
} | ||
} | ||
} | ||
|
||
isValid(task: GraveSourceTask, context: ResourceSourceContext): boolean { | ||
const tombstone = Game.getObjectById(task.target); | ||
if (!tombstone) return false; | ||
if (tombstone.store.getUsedCapacity(task.resourceType) === 0) return false; | ||
if (context.creep.store.getFreeCapacity(task.resourceType) === 0) return false; | ||
if (!this.isSafePosition(context.creep, tombstone.pos)) return false; | ||
|
||
const terminal = this.room.terminal; | ||
const terminalNeedsSpaceForEnergy = terminal && (terminal.store.getFreeCapacity() + terminal.store.getUsedCapacity(RESOURCE_ENERGY)) < 5000; | ||
if (task.resourceType !== RESOURCE_ENERGY && terminalNeedsSpaceForEnergy) return false; | ||
|
||
return true; | ||
} | ||
|
||
isSafePosition(creep: Creep | PowerCreep, pos: RoomPosition): boolean { | ||
if (!creep.room.isMine()) return true; | ||
if (creep.room.defense.getEnemyStrength() === ENEMY_STRENGTH_NONE) return true; | ||
|
||
const matrix = getDangerMatrix(creep.room.name); | ||
if (matrix.get(pos.x, pos.y) > 0) return false; | ||
|
||
return true; | ||
} | ||
|
||
execute(task: GraveSourceTask, context: ResourceSourceContext): void { | ||
const creep = context.creep; | ||
const target = Game.getObjectById(task.target); | ||
|
||
creep.whenInRange(1, target, () => { | ||
creep.withdraw(target, task.resourceType); | ||
}); | ||
} | ||
} |
Oops, something went wrong.