Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Just for fun, a distraction Overlord for making creeps that just run … #3

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
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
5 changes: 5 additions & 0 deletions src/creepSetups/setups.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,11 @@ export const CombatSetups = {
sizeLimit: Infinity,
}),

distraction: new CreepSetup(Roles.ranged, {
pattern : [MOVE, MOVE, MOVE, RANGED_ATTACK, MOVE],
sizeLimit: 1,
}),

default: new CreepSetup(Roles.ranged, {
pattern : [RANGED_ATTACK, RANGED_ATTACK, RANGED_ATTACK, MOVE, MOVE, MOVE, MOVE, HEAL],
sizeLimit: Infinity,
Expand Down
6 changes: 6 additions & 0 deletions src/directives/defense/invasionDefense.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {ColonyStage} from '../../Colony';
import {CombatIntel} from '../../intel/CombatIntel';
import {DistractionOverlord} from '../../overlords/defense/distraction';
import {MeleeDefenseOverlord} from '../../overlords/defense/meleeDefense';
import {RangedDefenseOverlord} from '../../overlords/defense/rangedDefense';
import {profile} from '../../profiler/decorator';
Expand Down Expand Up @@ -51,6 +52,11 @@ export class DirectiveInvasionDefense extends Directive {
this.overlords.meleeDefense = new MeleeDefenseOverlord(this, useBoosts);
}

// Secondary defense
if (this.colony.level > 4 && meleeHostiles.length > 1 && expectedDamage > (ATTACK_POWER * 20)) {
this.overlords.distraction = new DistractionOverlord(this);
}

}

init(): void {
Expand Down
61 changes: 61 additions & 0 deletions src/overlords/defense/distraction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
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';

/**
* 5 Move 1 RA creep that avoids all enemies and distracts attackers.
* Just for fun
* TODO: Make them prefer swamps when at max hp
*/
@profile
export class DistractionOverlord extends CombatOverlord {

distractions: CombatZerg[];
room: Room;

static settings = {
retreatHitsPercent : 0.85,
reengageHitsPercent: 0.95,
};

constructor(directive: DirectiveInvasionDefense,
boosted = false,
priority = OverlordPriority.defense.rangedDefense) {
super(directive, 'distraction', priority, 1);
this.distractions = this.combatZerg(Roles.ranged);
}

private handleDistraction(distraction: CombatZerg): void {
if (this.room.hostiles.length > 0) {
distraction.autoCombat(this.room.name, false, 5, {preferRamparts: false});
DistractionOverlord.taunt(distraction, this.room.hostiles[0].owner.username);
const nearbyHostiles = this.room.hostiles.filter(hostile => hostile.pos.getRangeTo(distraction) <= 6);
if (nearbyHostiles.length > 0) {
distraction.kite(nearbyHostiles);
}
}
}

static taunt(distraction: CombatZerg, name?: string) {
const taunts: string[] = ['Heylisten!', 'Pssssst', 'So close', '🎣', 'Try harder', 'Get good;)', 'Base ⬆️', '🔜',
'⚠️Swamp⚠️', 'Follow me!', 'Catch Me!', `Hi ${name || ''}`, '🍑🍑🍑', '🏎️ VROOM'];
distraction.sayRandom(taunts, true);
}

init() {
this.reassignIdleCreeps(Roles.ranged);
const setup = CombatSetups.hydralisks.distraction;
this.wishlist(1, setup);
}

run() {
console.log(`Distraction overlord running in ${this.room.print} with ${this.distractions}!`);
this.autoRun(this.distractions, distraction => this.handleDistraction(distraction));
}
}
10 changes: 5 additions & 5 deletions src/zerg/CombatZerg.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {CombatIntel} from '../intel/CombatIntel';
import {Movement, NO_ACTION} from '../movement/Movement';
import {CombatMoveOptions, Movement, MoveOptions, NO_ACTION} from '../movement/Movement';
import {profile} from '../profiler/decorator';
import {CombatTargeting} from '../targeting/CombatTargeting';
import {GoalFinder} from '../targeting/GoalFinder';
Expand Down Expand Up @@ -227,7 +227,7 @@ export class CombatZerg extends Zerg {
/**
* Navigate to a room, then engage hostile creeps there, perform medic actions, etc.
*/
autoCombat(roomName: string, verbose = false) {
autoCombat(roomName: string, verbose = false, preferredRange?: number, options?: CombatMoveOptions) {

// Do standard melee, ranged, and heal actions
if (this.getActiveBodyparts(ATTACK) > 0) {
Expand Down Expand Up @@ -255,18 +255,18 @@ export class CombatZerg extends Zerg {
// Fight within the room
const target = CombatTargeting.findTarget(this);
const preferRanged = this.getActiveBodyparts(RANGED_ATTACK) > this.getActiveBodyparts(ATTACK);
const targetRange = preferRanged ? 3 : 1;
const targetRange = preferredRange || preferRanged ? 3 : 1;
this.debug(`${target}, ${targetRange}`);
if (target) {
const avoid = [];
// Avoid melee hostiles if you are a ranged creep
if (preferRanged) {
const meleeHostiles = _.filter(this.room.hostiles, h => CombatIntel.getAttackDamage(h) > 0);
for (const hostile of meleeHostiles) {
avoid.push({pos: hostile.pos, range: 2});
avoid.push({pos: hostile.pos, range: targetRange - 1});
}
}
return Movement.combatMove(this, [{pos: target.pos, range: targetRange}], []);
return Movement.combatMove(this, [{pos: target.pos, range: targetRange}], avoid, options);
}

}
Expand Down