Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/creepSetups/setups.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ export const Roles = {
ranged : 'hydralisk',
healer : 'transfuser',
dismantler: 'lurker',
drill : 'drill',
coolant : 'coolant',
};

/**
Expand Down Expand Up @@ -319,4 +321,23 @@ export const CombatSetups = {

},

drill: {
default: new CreepSetup(Roles.drill, {
pattern : [MOVE, ATTACK, ATTACK, MOVE],
sizeLimit: Infinity,
}),
},

coolant: {
default: new CreepSetup(Roles.coolant, {
pattern : [HEAL, MOVE],
sizeLimit: Infinity,
}),
small: new CreepSetup(Roles.coolant, {
pattern : [HEAL, MOVE],
sizeLimit: 16,
}),
}


};
7 changes: 6 additions & 1 deletion src/declarations/memory.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,12 @@ interface Memory {
operationMode: operationMode;
log: LoggerMemory;
enableVisuals: boolean;
};
powerCollection: {
enabled: boolean;
maxRange: number;
minPower: number;
};
}
profiler?: any;
stats: any;
constructionSites: { [id: string]: number };
Expand Down
3 changes: 3 additions & 0 deletions src/directives/initializer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {DirectiveTargetSiege} from './targeting/siegeTarget';
import {DirectiveTerminalEmergencyState} from './terminalState/terminalState_emergency';
import {DirectiveTerminalEvacuateState} from './terminalState/terminalState_evacuate';
import {DirectiveTerminalRebuildState} from './terminalState/terminalState_rebuild';
import {DirectivePowerMine} from "./resource/powerMine";

/**
* This is the initializer for directives, which maps flags by their color code to the corresponding directive
Expand Down Expand Up @@ -92,6 +93,8 @@ export function DirectiveWrapper(flag: Flag): Directive | undefined {
return new DirectiveExtract(flag);
case COLOR_BLUE:
return new DirectiveHaul(flag);
case COLOR_RED:
return new DirectivePowerMine(flag);
}
break;

Expand Down
7 changes: 6 additions & 1 deletion src/directives/resource/haul.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ interface DirectiveHaulMemory extends FlagMemory {


/**
* Hauling directive: spawns hauler creeps to move large amounts of resourecs from a location (e.g. draining a storage)
* Hauling directive: spawns hauler creeps to move large amounts of resources from a location (e.g. draining a storage)
*/
@profile
export class DirectiveHaul extends Directive {
Expand All @@ -21,6 +21,7 @@ export class DirectiveHaul extends Directive {

private _store: StoreDefinition;
private _drops: { [resourceType: string]: Resource[] };
private _finishAtTime: number;

memory: DirectiveHaulMemory;

Expand Down Expand Up @@ -107,6 +108,10 @@ export class DirectiveHaul extends Directive {

run(): void {
if (_.sum(this.store) == 0 && this.pos.isVisible) {
// If everything is picked up, crudely give enough time to bring it back
this._finishAtTime = this._finishAtTime || (Game.time + 300);
}
if (Game.time >= this._finishAtTime) {
this.remove();
}
}
Expand Down
132 changes: 132 additions & 0 deletions src/directives/resource/powerMine.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import {Directive} from '../Directive';
import {profile} from '../../profiler/decorator';
import {PowerDrillOverlord} from '../../overlords/powerMining/PowerDrill';
import {Pathing} from "../../movement/Pathing";
import {calculateFormationStrength} from "../../utilities/creepUtils";
import {PowerHaulingOverlord} from "../../overlords/powerMining/PowerHauler";
import {log} from "../../console/log";


interface DirectivePowerMineMemory extends FlagMemory {
totalResources?: number;
}


/**
* PowerMining directive: kills power banks and collects the resources.
*/
@profile
export class DirectivePowerMine extends Directive {

static directiveName = 'powerMine';
static color = COLOR_YELLOW;
static secondaryColor = COLOR_RED;

miningDone: boolean;
pickupDone: boolean;
haulDirectiveCreated: boolean;
private _powerBank: StructurePowerBank | undefined;
private _drops: { [resourceType: string]: Resource[] };

memory: DirectivePowerMineMemory;

constructor(flag: Flag) {
super(flag);
this._powerBank = this.room != undefined ? this.pos.lookForStructure(STRUCTURE_POWER_BANK) as StructurePowerBank : undefined;
}

spawnMoarOverlords() {
if (!this.miningDone && this.powerBank) {
this.overlords.powerMine = new PowerDrillOverlord(this);
}
if (!this.pickupDone) {
this.spawnHaulers();
}
}

get drops(): { [resourceType: string]: Resource[] } {
if (!this.pos.isVisible) {
return {};
}
if (!this._drops) {
let drops = (this.pos.lookFor(LOOK_RESOURCES) || []) as Resource[];
this._drops = _.groupBy(drops, drop => drop.resourceType);
}
return this._drops;
}

get hasDrops(): boolean {
return _.keys(this.drops).length > 0;
}

get powerBank(): StructurePowerBank | undefined {
this._powerBank = this._powerBank || this.room ? this.flag.pos.lookForStructure(STRUCTURE_POWER_BANK) as StructurePowerBank : undefined;
return this._powerBank;
}

/**
* Total amount of resources remaining to be transported; cached into memory in case room loses visibility
*/
get totalResources(): number {
if (this.memory.totalResources == undefined) {
return 5000; // pick some non-zero number so that powerMiners will spawn
}
if (this.pos.isVisible) {
this.memory.totalResources = this.powerBank ? this.powerBank.power : this.memory.totalResources; // update total amount remaining
}
return this.memory.totalResources;
}

calculateRemainingLifespan() {
if (!this.room) {
return undefined;
} else if (this.powerBank == undefined) {
if (this.miningDone) {
// Power Bank is gone
return 0;
}
} else {
let tally = calculateFormationStrength(this.powerBank.pos.findInRange(FIND_MY_CREEPS, 4));
let healStrength: number = tally.heal * HEAL_POWER || 0;
let attackStrength: number = tally.attack * ATTACK_POWER || 0;
// PB have 50% hitback, avg damage is attack strength if its enough healing, otherwise healing
let avgDamagePerTick = Math.min(attackStrength, healStrength*2);
return this.powerBank.hits / avgDamagePerTick;
}
}

spawnHaulers() {
log.info("Checking spawning haulers");
// Begin checking for spawn haulers at 666 estimated ticks before PB destruction
if (this.haulDirectiveCreated || this.room && (!this.powerBank || this.powerBank.hits < 500000)) {
log.debug('Activating spawning haulers for power mining in room ' + this.pos.roomName);
this.haulDirectiveCreated = true;
this.overlords.powerHaul = new PowerHaulingOverlord(this);
}
}

setMiningDone(name: string) {
log.debug("Setting mining done and removing overlord for power mine in room " + this.room + " at time " + Game.time);
delete this.overlords[name];
this.miningDone = true;
this._powerBank = undefined;
}

/**
* This states when all the power has been picked up. Once all power has been picked up and delivered remove the directive
*/
isPickupDone(): boolean {
if (!this.pickupDone && this.miningDone && this.room && this.pos.isVisible && !this.hasDrops) {
this.pickupDone = true;
}
return this.pickupDone;
}

init(): void {
this.alert(`PowerMine directive active`);
}

run(): void {
}
}

35 changes: 34 additions & 1 deletion src/intel/RoomIntel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import {ExpansionEvaluator} from '../strategy/ExpansionEvaluator';
import {getCacheExpiration, irregularExponentialMovingAverage} from '../utilities/utils';
import {Zerg} from '../zerg/Zerg';
import {MY_USERNAME} from '../~settings';
import {Cartographer, ROOMTYPE_ALLEY} from "../utilities/Cartographer";
import {getAllColonies} from "../Colony";
import {DirectivePowerMine} from "../directives/resource/powerMine";

const RECACHE_TIME = 2500;
const OWNED_RECACHE_TIME = 1000;
Expand Down Expand Up @@ -327,6 +330,36 @@ export class RoomIntel {
return 0;
}

/**
* Find PowerBanks within range of maxRange and power above minPower to mine
* Creates directive to mine it
* TODO refactor when factory resources come out to be more generic
*/
private static minePowerBanks(room: Room) {
let powerSetting = Memory.settings.powerCollection;
if (powerSetting.enabled && Game.time % 300 == 0 && Cartographer.roomType(room.name) == ROOMTYPE_ALLEY) {
let powerBank = _.first(room.find(FIND_STRUCTURES).filter(struct => struct.structureType == STRUCTURE_POWER_BANK)) as StructurePowerBank;
if (powerBank != undefined && powerBank.ticksToDecay > 4000 && powerBank.power >= powerSetting.minPower) {
Game.notify(`Looking for power banks in ${room} found ${powerBank} with power ${powerBank.power} and ${powerBank.ticksToDecay} TTL.`);
if (DirectivePowerMine.isPresent(powerBank.pos, 'pos')) {
Game.notify(`Already mining room ${powerBank.room}!`);
return;
}

let colonies = getAllColonies().filter(colony => colony.level > 6);

for (let colony of colonies) {
let route = Game.map.findRoute(colony.room, powerBank.room);
if (route != -2 && route.length <= powerSetting.maxRange) {
Game.notify(`FOUND POWER BANK IN RANGE ${route.length}, STARTING MINING ${powerBank.room}`);
DirectivePowerMine.create(powerBank.pos);
return;
}
}

}
}
}

static run(): void {
let alreadyComputedScore = false;
Expand Down Expand Up @@ -365,7 +398,7 @@ export class RoomIntel {
if (room.controller && Game.time % 5 == 0) {
this.recordControllerInfo(room.controller);
}

this.minePowerBanks(room);
}
}

Expand Down
5 changes: 5 additions & 0 deletions src/memory/Memory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,11 @@ export class Mem {
operationMode: DEFAULT_OPERATION_MODE,
log : {},
enableVisuals: true,
powerCollection: {
enabled: false,
maxRange: 5,
minPower: 5000,
},
});
if (!Memory.stats) {
Memory.stats = {};
Expand Down
Loading