From c7759aca7f714fe41947b7acbf8a5d054d20ed23 Mon Sep 17 00:00:00 2001 From: Matthew Roy Date: Fri, 10 May 2019 13:54:52 -0700 Subject: [PATCH 01/11] Adding a melee defender to protect bunkers --- src/creepSetups/setups.ts | 20 +++++++++ src/directives/defense/invasionDefense.ts | 6 +++ src/movement/Movement.ts | 8 +++- src/overlords/defense/bunkerDefense.ts | 55 +++++++++++++++++++++++ src/zerg/CombatZerg.ts | 29 ++++++++++++ 5 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 src/overlords/defense/bunkerDefense.ts diff --git a/src/creepSetups/setups.ts b/src/creepSetups/setups.ts index 1c57dcbee..c51660b9b 100644 --- a/src/creepSetups/setups.ts +++ b/src/creepSetups/setups.ts @@ -21,6 +21,7 @@ export const Roles = { melee : 'zergling', ranged : 'hydralisk', healer : 'transfuser', + bunkerGuard : 'bunkerGuard', dismantler: 'lurker', }; @@ -297,6 +298,25 @@ export const CombatSetups = { }, + bunkerGuard: { + + early: new CreepSetup(Roles.bunkerGuard, { + pattern : [ATTACK, MOVE], + sizeLimit: Infinity, + }), + + default: new CreepSetup(Roles.bunkerGuard, { + pattern : [ATTACK, ATTACK, ATTACK, ATTACK, MOVE, MOVE, MOVE, MOVE], + sizeLimit: Infinity, + }), + + boosted_T3: new CreepSetup(Roles.bunkerGuard, { + pattern : [ATTACK, ATTACK, ATTACK, ATTACK, MOVE], + sizeLimit: Infinity, + }), + + }, + /** * Dismantlers (lurkers) are creeps with work parts for dismantle sieges */ diff --git a/src/directives/defense/invasionDefense.ts b/src/directives/defense/invasionDefense.ts index 1d6cab663..60a61293b 100644 --- a/src/directives/defense/invasionDefense.ts +++ b/src/directives/defense/invasionDefense.ts @@ -5,6 +5,7 @@ import {RangedDefenseOverlord} from '../../overlords/defense/rangedDefense'; import {profile} from '../../profiler/decorator'; import {Directive} from '../Directive'; import {NotifierPriority} from '../Notifier'; +import {BunkerDefenseOverlord} from "../../overlords/defense/bunkerDefense"; interface DirectiveInvasionDefenseMemory extends FlagMemory { persistent?: boolean; @@ -50,6 +51,11 @@ export class DirectiveInvasionDefense extends Directive { } else { this.overlords.meleeDefense = new MeleeDefenseOverlord(this, useBoosts); } + // If serious bunker busting attempt, spawn lurkers + if (meleeHostiles.length > 0 && ((expectedDamage > ATTACK_POWER * 30) || meleeHostiles[0].owner.username == 'Inakrin')) { + Game.notify(`Adding a new Bunker Defense in room ${this.room.print}`); + this.overlords.bunkerDefense = new BunkerDefenseOverlord(this, true); + } } diff --git a/src/movement/Movement.ts b/src/movement/Movement.ts index 15338ebb9..961050d17 100644 --- a/src/movement/Movement.ts +++ b/src/movement/Movement.ts @@ -88,6 +88,7 @@ export interface CombatMoveOptions { avoidPenalty?: number; approachBonus?: number; preferRamparts?: boolean; + requireRamparts?: boolean; displayCostMatrix?: boolean; displayAvoid?: boolean; } @@ -862,6 +863,7 @@ export class Movement { avoidPenalty : 10, approachBonus : 5, preferRamparts: true, + requireRamparts: false, }); const debug = false; @@ -923,7 +925,7 @@ export class Movement { } // Try to maneuver under ramparts if possible - if (options.preferRamparts && !creep.inRampart && approach.length > 0) { + if ((options.preferRamparts || options.requireRamparts) && !creep.inRampart && approach.length > 0) { const openRamparts = _.filter(creep.room.walkableRamparts, rampart => _.any(approach, g => rampart.pos.inRangeToXY(g.pos.x, g.pos.y, g.range)) @@ -940,7 +942,11 @@ export class Movement { outcome = creep.move(creep.pos.getDirectionTo(ret.path[0])); if (outcome == OK) { return outcome; + } else if (options.requireRamparts) { + creep.cancelOrder('move'); } + } else if (options.requireRamparts) { + creep.cancelOrder('move'); } } } diff --git a/src/overlords/defense/bunkerDefense.ts b/src/overlords/defense/bunkerDefense.ts new file mode 100644 index 000000000..c2c3ac257 --- /dev/null +++ b/src/overlords/defense/bunkerDefense.ts @@ -0,0 +1,55 @@ +import {CreepSetup} from '../../creepSetups/CreepSetup'; +import {CombatSetups, Roles} from '../../creepSetups/setups'; +import {DirectiveInvasionDefense} from '../../directives/defense/invasionDefense'; +import {CombatIntel} from '../../intel/CombatIntel'; +import {OverlordPriority} from '../../priorities/priorities_overlords'; +import {profile} from '../../profiler/decorator'; +import {boostResources} from '../../resources/map_resources'; +import {CombatZerg} from '../../zerg/CombatZerg'; +import {CombatOverlord} from '../CombatOverlord'; + +/** + * Spawns bunker-only defenders to defend against incoming sieges + */ +@profile +export class BunkerDefenseOverlord extends CombatOverlord { + + lurkers: CombatZerg[]; + room: Room; + + static settings = { + retreatHitsPercent : 0.75, + reengageHitsPercent: 0.95, + }; + + constructor(directive: DirectiveInvasionDefense, boosted = false, priority = OverlordPriority.defense.meleeDefense) { + super(directive, 'meleeDefense', priority, 1); + this.lurkers = this.combatZerg(Roles.bunkerGuard, { + boostWishlist: boosted ? [boostResources.attack[3], boostResources.move[3]] + : undefined + }); + } + + private handleDefender(zergling: CombatZerg): void { + if (zergling.room.hostiles.length > 0) { + zergling.autoBunkerCombat(zergling.room.name); + } + } + + private computeNeededZerglingAmount(setup: CreepSetup, boostMultiplier: number): number { + return 1; + } + + init() { + this.reassignIdleCreeps(Roles.melee); + if (this.canBoostSetup(CombatSetups.bunkerGuard.boosted_T3)) { + const setup = CombatSetups.bunkerGuard.boosted_T3; + this.wishlist(this.computeNeededZerglingAmount(setup, BOOSTS.attack.XUH2O.attack), setup); + } + } + + run() { + console.log(("Running Bunker defender")); + this.autoRun(this.lurkers, zergling => this.handleDefender(zergling)); + } +} diff --git a/src/zerg/CombatZerg.ts b/src/zerg/CombatZerg.ts index 567219dfc..7b0417872 100644 --- a/src/zerg/CombatZerg.ts +++ b/src/zerg/CombatZerg.ts @@ -5,6 +5,8 @@ import {CombatTargeting} from '../targeting/CombatTargeting'; import {GoalFinder} from '../targeting/GoalFinder'; import {randomHex} from '../utilities/utils'; import {Zerg} from './Zerg'; +import {insideBunkerBounds} from "../roomPlanner/layouts/bunker"; +import {Colony} from "../Colony"; interface CombatZergMemory extends CreepMemory { recovering: boolean; @@ -271,6 +273,33 @@ export class CombatZerg extends Zerg { } + autoBunkerCombat(roomName: string, verbose = false) { + if (this.getActiveBodyparts(ATTACK) > 0) { + this.autoMelee(); // Melee should be performed first + } + if (this.getActiveBodyparts(RANGED_ATTACK) > 0) { + this.autoRanged(); + } + + // Travel to the target room + if (!this.safelyInRoom(roomName)) { + this.debug(`Going to room!`); + return this.goToRoom(roomName, {ensurePath: true}); + } + + //let colony = Overmind.colonies[Overmind.colonyMap[roomName]] as Colony | undefined; + // TODO check if right colony + let siegingCreeps = this.room.hostiles.filter(creep => _.any(creep.pos.neighbors, pos => insideBunkerBounds(pos, this.colony))); + + + const target = CombatTargeting.findTarget(this, siegingCreeps); + + if (target) { + return Movement.combatMove(this, [{pos: target.pos, range: 1}], [], {requireRamparts: true}); + } + + } + needsToRecover(recoverThreshold = CombatIntel.minimumDamageTakenMultiplier(this.creep) < 1 ? 0.85 : 0.75, reengageThreshold = 1.0): boolean { let recovering: boolean; From 2a3e1bb913f3b195d6d7320c2ce67b2d21fbbead Mon Sep 17 00:00:00 2001 From: Matthew Roy Date: Mon, 13 May 2019 23:58:50 -0700 Subject: [PATCH 02/11] Trying to add movement towards creeps, but it will not prevent movement off rampart yet --- src/creepSetups/setups.ts | 9 +++++++-- src/directives/defense/invasionDefense.ts | 8 +++++++- src/movement/Movement.ts | 4 ---- src/overlords/defense/bunkerDefense.ts | 2 +- src/zerg/CombatZerg.ts | 2 +- 5 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/creepSetups/setups.ts b/src/creepSetups/setups.ts index c51660b9b..ec8aad43b 100644 --- a/src/creepSetups/setups.ts +++ b/src/creepSetups/setups.ts @@ -298,6 +298,9 @@ export const CombatSetups = { }, + /** + * Pure melee raw power creeps that should never leave the bunker. These are the final guards for a room + */ bunkerGuard: { early: new CreepSetup(Roles.bunkerGuard, { @@ -306,12 +309,14 @@ export const CombatSetups = { }), default: new CreepSetup(Roles.bunkerGuard, { - pattern : [ATTACK, ATTACK, ATTACK, ATTACK, MOVE, MOVE, MOVE, MOVE], + pattern : [ATTACK, ATTACK, MOVE], sizeLimit: Infinity, }), boosted_T3: new CreepSetup(Roles.bunkerGuard, { - pattern : [ATTACK, ATTACK, ATTACK, ATTACK, MOVE], + // 22 ATTACK, 3 MOVE times 2 + pattern : [ATTACK, ATTACK, ATTACK, ATTACK, ATTACK, ATTACK, ATTACK, ATTACK, ATTACK, ATTACK, ATTACK, ATTACK, + ATTACK, ATTACK, ATTACK, ATTACK, ATTACK, ATTACK, ATTACK, ATTACK, ATTACK, ATTACK, MOVE, MOVE, MOVE], sizeLimit: Infinity, }), diff --git a/src/directives/defense/invasionDefense.ts b/src/directives/defense/invasionDefense.ts index 60a61293b..de2bfcdc9 100644 --- a/src/directives/defense/invasionDefense.ts +++ b/src/directives/defense/invasionDefense.ts @@ -52,7 +52,13 @@ export class DirectiveInvasionDefense extends Directive { this.overlords.meleeDefense = new MeleeDefenseOverlord(this, useBoosts); } // If serious bunker busting attempt, spawn lurkers - if (meleeHostiles.length > 0 && ((expectedDamage > ATTACK_POWER * 30) || meleeHostiles[0].owner.username == 'Inakrin')) { + //console.log("Bunker Melee hostiles are: " + rangedHostiles); + // if (meleeHostiles.length > 0 && ((expectedDamage > ATTACK_POWER * 30) || meleeHostiles[0].owner.username == 'Inakrin' || rangedHostiles[0])) { + // Game.notify(`Adding a new Bunker Defense in room ${this.room.print}`); + // this.overlords.bunkerDefense = new BunkerDefenseOverlord(this, true); + // } + if ((meleeHostiles.length > 0 && (meleeHostiles[0].owner.username == 'o4kapuk' || meleeHostiles[0].owner.username == 'Inakrin')) || (rangedHostiles.length > 0 && rangedHostiles[0].owner.username == 'o4kapuk')) { + //if (meleeHostiles.length > 0 && ((expectedDamage > ATTACK_POWER * 30) || meleeHostiles[0].owner.username == 'Inakrin')) { Game.notify(`Adding a new Bunker Defense in room ${this.room.print}`); this.overlords.bunkerDefense = new BunkerDefenseOverlord(this, true); } diff --git a/src/movement/Movement.ts b/src/movement/Movement.ts index 961050d17..08a325e36 100644 --- a/src/movement/Movement.ts +++ b/src/movement/Movement.ts @@ -942,11 +942,7 @@ export class Movement { outcome = creep.move(creep.pos.getDirectionTo(ret.path[0])); if (outcome == OK) { return outcome; - } else if (options.requireRamparts) { - creep.cancelOrder('move'); } - } else if (options.requireRamparts) { - creep.cancelOrder('move'); } } } diff --git a/src/overlords/defense/bunkerDefense.ts b/src/overlords/defense/bunkerDefense.ts index c2c3ac257..625ac0971 100644 --- a/src/overlords/defense/bunkerDefense.ts +++ b/src/overlords/defense/bunkerDefense.ts @@ -23,7 +23,7 @@ export class BunkerDefenseOverlord extends CombatOverlord { }; constructor(directive: DirectiveInvasionDefense, boosted = false, priority = OverlordPriority.defense.meleeDefense) { - super(directive, 'meleeDefense', priority, 1); + super(directive, 'bunkerDefense', priority, 1); this.lurkers = this.combatZerg(Roles.bunkerGuard, { boostWishlist: boosted ? [boostResources.attack[3], boostResources.move[3]] : undefined diff --git a/src/zerg/CombatZerg.ts b/src/zerg/CombatZerg.ts index 7b0417872..1707ff9d7 100644 --- a/src/zerg/CombatZerg.ts +++ b/src/zerg/CombatZerg.ts @@ -295,7 +295,7 @@ export class CombatZerg extends Zerg { const target = CombatTargeting.findTarget(this, siegingCreeps); if (target) { - return Movement.combatMove(this, [{pos: target.pos, range: 1}], [], {requireRamparts: true}); + return Movement.combatMove(this, [{pos: target.pos, range: 1}], [], {preferRamparts: true, requireRamparts: true}); } } From da91812a68854d26766a6ba33355e745c78f8ec2 Mon Sep 17 00:00:00 2001 From: Matthew Roy Date: Tue, 14 May 2019 01:10:41 -0700 Subject: [PATCH 03/11] Adding max spawning distance --- src/overlords/CombatOverlord.ts | 4 ++-- src/overlords/defense/bunkerDefense.ts | 11 ++++------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/overlords/CombatOverlord.ts b/src/overlords/CombatOverlord.ts index d080962f8..88d446b28 100644 --- a/src/overlords/CombatOverlord.ts +++ b/src/overlords/CombatOverlord.ts @@ -19,11 +19,11 @@ export abstract class CombatOverlord extends Overlord { spawnGroup: SpawnGroup; requiredRCL: number; // default required RCL - constructor(directive: Directive, name: string, priority: number, requiredRCL: number) { + constructor(directive: Directive, name: string, priority: number, requiredRCL: number, maxPathDistance?: number) { super(directive, name, priority); this.directive = directive; this.requiredRCL = requiredRCL; - this.spawnGroup = new SpawnGroup(this, {requiredRCL: this.requiredRCL}); + this.spawnGroup = new SpawnGroup(this, {requiredRCL: this.requiredRCL, maxPathDistance: maxPathDistance}); } // Standard sequence of actions for running combat creeps diff --git a/src/overlords/defense/bunkerDefense.ts b/src/overlords/defense/bunkerDefense.ts index 625ac0971..2761e9f8f 100644 --- a/src/overlords/defense/bunkerDefense.ts +++ b/src/overlords/defense/bunkerDefense.ts @@ -23,7 +23,8 @@ export class BunkerDefenseOverlord extends CombatOverlord { }; constructor(directive: DirectiveInvasionDefense, boosted = false, priority = OverlordPriority.defense.meleeDefense) { - super(directive, 'bunkerDefense', priority, 1); + // Only spawn inside room + super(directive, 'bunkerDefense', priority, 1, 30); this.lurkers = this.combatZerg(Roles.bunkerGuard, { boostWishlist: boosted ? [boostResources.attack[3], boostResources.move[3]] : undefined @@ -32,24 +33,20 @@ export class BunkerDefenseOverlord extends CombatOverlord { private handleDefender(zergling: CombatZerg): void { if (zergling.room.hostiles.length > 0) { + console.log(`Running actual defender in room ${this.room.print}`); zergling.autoBunkerCombat(zergling.room.name); } } - private computeNeededZerglingAmount(setup: CreepSetup, boostMultiplier: number): number { - return 1; - } - init() { this.reassignIdleCreeps(Roles.melee); if (this.canBoostSetup(CombatSetups.bunkerGuard.boosted_T3)) { const setup = CombatSetups.bunkerGuard.boosted_T3; - this.wishlist(this.computeNeededZerglingAmount(setup, BOOSTS.attack.XUH2O.attack), setup); + this.wishlist(1, setup); } } run() { - console.log(("Running Bunker defender")); this.autoRun(this.lurkers, zergling => this.handleDefender(zergling)); } } From b20c6f0216fd60280cd8961d76e58dfa154b7905 Mon Sep 17 00:00:00 2001 From: Matthew Roy Date: Wed, 15 May 2019 12:53:36 -0700 Subject: [PATCH 04/11] Adding improved bodies and spawning --- src/creepSetups/setups.ts | 5 +++++ src/directives/defense/invasionDefense.ts | 4 ++-- src/movement/Movement.ts | 3 +++ src/overlords/SwarmOverlord.ts | 2 +- src/overlords/defense/bunkerDefense.ts | 14 +++++++++----- 5 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/creepSetups/setups.ts b/src/creepSetups/setups.ts index ec8aad43b..6e34dd94d 100644 --- a/src/creepSetups/setups.ts +++ b/src/creepSetups/setups.ts @@ -313,6 +313,11 @@ export const CombatSetups = { sizeLimit: Infinity, }), + halfMove: new CreepSetup(Roles.bunkerGuard, { + pattern : [ATTACK, ATTACK, ATTACK, ATTACK, MOVE], + sizeLimit: Infinity, + }), + boosted_T3: new CreepSetup(Roles.bunkerGuard, { // 22 ATTACK, 3 MOVE times 2 pattern : [ATTACK, ATTACK, ATTACK, ATTACK, ATTACK, ATTACK, ATTACK, ATTACK, ATTACK, ATTACK, ATTACK, ATTACK, diff --git a/src/directives/defense/invasionDefense.ts b/src/directives/defense/invasionDefense.ts index de2bfcdc9..b7e268b92 100644 --- a/src/directives/defense/invasionDefense.ts +++ b/src/directives/defense/invasionDefense.ts @@ -57,8 +57,8 @@ export class DirectiveInvasionDefense extends Directive { // Game.notify(`Adding a new Bunker Defense in room ${this.room.print}`); // this.overlords.bunkerDefense = new BunkerDefenseOverlord(this, true); // } - if ((meleeHostiles.length > 0 && (meleeHostiles[0].owner.username == 'o4kapuk' || meleeHostiles[0].owner.username == 'Inakrin')) || (rangedHostiles.length > 0 && rangedHostiles[0].owner.username == 'o4kapuk')) { - //if (meleeHostiles.length > 0 && ((expectedDamage > ATTACK_POWER * 30) || meleeHostiles[0].owner.username == 'Inakrin')) { + // Look, it's 2am so going to go with name hack for now. + if ((meleeHostiles.length > 0 && (meleeHostiles[0].owner.username == 'o4kapuk' || meleeHostiles[0].owner.username == 'inakrin'))) { Game.notify(`Adding a new Bunker Defense in room ${this.room.print}`); this.overlords.bunkerDefense = new BunkerDefenseOverlord(this, true); } diff --git a/src/movement/Movement.ts b/src/movement/Movement.ts index 08a325e36..e5b033df5 100644 --- a/src/movement/Movement.ts +++ b/src/movement/Movement.ts @@ -943,6 +943,9 @@ export class Movement { if (outcome == OK) { return outcome; } + } else if (options.requireRamparts) { + log.alert(`Canceling move order for non-ramparted area for ${creep.print}`); + creep.cancelOrder('move'); } } } diff --git a/src/overlords/SwarmOverlord.ts b/src/overlords/SwarmOverlord.ts index 9d581a1ea..223aba651 100644 --- a/src/overlords/SwarmOverlord.ts +++ b/src/overlords/SwarmOverlord.ts @@ -32,7 +32,7 @@ export abstract class SwarmOverlord extends CombatOverlord { creepQuantities[setup.role] += existingCreepsOfRole.length; if (!neededQuantities[setup.role]) neededQuantities[setup.role] = 0; neededQuantities[setup.role] += amount; - // Spawn the neede quantity of creeps + // Spawn the needed quantity of creeps const spawnQuantity = amount - existingCreepsOfRole.length; for (let i = 0; i < spawnQuantity; i++) { this.requestCreep(setup, {priority: priority}); diff --git a/src/overlords/defense/bunkerDefense.ts b/src/overlords/defense/bunkerDefense.ts index 2761e9f8f..e204742ac 100644 --- a/src/overlords/defense/bunkerDefense.ts +++ b/src/overlords/defense/bunkerDefense.ts @@ -7,6 +7,7 @@ import {profile} from '../../profiler/decorator'; import {boostResources} from '../../resources/map_resources'; import {CombatZerg} from '../../zerg/CombatZerg'; import {CombatOverlord} from '../CombatOverlord'; +import {log} from "../../console/log"; /** * Spawns bunker-only defenders to defend against incoming sieges @@ -31,10 +32,10 @@ export class BunkerDefenseOverlord extends CombatOverlord { }); } - private handleDefender(zergling: CombatZerg): void { - if (zergling.room.hostiles.length > 0) { - console.log(`Running actual defender in room ${this.room.print}`); - zergling.autoBunkerCombat(zergling.room.name); + private handleDefender(lurker: CombatZerg): void { + log.debug(`Running BunkerDefender in room ${this.room.print}`); + if (lurker.room.hostiles.length > 0) { + lurker.autoBunkerCombat(lurker.room.name); } } @@ -43,10 +44,13 @@ export class BunkerDefenseOverlord extends CombatOverlord { if (this.canBoostSetup(CombatSetups.bunkerGuard.boosted_T3)) { const setup = CombatSetups.bunkerGuard.boosted_T3; this.wishlist(1, setup); + } else { + const setup = CombatSetups.bunkerGuard.halfMove; + this.wishlist(2, setup); } } run() { - this.autoRun(this.lurkers, zergling => this.handleDefender(zergling)); + this.autoRun(this.lurkers, lurkers => this.handleDefender(lurkers)); } } From e2e41ffae923dbbfbe3cc10554429df01697083d Mon Sep 17 00:00:00 2001 From: Matthew Roy Date: Wed, 15 May 2019 14:49:32 -0700 Subject: [PATCH 05/11] Merge --- src/directives/defense/invasionDefense.ts | 7 +++++-- src/overlords/defense/rangedDefense.ts | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/directives/defense/invasionDefense.ts b/src/directives/defense/invasionDefense.ts index b7e268b92..01bd8ee3f 100644 --- a/src/directives/defense/invasionDefense.ts +++ b/src/directives/defense/invasionDefense.ts @@ -25,6 +25,8 @@ export class DirectiveInvasionDefense extends Directive { memory: DirectiveInvasionDefenseMemory; room: Room | undefined; + safeEndTime: 300; + safeSpawnHaltTime: 100; private relocateFrequency: number; @@ -37,8 +39,9 @@ export class DirectiveInvasionDefense extends Directive { if (!this.room) { return; } - const expectedDamage = CombatIntel.maxDamageByCreeps(this.room.dangerousHostiles); - const useBoosts = (expectedDamage > ATTACK_POWER * 75) + const expectedDamage = CombatIntel.maxDamageByCreeps(this.room.dangerousPlayerHostiles); + const expectedHealing = CombatIntel.maxHealingByCreeps(this.room.dangerousPlayerHostiles); + const useBoosts = (expectedDamage > ATTACK_POWER * 13) || (expectedHealing > RANGED_ATTACK_POWER * 50) && !!this.colony.terminal && !!this.colony.evolutionChamber; const percentWalls = _.filter(this.room.barriers, s => s.structureType == STRUCTURE_WALL).length / diff --git a/src/overlords/defense/rangedDefense.ts b/src/overlords/defense/rangedDefense.ts index c3f2f2e5f..e6a432e0f 100644 --- a/src/overlords/defense/rangedDefense.ts +++ b/src/overlords/defense/rangedDefense.ts @@ -27,7 +27,7 @@ export class RangedDefenseOverlord extends CombatOverlord { priority = OverlordPriority.defense.rangedDefense) { super(directive, 'rangedDefense', priority, 1); this.hydralisks = this.combatZerg(Roles.ranged, { - boostWishlist: boosted ? [boostResources.ranged_attack[3], boostResources.heal[3], boostResources.move[3]] + boostWishlist: boosted ? [boostResources.tough[3], boostResources.ranged_attack[3], boostResources.heal[3], boostResources.move[3]] : undefined }); } From ebc2a5b8f74651da280880287ec6d59d2a5dd151 Mon Sep 17 00:00:00 2001 From: Matthew Roy Date: Thu, 16 May 2019 23:46:20 -0700 Subject: [PATCH 06/11] value modifications --- src/directives/defense/invasionDefense.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/directives/defense/invasionDefense.ts b/src/directives/defense/invasionDefense.ts index 01bd8ee3f..7914a5f4e 100644 --- a/src/directives/defense/invasionDefense.ts +++ b/src/directives/defense/invasionDefense.ts @@ -41,7 +41,7 @@ export class DirectiveInvasionDefense extends Directive { } const expectedDamage = CombatIntel.maxDamageByCreeps(this.room.dangerousPlayerHostiles); const expectedHealing = CombatIntel.maxHealingByCreeps(this.room.dangerousPlayerHostiles); - const useBoosts = (expectedDamage > ATTACK_POWER * 13) || (expectedHealing > RANGED_ATTACK_POWER * 50) + const useBoosts = (expectedDamage > ATTACK_POWER * 50) || (expectedHealing > RANGED_ATTACK_POWER * 100) && !!this.colony.terminal && !!this.colony.evolutionChamber; const percentWalls = _.filter(this.room.barriers, s => s.structureType == STRUCTURE_WALL).length / @@ -49,7 +49,7 @@ export class DirectiveInvasionDefense extends Directive { const meleeHostiles = _.filter(this.room.hostiles, hostile => hostile.getActiveBodyparts(ATTACK) > 0 || hostile.getActiveBodyparts(WORK) > 0); const rangedHostiles = _.filter(this.room.hostiles, hostile => hostile.getActiveBodyparts(RANGED_ATTACK) > 0); - if (this.colony.stage > ColonyStage.Larva) { + if (this.colony.stage > ColonyStage.Larva && !this.colony.controller.upgradeBlocked) { this.overlords.rangedDefense = new RangedDefenseOverlord(this, useBoosts); } else { this.overlords.meleeDefense = new MeleeDefenseOverlord(this, useBoosts); @@ -63,7 +63,7 @@ export class DirectiveInvasionDefense extends Directive { // Look, it's 2am so going to go with name hack for now. if ((meleeHostiles.length > 0 && (meleeHostiles[0].owner.username == 'o4kapuk' || meleeHostiles[0].owner.username == 'inakrin'))) { Game.notify(`Adding a new Bunker Defense in room ${this.room.print}`); - this.overlords.bunkerDefense = new BunkerDefenseOverlord(this, true); + this.overlords.bunkerDefense = new BunkerDefenseOverlord(this, false); } } From 12b8c6cb303be382a7e639ae840471d65d36f903 Mon Sep 17 00:00:00 2001 From: Matthew Roy Date: Fri, 24 May 2019 07:34:16 -0700 Subject: [PATCH 07/11] Updating line for bunker guard --- src/overlords/defense/bunkerDefense.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/overlords/defense/bunkerDefense.ts b/src/overlords/defense/bunkerDefense.ts index e204742ac..6418ca409 100644 --- a/src/overlords/defense/bunkerDefense.ts +++ b/src/overlords/defense/bunkerDefense.ts @@ -40,7 +40,7 @@ export class BunkerDefenseOverlord extends CombatOverlord { } init() { - this.reassignIdleCreeps(Roles.melee); + this.reassignIdleCreeps(Roles.bunkerGuard); if (this.canBoostSetup(CombatSetups.bunkerGuard.boosted_T3)) { const setup = CombatSetups.bunkerGuard.boosted_T3; this.wishlist(1, setup); From 2d98774bdd12d609e53f16303b81fb6ddb857a71 Mon Sep 17 00:00:00 2001 From: Matthew Roy Date: Sun, 26 May 2019 23:04:13 -0700 Subject: [PATCH 08/11] Some final tweakers --- src/directives/defense/invasionDefense.ts | 12 +++--------- src/overlords/defense/bunkerDefense.ts | 2 +- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/src/directives/defense/invasionDefense.ts b/src/directives/defense/invasionDefense.ts index 7914a5f4e..1c19c65a8 100644 --- a/src/directives/defense/invasionDefense.ts +++ b/src/directives/defense/invasionDefense.ts @@ -49,20 +49,14 @@ export class DirectiveInvasionDefense extends Directive { const meleeHostiles = _.filter(this.room.hostiles, hostile => hostile.getActiveBodyparts(ATTACK) > 0 || hostile.getActiveBodyparts(WORK) > 0); const rangedHostiles = _.filter(this.room.hostiles, hostile => hostile.getActiveBodyparts(RANGED_ATTACK) > 0); - if (this.colony.stage > ColonyStage.Larva && !this.colony.controller.upgradeBlocked) { + if (this.colony.stage > ColonyStage.Larva) { this.overlords.rangedDefense = new RangedDefenseOverlord(this, useBoosts); } else { this.overlords.meleeDefense = new MeleeDefenseOverlord(this, useBoosts); } // If serious bunker busting attempt, spawn lurkers - //console.log("Bunker Melee hostiles are: " + rangedHostiles); - // if (meleeHostiles.length > 0 && ((expectedDamage > ATTACK_POWER * 30) || meleeHostiles[0].owner.username == 'Inakrin' || rangedHostiles[0])) { - // Game.notify(`Adding a new Bunker Defense in room ${this.room.print}`); - // this.overlords.bunkerDefense = new BunkerDefenseOverlord(this, true); - // } - // Look, it's 2am so going to go with name hack for now. - if ((meleeHostiles.length > 0 && (meleeHostiles[0].owner.username == 'o4kapuk' || meleeHostiles[0].owner.username == 'inakrin'))) { - Game.notify(`Adding a new Bunker Defense in room ${this.room.print}`); + // TODO understand dismantlers damage output + if (meleeHostiles.length > 0 && (expectedDamage > ATTACK_POWER * 70)) { this.overlords.bunkerDefense = new BunkerDefenseOverlord(this, false); } diff --git a/src/overlords/defense/bunkerDefense.ts b/src/overlords/defense/bunkerDefense.ts index 6418ca409..50f28cfa9 100644 --- a/src/overlords/defense/bunkerDefense.ts +++ b/src/overlords/defense/bunkerDefense.ts @@ -19,7 +19,7 @@ export class BunkerDefenseOverlord extends CombatOverlord { room: Room; static settings = { - retreatHitsPercent : 0.75, + retreatHitsPercent : 0.85, reengageHitsPercent: 0.95, }; From f69cc2b831c01920f495bca4431470cdf14e697d Mon Sep 17 00:00:00 2001 From: Matthew Roy Date: Thu, 13 Jun 2019 11:26:17 -0700 Subject: [PATCH 09/11] BunkerDefender upgrades --- src/movement/Movement.ts | 5 ++--- src/overlords/defense/bunkerDefense.ts | 10 ++++++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/movement/Movement.ts b/src/movement/Movement.ts index e5b033df5..ccaa5c94e 100644 --- a/src/movement/Movement.ts +++ b/src/movement/Movement.ts @@ -31,6 +31,7 @@ const STATE_CURRENT_Y = 8; export const MovePriorities = { [Roles.manager] : 1, [Roles.queen] : 2, + [Roles.bunkerGuard]: 3, [Roles.melee] : 3, [Roles.ranged] : 4, [Roles.guardMelee]: 5, @@ -872,6 +873,7 @@ export class Movement { const matrix = Pathing.getDefaultMatrix(creep.room).clone(); Pathing.blockMyCreeps(matrix, creep.room); Pathing.blockHostileCreeps(matrix, creep.room); + if (options.requireRamparts) { Pathing.blockNonRamparts(matrix, creep.room); } Movement.combatMoveCallbackModifier(creep.room, matrix, approach, avoid, options); if (options.displayCostMatrix) { Visualizer.displayCostMatrix(matrix, roomName); @@ -943,9 +945,6 @@ export class Movement { if (outcome == OK) { return outcome; } - } else if (options.requireRamparts) { - log.alert(`Canceling move order for non-ramparted area for ${creep.print}`); - creep.cancelOrder('move'); } } } diff --git a/src/overlords/defense/bunkerDefense.ts b/src/overlords/defense/bunkerDefense.ts index 50f28cfa9..fc902d3cb 100644 --- a/src/overlords/defense/bunkerDefense.ts +++ b/src/overlords/defense/bunkerDefense.ts @@ -1,7 +1,5 @@ -import {CreepSetup} from '../../creepSetups/CreepSetup'; import {CombatSetups, Roles} from '../../creepSetups/setups'; import {DirectiveInvasionDefense} from '../../directives/defense/invasionDefense'; -import {CombatIntel} from '../../intel/CombatIntel'; import {OverlordPriority} from '../../priorities/priorities_overlords'; import {profile} from '../../profiler/decorator'; import {boostResources} from '../../resources/map_resources'; @@ -34,8 +32,16 @@ export class BunkerDefenseOverlord extends CombatOverlord { private handleDefender(lurker: CombatZerg): void { log.debug(`Running BunkerDefender in room ${this.room.print}`); + if (!lurker.inRampart) { + const nearRampart = _.find(lurker.room.walkableRamparts, rampart => rampart.pos.getRangeTo(lurker) < 5); + if (nearRampart) { + lurker.goTo(nearRampart); + } + } if (lurker.room.hostiles.length > 0) { lurker.autoBunkerCombat(lurker.room.name); + } else { + // go out of way in bunker } } From 4cd2b89dee523be9c9cd8571bf023095f3597b50 Mon Sep 17 00:00:00 2001 From: Matthew Roy Date: Thu, 13 Jun 2019 11:41:35 -0700 Subject: [PATCH 10/11] Fixing lint --- src/directives/defense/invasionDefense.ts | 8 +++----- src/overlords/defense/bunkerDefense.ts | 4 ++-- src/overlords/defense/rangedDefense.ts | 4 ++-- src/zerg/CombatZerg.ts | 8 +++----- 4 files changed, 10 insertions(+), 14 deletions(-) diff --git a/src/directives/defense/invasionDefense.ts b/src/directives/defense/invasionDefense.ts index 1c19c65a8..192854f88 100644 --- a/src/directives/defense/invasionDefense.ts +++ b/src/directives/defense/invasionDefense.ts @@ -1,11 +1,11 @@ import {ColonyStage} from '../../Colony'; import {CombatIntel} from '../../intel/CombatIntel'; +import {Directive} from '../Directive'; +import {BunkerDefenseOverlord} from '../../overlords/defense/bunkerDefense'; import {MeleeDefenseOverlord} from '../../overlords/defense/meleeDefense'; import {RangedDefenseOverlord} from '../../overlords/defense/rangedDefense'; -import {profile} from '../../profiler/decorator'; -import {Directive} from '../Directive'; import {NotifierPriority} from '../Notifier'; -import {BunkerDefenseOverlord} from "../../overlords/defense/bunkerDefense"; +import {profile} from '../../profiler/decorator'; interface DirectiveInvasionDefenseMemory extends FlagMemory { persistent?: boolean; @@ -25,8 +25,6 @@ export class DirectiveInvasionDefense extends Directive { memory: DirectiveInvasionDefenseMemory; room: Room | undefined; - safeEndTime: 300; - safeSpawnHaltTime: 100; private relocateFrequency: number; diff --git a/src/overlords/defense/bunkerDefense.ts b/src/overlords/defense/bunkerDefense.ts index fc902d3cb..08e59c4b8 100644 --- a/src/overlords/defense/bunkerDefense.ts +++ b/src/overlords/defense/bunkerDefense.ts @@ -5,7 +5,7 @@ import {profile} from '../../profiler/decorator'; import {boostResources} from '../../resources/map_resources'; import {CombatZerg} from '../../zerg/CombatZerg'; import {CombatOverlord} from '../CombatOverlord'; -import {log} from "../../console/log"; +import {log} from '../../console/log'; /** * Spawns bunker-only defenders to defend against incoming sieges @@ -52,7 +52,7 @@ export class BunkerDefenseOverlord extends CombatOverlord { this.wishlist(1, setup); } else { const setup = CombatSetups.bunkerGuard.halfMove; - this.wishlist(2, setup); + this.wishlist(1, setup); } } diff --git a/src/overlords/defense/rangedDefense.ts b/src/overlords/defense/rangedDefense.ts index e6a432e0f..1ce728d34 100644 --- a/src/overlords/defense/rangedDefense.ts +++ b/src/overlords/defense/rangedDefense.ts @@ -27,8 +27,8 @@ export class RangedDefenseOverlord extends CombatOverlord { priority = OverlordPriority.defense.rangedDefense) { super(directive, 'rangedDefense', priority, 1); this.hydralisks = this.combatZerg(Roles.ranged, { - boostWishlist: boosted ? [boostResources.tough[3], boostResources.ranged_attack[3], boostResources.heal[3], boostResources.move[3]] - : undefined + boostWishlist: boosted ? [boostResources.tough[3], boostResources.ranged_attack[3], + boostResources.heal[3], boostResources.move[3]] : undefined }); } diff --git a/src/zerg/CombatZerg.ts b/src/zerg/CombatZerg.ts index 1707ff9d7..3ce8e3239 100644 --- a/src/zerg/CombatZerg.ts +++ b/src/zerg/CombatZerg.ts @@ -1,12 +1,11 @@ import {CombatIntel} from '../intel/CombatIntel'; +import {insideBunkerBounds} from '../roomPlanner/layouts/bunker'; import {Movement, NO_ACTION} from '../movement/Movement'; import {profile} from '../profiler/decorator'; import {CombatTargeting} from '../targeting/CombatTargeting'; import {GoalFinder} from '../targeting/GoalFinder'; import {randomHex} from '../utilities/utils'; import {Zerg} from './Zerg'; -import {insideBunkerBounds} from "../roomPlanner/layouts/bunker"; -import {Colony} from "../Colony"; interface CombatZergMemory extends CreepMemory { recovering: boolean; @@ -287,10 +286,9 @@ export class CombatZerg extends Zerg { return this.goToRoom(roomName, {ensurePath: true}); } - //let colony = Overmind.colonies[Overmind.colonyMap[roomName]] as Colony | undefined; // TODO check if right colony - let siegingCreeps = this.room.hostiles.filter(creep => _.any(creep.pos.neighbors, pos => insideBunkerBounds(pos, this.colony))); - + const siegingCreeps = this.room.hostiles.filter(creep => + _.any(creep.pos.neighbors, pos => insideBunkerBounds(pos, this.colony))); const target = CombatTargeting.findTarget(this, siegingCreeps); From 903ea1d68ab2c2582795e96f6a9847b2170070fe Mon Sep 17 00:00:00 2001 From: Matthew Roy Date: Thu, 13 Jun 2019 12:50:13 -0700 Subject: [PATCH 11/11] Damn imports --- src/directives/defense/invasionDefense.ts | 7 ++++--- src/movement/Pathing.ts | 14 ++++++++++++++ src/overlords/defense/bunkerDefense.ts | 2 +- src/zerg/CombatZerg.ts | 7 +++---- 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/directives/defense/invasionDefense.ts b/src/directives/defense/invasionDefense.ts index 192854f88..5b27611e7 100644 --- a/src/directives/defense/invasionDefense.ts +++ b/src/directives/defense/invasionDefense.ts @@ -1,12 +1,13 @@ -import {ColonyStage} from '../../Colony'; import {CombatIntel} from '../../intel/CombatIntel'; -import {Directive} from '../Directive'; import {BunkerDefenseOverlord} from '../../overlords/defense/bunkerDefense'; import {MeleeDefenseOverlord} from '../../overlords/defense/meleeDefense'; import {RangedDefenseOverlord} from '../../overlords/defense/rangedDefense'; -import {NotifierPriority} from '../Notifier'; import {profile} from '../../profiler/decorator'; +import {ColonyStage} from '../../Colony'; +import {Directive} from '../Directive'; +import {NotifierPriority} from '../Notifier'; + interface DirectiveInvasionDefenseMemory extends FlagMemory { persistent?: boolean; created: number; diff --git a/src/movement/Pathing.ts b/src/movement/Pathing.ts index 4c207d594..7811632ea 100644 --- a/src/movement/Pathing.ts +++ b/src/movement/Pathing.ts @@ -613,6 +613,20 @@ export class Pathing { }); } + /** + * Sets walkable rampart positions to 1, everything else is blocked + */ + static blockNonRamparts(matrix: CostMatrix, room: Room) { + for (let y = 0; y < 50; ++y) { + for (let x = 0; x < 50; ++x) { + matrix.set(x, y, 0xff); + } + } + _.forEach(room.walkableRamparts, rampart => { + matrix.set(rampart.pos.x, rampart.pos.y, 1); + }); + } + /** * Explicitly blocks off walls for a room */ diff --git a/src/overlords/defense/bunkerDefense.ts b/src/overlords/defense/bunkerDefense.ts index 08e59c4b8..eeb036def 100644 --- a/src/overlords/defense/bunkerDefense.ts +++ b/src/overlords/defense/bunkerDefense.ts @@ -1,3 +1,4 @@ +import {log} from '../../console/log'; import {CombatSetups, Roles} from '../../creepSetups/setups'; import {DirectiveInvasionDefense} from '../../directives/defense/invasionDefense'; import {OverlordPriority} from '../../priorities/priorities_overlords'; @@ -5,7 +6,6 @@ import {profile} from '../../profiler/decorator'; import {boostResources} from '../../resources/map_resources'; import {CombatZerg} from '../../zerg/CombatZerg'; import {CombatOverlord} from '../CombatOverlord'; -import {log} from '../../console/log'; /** * Spawns bunker-only defenders to defend against incoming sieges diff --git a/src/zerg/CombatZerg.ts b/src/zerg/CombatZerg.ts index 3ce8e3239..514ad707d 100644 --- a/src/zerg/CombatZerg.ts +++ b/src/zerg/CombatZerg.ts @@ -1,7 +1,7 @@ import {CombatIntel} from '../intel/CombatIntel'; -import {insideBunkerBounds} from '../roomPlanner/layouts/bunker'; import {Movement, NO_ACTION} from '../movement/Movement'; import {profile} from '../profiler/decorator'; +import {insideBunkerBounds} from '../roomPlanner/layouts/bunker'; import {CombatTargeting} from '../targeting/CombatTargeting'; import {GoalFinder} from '../targeting/GoalFinder'; import {randomHex} from '../utilities/utils'; @@ -286,16 +286,15 @@ export class CombatZerg extends Zerg { return this.goToRoom(roomName, {ensurePath: true}); } - // TODO check if right colony + // TODO check if right colony, also yes colony check is in there to stop red squigglies const siegingCreeps = this.room.hostiles.filter(creep => - _.any(creep.pos.neighbors, pos => insideBunkerBounds(pos, this.colony))); + _.any(creep.pos.neighbors, pos => this.colony && insideBunkerBounds(pos, this.colony))); const target = CombatTargeting.findTarget(this, siegingCreeps); if (target) { return Movement.combatMove(this, [{pos: target.pos, range: 1}], [], {preferRamparts: true, requireRamparts: true}); } - } needsToRecover(recoverThreshold = CombatIntel.minimumDamageTakenMultiplier(this.creep) < 1 ? 0.85 : 0.75,