Add ESLint, Add worker utils
This commit is contained in:
parent
a64f40b6cc
commit
c026087af1
29 changed files with 3042 additions and 1734 deletions
4
.envrc
Normal file
4
.envrc
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
if command -v nix-shell &> /dev/null
|
||||||
|
then
|
||||||
|
use flake
|
||||||
|
fi
|
||||||
30
.gitignore
vendored
30
.gitignore
vendored
|
|
@ -1,3 +1,29 @@
|
||||||
dist/
|
*.log
|
||||||
|
database.json
|
||||||
node_modules/
|
node_modules/
|
||||||
.env
|
rethinkdb_data/
|
||||||
|
.idea/
|
||||||
|
*.iml
|
||||||
|
.npm/
|
||||||
|
.gitconfig
|
||||||
|
.bash_history
|
||||||
|
.bash_login
|
||||||
|
static/img/*.png
|
||||||
|
*.db
|
||||||
|
*.db-journal
|
||||||
|
.env
|
||||||
|
/.next/
|
||||||
|
/out/
|
||||||
|
/build
|
||||||
|
.DS_Store
|
||||||
|
*.pem
|
||||||
|
/.pnp
|
||||||
|
.pnp.js
|
||||||
|
.env.local
|
||||||
|
.env.development.local
|
||||||
|
.env.test.local
|
||||||
|
.env.production.local
|
||||||
|
.direnv
|
||||||
|
tsconfig.tsbuildinfo
|
||||||
|
/data/
|
||||||
|
dist/
|
||||||
|
|
|
||||||
24
eslint.config.mts
Normal file
24
eslint.config.mts
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
import js from "@eslint/js";
|
||||||
|
import globals from "globals";
|
||||||
|
import tseslint from "typescript-eslint";
|
||||||
|
import { defineConfig } from "eslint/config";
|
||||||
|
import stylistic from "@stylistic/eslint-plugin";
|
||||||
|
|
||||||
|
export default defineConfig([
|
||||||
|
{
|
||||||
|
files: ["**/*.{js,mjs,cjs,ts,mts,cts}"],
|
||||||
|
plugins: { js,
|
||||||
|
"@stylistic": stylistic
|
||||||
|
},
|
||||||
|
extends: ["js/recommended"],
|
||||||
|
languageOptions: { globals: globals.browser },
|
||||||
|
rules: {
|
||||||
|
"@stylistic/max-len": ["error", { code: 80, tabWidth: 2 }],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tseslint.configs.recommended,
|
||||||
|
stylistic.configs.customize({
|
||||||
|
quotes: "double",
|
||||||
|
semi: true,
|
||||||
|
})
|
||||||
|
]);
|
||||||
61
flake.lock
generated
Normal file
61
flake.lock
generated
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"flake-utils": {
|
||||||
|
"inputs": {
|
||||||
|
"systems": "systems"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1731533236,
|
||||||
|
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1765929117,
|
||||||
|
"narHash": "sha256-Z1FXlaWWA5Vq6lwiW7bwJFgPLX5vBC0eyiiGLhIAlhY=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "d2d63347f51ab2867c08a08e0fddb00001930c42",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "master",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-utils": "flake-utils",
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"systems": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
||||||
19
flake.nix
Normal file
19
flake.nix
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
description = "Screeps Bot Hurricane";
|
||||||
|
inputs.nixpkgs.url = "github:NixOS/nixpkgs/master";
|
||||||
|
inputs.flake-utils.url = "github:numtide/flake-utils";
|
||||||
|
|
||||||
|
outputs = { self, nixpkgs, flake-utils }:
|
||||||
|
flake-utils.lib.eachDefaultSystem (system: let
|
||||||
|
pkgs = nixpkgs.legacyPackages.${system};
|
||||||
|
in {
|
||||||
|
devShell = pkgs.mkShell {
|
||||||
|
nativeBuildInputs = [ pkgs.bashInteractive ];
|
||||||
|
buildInputs = with pkgs; [
|
||||||
|
(yarn.override { nodejs = nodejs_24; }) nodejs_24
|
||||||
|
nodePackages.typescript
|
||||||
|
nodePackages.typescript-language-server
|
||||||
|
];
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
36
package.json
36
package.json
|
|
@ -12,23 +12,27 @@
|
||||||
"push": "yarn build && node ./upload.js"
|
"push": "yarn build && node ./upload.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/screeps": "^3.3.0"
|
"@types/screeps": "^3.3.8"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@swc/cli": "^0.1.57",
|
"@eslint/js": "^9.39.2",
|
||||||
"@swc/core": "^1.3.24",
|
"@stylistic/eslint-plugin": "^5.6.1",
|
||||||
"@swc/jest": "^0.2.24",
|
"@swc/cli": "^0.7.9",
|
||||||
"@types/jest": "^29.2.5",
|
"@swc/core": "^1.15.5",
|
||||||
"@types/node": "^18.11.18",
|
"@swc/jest": "^0.2.39",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.47.0",
|
"@types/jest": "^30.0.0",
|
||||||
"@typescript-eslint/parser": "^5.47.0",
|
"@types/node": "^25.0.3",
|
||||||
"dotenv": "^16.0.3",
|
"@typescript-eslint/eslint-plugin": "^8.50.0",
|
||||||
"eslint": "^8.30.0",
|
"@typescript-eslint/parser": "^8.50.0",
|
||||||
"husky": "^8.0.0",
|
"dotenv": "^17.2.3",
|
||||||
"jest": "^29.3.1",
|
"eslint": "^9.39.2",
|
||||||
"lodash": "^4.17.21",
|
"globals": "^16.5.0",
|
||||||
"screeps-jest": "^2.0.2",
|
"husky": "^9.1.7",
|
||||||
"ts-node": "^10.9.1",
|
"jest": "^30.2.0",
|
||||||
"typescript": "^4.9.4"
|
"jiti": "^2.6.1",
|
||||||
|
"screeps-jest": "^2.0.3",
|
||||||
|
"ts-node": "^10.9.2",
|
||||||
|
"typescript": "^5.9.3",
|
||||||
|
"typescript-eslint": "^8.50.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,60 +1,62 @@
|
||||||
declare global {
|
declare global {
|
||||||
interface CreepMemory {
|
interface CreepMemory {
|
||||||
state?: number
|
state?: number;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ChainableAction {
|
export interface ChainableAction {
|
||||||
or: (action: Action) => ChainableAction,
|
or: (action: Action) => ChainableAction;
|
||||||
and: (action: Action) => ChainableAction,
|
and: (action: Action) => ChainableAction;
|
||||||
andThen: (action: Action) => ChainableAction,
|
andThen: (action: Action) => ChainableAction;
|
||||||
repeat: () => void
|
repeat: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const NoOp: Action = (creep: Creep, state: number = 0) => ({
|
export const NoOp: Action = (creep: Creep, state: number = 0) => ({
|
||||||
or: () => NoOp(creep, state),
|
or: () => NoOp(creep, state),
|
||||||
and: () => NoOp(creep, state),
|
and: () => NoOp(creep, state),
|
||||||
andThen: () => NoOp(creep, state),
|
andThen: () => NoOp(creep, state),
|
||||||
repeat: () => {}
|
repeat: () => {},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const Success: Action = (creep: Creep, state: number = 0) => ({
|
export const Success: Action = (creep: Creep, state: number = 0) => ({
|
||||||
or: () => Success(creep, state),
|
or: () => Success(creep, state),
|
||||||
and: (action: Action) => action(creep, state),
|
and: (action: Action) => action(creep, state),
|
||||||
andThen: (action: Action) => {
|
andThen: (action: Action) => {
|
||||||
creep.memory.state = state + 1;
|
creep.memory.state = state + 1;
|
||||||
return action(creep, state + 1);
|
return action(creep, state + 1);
|
||||||
},
|
},
|
||||||
repeat: () => {
|
repeat: () => {
|
||||||
creep.memory.state = 0;
|
creep.memory.state = 0;
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const InProgress: Action = (creep: Creep, state: number = 0) => ({
|
export const InProgress: Action = (creep: Creep, state: number = 0) => ({
|
||||||
or: () => InProgress(creep, state),
|
or: () => InProgress(creep, state),
|
||||||
and: (action: Action) => action(creep, state),
|
and: (action: Action) => action(creep, state),
|
||||||
andThen: () => NoOp(creep, state),
|
andThen: () => NoOp(creep, state),
|
||||||
repeat: () => {}
|
repeat: () => {},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const Fail: Action = (creep: Creep, state: number = 0) => ({
|
export const Fail: Action = (creep: Creep, state: number = 0) => ({
|
||||||
or: (action: Action) => action(creep, state),
|
or: (action: Action) => action(creep, state),
|
||||||
and: () => NoOp(creep, state),
|
and: () => NoOp(creep, state),
|
||||||
andThen: () => NoOp(creep, state),
|
andThen: () => NoOp(creep, state),
|
||||||
repeat: () => {
|
repeat: () => {
|
||||||
console.log('Warning: Last task in series failed for creep ' + creep.name);
|
console.log("Warning: Last task in series failed for creep " + creep.name);
|
||||||
}
|
},
|
||||||
})
|
});
|
||||||
|
|
||||||
export const createAction = (name: string, action: (creep: Creep) => Action): Action => {
|
export const createAction
|
||||||
|
= (name: string, action: (c: Creep) => Action): Action => {
|
||||||
return (creep: Creep, state: number = 0) => {
|
return (creep: Creep, state: number = 0) => {
|
||||||
if ((creep.memory.state ?? 0) > state) {
|
if ((creep.memory.state ?? 0) > state) {
|
||||||
return Success(creep, state);
|
return Success(creep, state);
|
||||||
}
|
}
|
||||||
return action(creep)(creep, state);
|
return action(creep)(creep, state);
|
||||||
}
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
export const runAction = (creep: Creep, action: Action): ChainableAction => action(creep);
|
export const runAction = (creep: Creep, action: Action): ChainableAction =>
|
||||||
|
action(creep);
|
||||||
|
|
||||||
export type Action = (creep: Creep, state?: number) => ChainableAction;
|
export type Action = (creep: Creep, state?: number) => ChainableAction;
|
||||||
|
|
|
||||||
53
src/Actions/Util.ts
Normal file
53
src/Actions/Util.ts
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
import { Action, Fail } from "../Actions/Action";
|
||||||
|
|
||||||
|
export const notNull
|
||||||
|
= <T>(x: T | null | undefined, f: (y: T) => Action): Action => {
|
||||||
|
if (x == null) {
|
||||||
|
return Fail;
|
||||||
|
}
|
||||||
|
return f(x);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const closestTowerToFill = (pos: RoomPosition): StructureTower | null =>
|
||||||
|
pos.findClosestByRange(FIND_MY_STRUCTURES, {
|
||||||
|
filter: structure => structure.structureType === STRUCTURE_TOWER
|
||||||
|
&& (structure as StructureTower).store
|
||||||
|
.getFreeCapacity(RESOURCE_ENERGY) > 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const closestExtensionToFill
|
||||||
|
= (pos: RoomPosition): StructureExtension | null =>
|
||||||
|
pos.findClosestByRange(FIND_MY_STRUCTURES, {
|
||||||
|
filter: structure => structure.structureType === STRUCTURE_EXTENSION
|
||||||
|
&& (structure as StructureExtension).store
|
||||||
|
.getFreeCapacity(RESOURCE_ENERGY) > 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const closestContainerWithEnergy
|
||||||
|
= (pos: RoomPosition): StructureContainer | null =>
|
||||||
|
pos.findClosestByRange(FIND_STRUCTURES, {
|
||||||
|
filter: structure => structure.structureType === STRUCTURE_CONTAINER
|
||||||
|
&& (structure as StructureContainer).store
|
||||||
|
.getUsedCapacity(RESOURCE_ENERGY) > 0,
|
||||||
|
});
|
||||||
|
export const closestContainerToFill
|
||||||
|
= (pos: RoomPosition): StructureContainer | null =>
|
||||||
|
pos.findClosestByRange(FIND_STRUCTURES, {
|
||||||
|
filter: structure => structure.structureType === STRUCTURE_CONTAINER
|
||||||
|
&& (structure as StructureContainer).store
|
||||||
|
.getFreeCapacity(RESOURCE_ENERGY) > 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
export const closestStorageWithResource
|
||||||
|
= (pos: RoomPosition, t: ResourceConstant): StructureStorage | null =>
|
||||||
|
pos.findClosestByRange(FIND_MY_STRUCTURES, {
|
||||||
|
filter: structure => structure.structureType === STRUCTURE_STORAGE
|
||||||
|
&& (structure as StructureStorage).store
|
||||||
|
.getUsedCapacity(t) > 0,
|
||||||
|
});
|
||||||
|
export const closestStorageToFill
|
||||||
|
= (pos: RoomPosition, t: ResourceConstant): StructureStorage | null =>
|
||||||
|
pos.findClosestByRange(FIND_MY_STRUCTURES, {
|
||||||
|
filter: structure => structure.structureType === STRUCTURE_STORAGE
|
||||||
|
&& (structure as StructureStorage).store.getFreeCapacity(t) > 0,
|
||||||
|
});
|
||||||
|
|
@ -1,23 +1,24 @@
|
||||||
import { createAction, Fail, InProgress, Success } from "./Action";
|
import { createAction, Fail, InProgress, Success } from "./Action";
|
||||||
import { moveTo } from "./moveTo";
|
import { moveTo } from "./moveTo";
|
||||||
|
|
||||||
export const buildConstructionSite = () => createAction('buildConstructionSite', (creep: Creep) => {
|
export const buildConstructionSite = () =>
|
||||||
|
createAction("buildConstructionSite", (creep: Creep) => {
|
||||||
const cs = creep.pos.findClosestByRange(FIND_CONSTRUCTION_SITES);
|
const cs = creep.pos.findClosestByRange(FIND_CONSTRUCTION_SITES);
|
||||||
if (!cs) {
|
if (!cs) {
|
||||||
return Fail;
|
return Fail;
|
||||||
}
|
}
|
||||||
switch (creep.build(cs)) {
|
switch (creep.build(cs)) {
|
||||||
case OK: {
|
case OK: {
|
||||||
return InProgress;
|
return InProgress;
|
||||||
}
|
}
|
||||||
case ERR_NOT_ENOUGH_RESOURCES: {
|
case ERR_NOT_ENOUGH_RESOURCES: {
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
case ERR_NOT_IN_RANGE: {
|
case ERR_NOT_IN_RANGE: {
|
||||||
return moveTo(cs);
|
return moveTo(cs);
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
return Fail;
|
return Fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,24 @@
|
||||||
import { createAction, Fail, InProgress, Success } from "./Action";
|
import { createAction, Fail, InProgress, Success } from "./Action";
|
||||||
import { moveTo } from "./moveTo";
|
import { moveTo } from "./moveTo";
|
||||||
|
|
||||||
export const harvestFromClosestActiveSource = () => createAction('harvestFromClosestActiveSource', (creep: Creep) => {
|
export const harvestFromClosestActiveSource = () =>
|
||||||
|
createAction("harvestFromClosestActiveSource", (creep: Creep) => {
|
||||||
const source = creep.pos.findClosestByPath(FIND_SOURCES_ACTIVE);
|
const source = creep.pos.findClosestByPath(FIND_SOURCES_ACTIVE);
|
||||||
if (!source) {
|
if (!source) {
|
||||||
return Fail;
|
return Fail;
|
||||||
}
|
}
|
||||||
if (creep.store.getFreeCapacity(RESOURCE_ENERGY) === 0) {
|
if (creep.store.getFreeCapacity(RESOURCE_ENERGY) === 0) {
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
switch(creep.harvest(source)) {
|
switch (creep.harvest(source)) {
|
||||||
case OK: {
|
case OK: {
|
||||||
return InProgress;
|
return InProgress;
|
||||||
}
|
}
|
||||||
case ERR_NOT_IN_RANGE: {
|
case ERR_NOT_IN_RANGE: {
|
||||||
return moveTo(source);
|
return moveTo(source);
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
return Fail;
|
return Fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,16 @@
|
||||||
import { createAction, Fail, InProgress } from "./Action";
|
import { createAction, Fail, InProgress } from "./Action";
|
||||||
|
|
||||||
export const moveTo = (pos: _HasRoomPosition | RoomPosition) => createAction('moveTo', (creep: Creep) => {
|
export const moveTo = (pos: _HasRoomPosition | RoomPosition) =>
|
||||||
switch(creep.moveTo(pos)) {
|
createAction("moveTo", (creep: Creep) => {
|
||||||
case OK: {
|
switch (creep.moveTo(pos)) {
|
||||||
return InProgress;
|
case OK: {
|
||||||
}
|
return InProgress;
|
||||||
case ERR_TIRED: {
|
}
|
||||||
return InProgress;
|
case ERR_TIRED: {
|
||||||
}
|
return InProgress;
|
||||||
default: {
|
}
|
||||||
return Fail;
|
default: {
|
||||||
}
|
return Fail;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,25 @@
|
||||||
import { createAction, Fail, InProgress, Success } from "./Action";
|
import { createAction, Fail, InProgress, Success } from "./Action";
|
||||||
import { moveTo } from "./moveTo";
|
import { moveTo } from "./moveTo";
|
||||||
|
|
||||||
export const repairStructure = () => createAction('repairStructure', (creep: Creep) => {
|
export const repairStructure = () =>
|
||||||
const cs = creep.pos.findClosestByRange(FIND_STRUCTURES, { filter: (str) => str.hits < str.hitsMax * 0.8 });
|
createAction("repairStructure", (creep: Creep) => {
|
||||||
|
const cs = creep.pos.findClosestByRange(FIND_STRUCTURES,
|
||||||
|
{ filter: str => str.hits < str.hitsMax * 0.8 });
|
||||||
if (!cs) {
|
if (!cs) {
|
||||||
return Fail;
|
return Fail;
|
||||||
}
|
}
|
||||||
switch (creep.repair(cs)) {
|
switch (creep.repair(cs)) {
|
||||||
case OK: {
|
case OK: {
|
||||||
return InProgress;
|
return InProgress;
|
||||||
}
|
}
|
||||||
case ERR_NOT_ENOUGH_RESOURCES: {
|
case ERR_NOT_ENOUGH_RESOURCES: {
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
case ERR_NOT_IN_RANGE: {
|
case ERR_NOT_IN_RANGE: {
|
||||||
return moveTo(cs);
|
return moveTo(cs);
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
return Fail;
|
return Fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,33 @@
|
||||||
import { createAction, Fail, InProgress, Success } from "./Action";
|
import { createAction, Fail, InProgress, Success } from "./Action";
|
||||||
import { moveTo } from "./moveTo";
|
import { moveTo } from "./moveTo";
|
||||||
|
|
||||||
export const transferEnergy = (target: Creep | StructureSpawn | StructureContainer | StructureExtension | StructureStorage | null) => createAction('transferEnergy', (creep: Creep) => {
|
type TransferTarget = Creep
|
||||||
|
| StructureSpawn
|
||||||
|
| StructureContainer
|
||||||
|
| StructureStorage
|
||||||
|
| StructureExtension
|
||||||
|
| StructureTower;
|
||||||
|
|
||||||
|
export const transferEnergy = (target: TransferTarget | null) =>
|
||||||
|
createAction("transferEnergy", (creep: Creep) => {
|
||||||
if (target == null) {
|
if (target == null) {
|
||||||
return Fail;
|
return Fail;
|
||||||
}
|
}
|
||||||
if (target.store.getFreeCapacity(RESOURCE_ENERGY) === 0) {
|
if (target.store.getFreeCapacity(RESOURCE_ENERGY) === 0) {
|
||||||
|
return Fail;
|
||||||
|
}
|
||||||
|
switch (creep.transfer(target, RESOURCE_ENERGY)) {
|
||||||
|
case OK: {
|
||||||
|
return InProgress;
|
||||||
|
}
|
||||||
|
case ERR_NOT_ENOUGH_RESOURCES: {
|
||||||
|
return Success;
|
||||||
|
}
|
||||||
|
case ERR_NOT_IN_RANGE: {
|
||||||
|
return moveTo(target);
|
||||||
|
}
|
||||||
|
default: {
|
||||||
return Fail;
|
return Fail;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
switch(creep.transfer(target, RESOURCE_ENERGY)) {
|
});
|
||||||
case OK: {
|
|
||||||
return InProgress;
|
|
||||||
}
|
|
||||||
case ERR_NOT_ENOUGH_RESOURCES: {
|
|
||||||
return Success;
|
|
||||||
}
|
|
||||||
case ERR_NOT_IN_RANGE: {
|
|
||||||
return moveTo(target);
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
return Fail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,20 @@
|
||||||
import { createAction, Fail, InProgress, Success } from "./Action";
|
import { createAction, Fail, InProgress, Success } from "./Action";
|
||||||
import { moveTo } from "./moveTo";
|
import { moveTo } from "./moveTo";
|
||||||
|
|
||||||
export const upgradeController = (controller: StructureController) => createAction('upgradeController', (creep: Creep) => {
|
export const upgradeController = (controller: StructureController) =>
|
||||||
switch(creep.upgradeController(controller)) {
|
createAction("upgradeController", (creep: Creep) => {
|
||||||
case OK: {
|
switch (creep.upgradeController(controller)) {
|
||||||
return InProgress;
|
case OK: {
|
||||||
}
|
return InProgress;
|
||||||
case ERR_NOT_ENOUGH_RESOURCES: {
|
}
|
||||||
return Success;
|
case ERR_NOT_ENOUGH_RESOURCES: {
|
||||||
}
|
return Success;
|
||||||
case ERR_NOT_IN_RANGE: {
|
}
|
||||||
return moveTo(controller);
|
case ERR_NOT_IN_RANGE: {
|
||||||
}
|
return moveTo(controller);
|
||||||
default: {
|
}
|
||||||
return Fail;
|
default: {
|
||||||
}
|
return Fail;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,27 @@
|
||||||
import { createAction, Fail, InProgress, Success } from "./Action";
|
import { createAction, Fail, InProgress, Success } from "./Action";
|
||||||
import { moveTo } from "./moveTo";
|
import { moveTo } from "./moveTo";
|
||||||
|
|
||||||
export const withdrawEnergy = (target: StructureContainer | StructureStorage | null) => createAction('transferEnergy', (creep: Creep) => {
|
export const withdrawEnergy
|
||||||
if (target == null) {
|
= (target: StructureContainer | StructureStorage | null) =>
|
||||||
|
createAction("withdrawEnergy", (creep: Creep) => {
|
||||||
|
if (target == null) {
|
||||||
return Fail;
|
return Fail;
|
||||||
}
|
}
|
||||||
if (target.store.getUsedCapacity(RESOURCE_ENERGY) === 0) {
|
if (target.store.getUsedCapacity(RESOURCE_ENERGY) === 0) {
|
||||||
return Fail;
|
return Fail;
|
||||||
}
|
}
|
||||||
switch(creep.withdraw(target, RESOURCE_ENERGY)) {
|
switch (creep.withdraw(target, RESOURCE_ENERGY)) {
|
||||||
case OK: {
|
case OK: {
|
||||||
return InProgress;
|
return InProgress;
|
||||||
}
|
}
|
||||||
case ERR_FULL: {
|
case ERR_FULL: {
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
case ERR_NOT_IN_RANGE: {
|
case ERR_NOT_IN_RANGE: {
|
||||||
return moveTo(target);
|
return moveTo(target);
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
return Fail;
|
return Fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
const BodyPartCosts = {
|
const BodyPartCosts = {
|
||||||
[MOVE]: 50,
|
[MOVE]: 50,
|
||||||
[WORK]: 100,
|
[WORK]: 100,
|
||||||
[CARRY]: 50,
|
[CARRY]: 50,
|
||||||
[ATTACK]: 80,
|
[ATTACK]: 80,
|
||||||
[RANGED_ATTACK]: 150,
|
[RANGED_ATTACK]: 150,
|
||||||
[HEAL]: 250,
|
[HEAL]: 250,
|
||||||
[CLAIM]: 600,
|
[CLAIM]: 600,
|
||||||
[TOUGH]: 10
|
[TOUGH]: 10,
|
||||||
}
|
};
|
||||||
|
|
||||||
export default BodyPartCosts;
|
export default BodyPartCosts;
|
||||||
|
|
|
||||||
|
|
@ -1,29 +1,47 @@
|
||||||
export const buildContainers = (room: Room) => {
|
export const buildContainers = (room: Room) => {
|
||||||
const controller = room.controller;
|
const controller = room.controller;
|
||||||
if (controller == null) {
|
if (controller == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (controller.level < 2) {
|
if (controller.level < 2
|
||||||
return;
|
&& room.find(FIND_MY_STRUCTURES,
|
||||||
}
|
{ filter: STRUCTURE_EXTENSION }).length > 1) {
|
||||||
const sources = room.find(FIND_SOURCES);
|
return;
|
||||||
for (const source of sources) {
|
}
|
||||||
room.createConstructionSite(source.pos.x - 2, source.pos.y, STRUCTURE_CONTAINER);
|
const sources = room.find(FIND_SOURCES);
|
||||||
room.createConstructionSite(source.pos.x + 2, source.pos.y, STRUCTURE_CONTAINER);
|
for (const source of sources) {
|
||||||
room.createConstructionSite(source.pos.x, source.pos.y - 2, STRUCTURE_CONTAINER);
|
const pos = source.pos;
|
||||||
room.createConstructionSite(source.pos.x, source.pos.y + 2, STRUCTURE_CONTAINER);
|
room.createConstructionSite(pos.x - 1, pos.y, STRUCTURE_CONTAINER);
|
||||||
}
|
room.createConstructionSite(pos.x + 1, pos.y, STRUCTURE_CONTAINER);
|
||||||
if (controller.level < 4) {
|
room.createConstructionSite(pos.x, pos.y - 1, STRUCTURE_CONTAINER);
|
||||||
return;
|
room.createConstructionSite(pos.x, pos.y + 1, STRUCTURE_CONTAINER);
|
||||||
}
|
room.createConstructionSite(pos.x - 1, pos.y + 1, STRUCTURE_CONTAINER);
|
||||||
const terrain = room.getTerrain();
|
room.createConstructionSite(pos.x + 1, pos.y - 1, STRUCTURE_CONTAINER);
|
||||||
if (terrain.get(controller.pos.x, controller.pos.y - 3) !== TERRAIN_MASK_WALL) {
|
room.createConstructionSite(pos.x - 1, pos.y - 1, STRUCTURE_CONTAINER);
|
||||||
room.createConstructionSite(controller.pos.x, controller.pos.y - 3, STRUCTURE_STORAGE);
|
room.createConstructionSite(pos.x + 1, pos.y + 1, STRUCTURE_CONTAINER);
|
||||||
} else if (terrain.get(controller.pos.x, controller.pos.y + 3) !== TERRAIN_MASK_WALL) {
|
}
|
||||||
room.createConstructionSite(controller.pos.x, controller.pos.y + 3, STRUCTURE_STORAGE);
|
if (controller.level < 4) {
|
||||||
} else if (terrain.get(controller.pos.x - 3, controller.pos.y) !== TERRAIN_MASK_WALL) {
|
return;
|
||||||
room.createConstructionSite(controller.pos.x - 3, controller.pos.y, STRUCTURE_STORAGE);
|
}
|
||||||
} else if (terrain.get(controller.pos.x + 3, controller.pos.y) !== TERRAIN_MASK_WALL) {
|
const terrain = room.getTerrain();
|
||||||
room.createConstructionSite(controller.pos.x + 3, controller.pos.y, STRUCTURE_STORAGE);
|
if (terrain.get(controller.pos.x, controller.pos.y - 3)
|
||||||
}
|
!== TERRAIN_MASK_WALL) {
|
||||||
}
|
room.createConstructionSite(
|
||||||
|
controller.pos.x, controller.pos.y - 3, STRUCTURE_STORAGE);
|
||||||
|
}
|
||||||
|
else if (terrain.get(controller.pos.x, controller.pos.y + 3)
|
||||||
|
!== TERRAIN_MASK_WALL) {
|
||||||
|
room.createConstructionSite(
|
||||||
|
controller.pos.x, controller.pos.y + 3, STRUCTURE_STORAGE);
|
||||||
|
}
|
||||||
|
else if (terrain.get(controller.pos.x - 3, controller.pos.y)
|
||||||
|
!== TERRAIN_MASK_WALL) {
|
||||||
|
room.createConstructionSite(
|
||||||
|
controller.pos.x - 3, controller.pos.y, STRUCTURE_STORAGE);
|
||||||
|
}
|
||||||
|
else if (terrain.get(controller.pos.x + 3, controller.pos.y)
|
||||||
|
!== TERRAIN_MASK_WALL) {
|
||||||
|
room.createConstructionSite(
|
||||||
|
controller.pos.x + 3, controller.pos.y, STRUCTURE_STORAGE);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,34 @@
|
||||||
const extentionsAvailable = (roomlevel: number) => {
|
const extentionsAvailable = (roomlevel: number) => {
|
||||||
return roomlevel > 2 ? roomlevel * 10 - 20 : (roomlevel - 1) * 5;
|
return roomlevel > 2 ? roomlevel * 10 - 20 : (roomlevel - 1) * 5;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const buildExtentions = (room: Room) => {
|
export const buildExtentions = (room: Room) => {
|
||||||
const spawns = room.find(FIND_MY_SPAWNS);
|
const spawns = room.find(FIND_MY_SPAWNS);
|
||||||
if (spawns.length < 1) return;
|
if (spawns.length < 1) return;
|
||||||
const spawn = spawns[0];
|
const spawn = spawns[0];
|
||||||
const exts = extentionsAvailable(room.controller?.level ?? 0);
|
const exts = extentionsAvailable(room.controller?.level ?? 0);
|
||||||
const terrain = room.getTerrain();
|
const terrain = room.getTerrain();
|
||||||
for (let x = -Math.floor(Math.sqrt(exts) / 2); x < Math.sqrt(exts) / 2; x++) {
|
const sqroffset = Math.sqrt(exts) / 2;
|
||||||
for (let y = -Math.floor(Math.sqrt(exts) / 2); y < Math.sqrt(exts) / 2; y++) {
|
for (let x = -Math.floor(sqroffset); x < sqroffset; x++) {
|
||||||
room.visual.circle(spawn.pos.x + x * 2, spawn.pos.y + y * 2);
|
for (let y = -Math.floor(sqroffset); y < sqroffset; y++) {
|
||||||
if (terrain.get(spawn.pos.x + x * 2 - 1, spawn.pos.y + y * 2 - 1) !== TERRAIN_MASK_WALL) {
|
room.visual.circle(spawn.pos.x + x * 2, spawn.pos.y + y * 2);
|
||||||
room.createConstructionSite(spawn.pos.x + x * 2 - 1, spawn.pos.y + y * 2 - 1, STRUCTURE_ROAD);
|
if (terrain.get(spawn.pos.x + x * 2 - 1, spawn.pos.y + y * 2 - 1)
|
||||||
}
|
!== TERRAIN_MASK_WALL) {
|
||||||
if (terrain.get(spawn.pos.x + x * 2, spawn.pos.y + y * 2 - 1) !== TERRAIN_MASK_WALL) {
|
room.createConstructionSite(
|
||||||
room.createConstructionSite(spawn.pos.x + x * 2, spawn.pos.y + y * 2 - 1, STRUCTURE_ROAD);
|
spawn.pos.x + x * 2 - 1, spawn.pos.y + y * 2 - 1, STRUCTURE_ROAD);
|
||||||
}
|
}
|
||||||
if (terrain.get(spawn.pos.x + x * 2 - 1, spawn.pos.y + y * 2) !== TERRAIN_MASK_WALL) {
|
if (terrain.get(spawn.pos.x + x * 2, spawn.pos.y + y * 2 - 1)
|
||||||
room.createConstructionSite(spawn.pos.x + x * 2 - 1, spawn.pos.y + y * 2, STRUCTURE_ROAD);
|
!== TERRAIN_MASK_WALL) {
|
||||||
}
|
room.createConstructionSite(
|
||||||
room.createConstructionSite(spawn.pos.x + x * 2, spawn.pos.y + y * 2, STRUCTURE_EXTENSION);
|
spawn.pos.x + x * 2, spawn.pos.y + y * 2 - 1, STRUCTURE_ROAD);
|
||||||
}
|
}
|
||||||
|
if (terrain.get(spawn.pos.x + x * 2 - 1, spawn.pos.y + y * 2)
|
||||||
|
!== TERRAIN_MASK_WALL) {
|
||||||
|
room.createConstructionSite(
|
||||||
|
spawn.pos.x + x * 2 - 1, spawn.pos.y + y * 2, STRUCTURE_ROAD);
|
||||||
|
}
|
||||||
|
room.createConstructionSite(
|
||||||
|
spawn.pos.x + x * 2, spawn.pos.y + y * 2, STRUCTURE_EXTENSION);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,27 @@
|
||||||
export const buildRoads = (room: Room) => {
|
export const buildRoads = (room: Room) => {
|
||||||
if ((room.controller?.level ?? 0) < 2) {
|
const rc = room.controller?.level ?? 0;
|
||||||
return;
|
if (rc < 2) {
|
||||||
}
|
return;
|
||||||
const sources: _HasRoomPosition[] = room.find(FIND_SOURCES);
|
}
|
||||||
const sourcesAndSpawns = sources.concat(room.find(FIND_MY_SPAWNS));
|
const sources: _HasRoomPosition[] = room.find(FIND_SOURCES);
|
||||||
const sourcesAndMinerals = sources.concat(room.find(FIND_MINERALS));
|
const sourcesAndSpawns = sources.concat(room.find(FIND_MY_SPAWNS));
|
||||||
room.visual.clear();
|
const sourcesAndMinerals = sources.concat(room.find(FIND_MINERALS));
|
||||||
for (const source of sourcesAndSpawns) {
|
room.visual.clear();
|
||||||
for (const source2 of (room.controller?.level ?? 0) > 4 ? sourcesAndMinerals : sources) {
|
for (const source of sourcesAndSpawns) {
|
||||||
const path = source.pos.findPathTo(source2, {
|
for (const source2 of rc > 4 ? sourcesAndMinerals : sources) {
|
||||||
ignoreCreeps: true,
|
const path = source.pos.findPathTo(source2, {
|
||||||
ignoreRoads: true
|
ignoreCreeps: true,
|
||||||
});
|
ignoreRoads: true,
|
||||||
for (const point of path) {
|
});
|
||||||
if ((point.x === source.pos.x && point.y === source.pos.y) || (point.x === source2.pos.x && point.y === source2.pos.y)) {
|
for (const point of path) {
|
||||||
continue;
|
if ((point.x === source.pos.x && point.y === source.pos.y)
|
||||||
}
|
|| (point.x === source2.pos.x && point.y === source2.pos.y)) {
|
||||||
room.visual.line(point.x, point.y, point.x - point.dx, point.y - point.dy);
|
continue;
|
||||||
room.createConstructionSite(point.x, point.y, STRUCTURE_ROAD);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
room.visual.line(point.x, point.y,
|
||||||
|
point.x - point.dx, point.y - point.dy);
|
||||||
|
room.createConstructionSite(point.x, point.y, STRUCTURE_ROAD);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,41 @@
|
||||||
import { Fail, runAction } from "../Actions/Action";
|
import { runAction } from "../Actions/Action";
|
||||||
import { harvestFromClosestActiveSource } from "../Actions/harvest";
|
import { harvestFromClosestActiveSource } from "../Actions/harvest";
|
||||||
import { transferEnergy } from "../Actions/transferEnergy";
|
import { transferEnergy } from "../Actions/transferEnergy";
|
||||||
import { upgradeController } from "../Actions/upgradeController";
|
import { upgradeController } from "../Actions/upgradeController";
|
||||||
|
import {
|
||||||
|
closestContainerWithEnergy,
|
||||||
|
closestExtensionToFill,
|
||||||
|
closestStorageToFill,
|
||||||
|
closestTowerToFill,
|
||||||
|
notNull,
|
||||||
|
} from "../Actions/Util";
|
||||||
import { withdrawEnergy } from "../Actions/withdrawEnergy";
|
import { withdrawEnergy } from "../Actions/withdrawEnergy";
|
||||||
import { WorkerDefinition } from "./worker";
|
import { WorkerDefinition } from "./worker";
|
||||||
|
|
||||||
|
const action = (creep: Creep, spawn: StructureSpawn) => runAction(creep,
|
||||||
|
withdrawEnergy(closestContainerWithEnergy(creep.pos)))
|
||||||
|
.or(harvestFromClosestActiveSource())
|
||||||
|
.andThen(transferEnergy(closestExtensionToFill(creep.pos)))
|
||||||
|
.or(transferEnergy(spawn))
|
||||||
|
.or(transferEnergy(closestTowerToFill(creep.pos)))
|
||||||
|
.or(transferEnergy(closestStorageToFill(creep.pos, RESOURCE_ENERGY)))
|
||||||
|
.or(notNull(creep.room.controller, upgradeController))
|
||||||
|
.repeat();
|
||||||
|
|
||||||
|
const body = (energy: number) => (
|
||||||
|
energy < 100
|
||||||
|
? []
|
||||||
|
: [WORK].concat(new Array(Math.floor((energy - 100) / 150))
|
||||||
|
.fill([MOVE, CARRY, CARRY]).reduce((x, y) => x.concat(y), []))
|
||||||
|
);
|
||||||
|
|
||||||
export const Clerk: WorkerDefinition = {
|
export const Clerk: WorkerDefinition = {
|
||||||
runAction: (creep: Creep, spawn: StructureSpawn) => runAction(creep, withdrawEnergy(creep.pos.findClosestByRange(FIND_STRUCTURES, { filter: (str: Structure) => str.structureType === STRUCTURE_CONTAINER && (str as StructureContainer).store.getUsedCapacity(RESOURCE_ENERGY) > 0 }) as StructureContainer | null))
|
runAction: action,
|
||||||
.or(harvestFromClosestActiveSource())
|
name: "clerk",
|
||||||
.andThen(transferEnergy(spawn))
|
requiredCreeps: () => 3,
|
||||||
.or(transferEnergy(creep.pos.findClosestByRange(FIND_MY_STRUCTURES, { filter: (structure: AnyOwnedStructure) => structure.structureType === STRUCTURE_EXTENSION && structure.store.getFreeCapacity(RESOURCE_ENERGY) > 0}) as StructureExtension | null))
|
bodyDefinition: body,
|
||||||
.or(transferEnergy(creep.pos.findClosestByRange(FIND_STRUCTURES, { filter: (str: Structure) => str.structureType === STRUCTURE_STORAGE && (str as StructureStorage).store.getFreeCapacity(RESOURCE_ENERGY) > 0 }) as StructureStorage | null))
|
motivationalThougts: [
|
||||||
.or(creep.room.controller ? upgradeController(creep.room.controller) : Fail)
|
"Carrying 🎒",
|
||||||
.repeat(),
|
"💗 working",
|
||||||
name: 'clerk',
|
],
|
||||||
requiredCreeps: (room: Room) => 2,
|
};
|
||||||
bodyDefinition: (energy: number) => energy < 100 ? [] : [WORK].concat(new Array(Math.floor((energy - 100) / 150)).fill([MOVE, CARRY, CARRY]).reduce((x, y) => x.concat(y), [])),
|
|
||||||
motivationalThougts: [
|
|
||||||
"Carrying 🎒",
|
|
||||||
"💗 working"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,37 @@
|
||||||
import { Fail, runAction } from "../Actions/Action";
|
import { runAction } from "../Actions/Action";
|
||||||
import { buildConstructionSite } from "../Actions/buildConstructionSite";
|
import { buildConstructionSite } from "../Actions/buildConstructionSite";
|
||||||
import { harvestFromClosestActiveSource } from "../Actions/harvest";
|
import { harvestFromClosestActiveSource } from "../Actions/harvest";
|
||||||
import { repairStructure } from "../Actions/repairStructure";
|
import { repairStructure } from "../Actions/repairStructure";
|
||||||
import { upgradeController } from "../Actions/upgradeController";
|
import { upgradeController } from "../Actions/upgradeController";
|
||||||
|
import {
|
||||||
|
closestContainerWithEnergy,
|
||||||
|
closestStorageWithResource,
|
||||||
|
notNull,
|
||||||
|
} from "../Actions/Util";
|
||||||
import { withdrawEnergy } from "../Actions/withdrawEnergy";
|
import { withdrawEnergy } from "../Actions/withdrawEnergy";
|
||||||
import { WorkerDefinition } from "./worker";
|
import { WorkerDefinition } from "./worker";
|
||||||
|
|
||||||
|
const action = (creep: Creep) => runAction(creep,
|
||||||
|
withdrawEnergy(closestStorageWithResource(creep.pos, RESOURCE_ENERGY)))
|
||||||
|
.or(withdrawEnergy(closestContainerWithEnergy(creep.pos)))
|
||||||
|
.or(harvestFromClosestActiveSource())
|
||||||
|
.andThen(buildConstructionSite())
|
||||||
|
.or(repairStructure())
|
||||||
|
.or(notNull(creep.room.controller, upgradeController))
|
||||||
|
.repeat();
|
||||||
|
|
||||||
|
const body = (energy: number) =>
|
||||||
|
new Array(Math.floor(energy / 250))
|
||||||
|
.fill([WORK, MOVE, CARRY, CARRY]).reduce((x, y) => x.concat(y), []);
|
||||||
|
|
||||||
export const Constructor: WorkerDefinition = {
|
export const Constructor: WorkerDefinition = {
|
||||||
runAction: (creep: Creep) => runAction(creep, withdrawEnergy(creep.pos.findClosestByRange(FIND_STRUCTURES, { filter: (str: Structure) => str.structureType === STRUCTURE_STORAGE && (str as StructureStorage).store.getUsedCapacity(RESOURCE_ENERGY) > 0 }) as StructureStorage | null))
|
runAction: action,
|
||||||
.or(withdrawEnergy(creep.pos.findClosestByRange(FIND_STRUCTURES, { filter: (str: Structure) => str.structureType === STRUCTURE_CONTAINER && (str as StructureContainer).store.getUsedCapacity(RESOURCE_ENERGY) > 0 }) as StructureContainer | null))
|
name: "constructor",
|
||||||
.or(harvestFromClosestActiveSource())
|
requiredCreeps: (room: Room) =>
|
||||||
.andThen(buildConstructionSite())
|
room.find(FIND_CONSTRUCTION_SITES).length > 10 ? 2 : 1,
|
||||||
.or(repairStructure())
|
bodyDefinition: body,
|
||||||
.or(creep.room.controller ? upgradeController(creep.room.controller) : Fail)
|
motivationalThougts: [
|
||||||
.repeat(),
|
"I 💗 making",
|
||||||
name: 'constructor',
|
"Fixin' 🔧",
|
||||||
requiredCreeps: (room: Room) => 1,
|
],
|
||||||
bodyDefinition: (energy: number) => new Array(Math.floor(energy / 250)).fill([WORK, MOVE, CARRY, CARRY]).reduce((x, y) => x.concat(y), []),
|
};
|
||||||
motivationalThougts: [
|
|
||||||
"I 💗 making",
|
|
||||||
"Fixin' 🔧"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,31 @@
|
||||||
import { Fail, runAction } from "../Actions/Action";
|
import { runAction } from "../Actions/Action";
|
||||||
import { harvestFromClosestActiveSource } from "../Actions/harvest";
|
import { harvestFromClosestActiveSource } from "../Actions/harvest";
|
||||||
import { transferEnergy } from "../Actions/transferEnergy";
|
import { transferEnergy } from "../Actions/transferEnergy";
|
||||||
|
import { closestContainerToFill } from "../Actions/Util";
|
||||||
import { WorkerDefinition } from "./worker";
|
import { WorkerDefinition } from "./worker";
|
||||||
|
|
||||||
|
const action = (creep: Creep) => runAction(creep,
|
||||||
|
harvestFromClosestActiveSource())
|
||||||
|
.andThen(transferEnergy(closestContainerToFill(creep.pos)))
|
||||||
|
.repeat();
|
||||||
|
|
||||||
|
const body = (energy: number) => (
|
||||||
|
energy < 300
|
||||||
|
? []
|
||||||
|
: ([WORK, WORK, MOVE, CARRY]
|
||||||
|
.concat(new Array(Math.floor((energy - 300) / 100)).fill(WORK)))
|
||||||
|
);
|
||||||
|
|
||||||
export const Miner: WorkerDefinition = {
|
export const Miner: WorkerDefinition = {
|
||||||
runAction: (creep: Creep) => runAction(creep, harvestFromClosestActiveSource())
|
runAction: action,
|
||||||
.andThen(transferEnergy(creep.pos.findClosestByRange(FIND_STRUCTURES, { filter: (str: Structure) => str.structureType === STRUCTURE_CONTAINER && (str as StructureContainer).store.getFreeCapacity(RESOURCE_ENERGY) > 0}) as StructureContainer | null))
|
name: "miner",
|
||||||
.repeat(),
|
requiredCreeps: (room: Room) =>
|
||||||
name: 'miner',
|
room.find(FIND_STRUCTURES,
|
||||||
requiredCreeps: (room: Room) => room.find(FIND_STRUCTURES, { filter: { structureType: STRUCTURE_CONTAINER }}).length > 0 ? 4 : 0,
|
{ filter: { structureType: STRUCTURE_CONTAINER } }).length > 0
|
||||||
bodyDefinition: (energy: number) => energy < 300 ? [] : [WORK, WORK, MOVE, CARRY].concat(new Array(Math.floor((energy - 300) / 100)).fill(WORK)),
|
? 4
|
||||||
motivationalThougts: [
|
: 0,
|
||||||
"RocknStone"
|
bodyDefinition: body,
|
||||||
]
|
motivationalThougts: [
|
||||||
}
|
"RocknStone",
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,31 @@
|
||||||
import { Fail, runAction } from "../Actions/Action";
|
import { runAction } from "../Actions/Action";
|
||||||
import { harvestFromClosestActiveSource } from "../Actions/harvest";
|
import { harvestFromClosestActiveSource } from "../Actions/harvest";
|
||||||
import { transferEnergy } from "../Actions/transferEnergy";
|
|
||||||
import { upgradeController } from "../Actions/upgradeController";
|
import { upgradeController } from "../Actions/upgradeController";
|
||||||
|
import {
|
||||||
|
closestContainerWithEnergy,
|
||||||
|
closestStorageWithResource,
|
||||||
|
notNull,
|
||||||
|
} from "../Actions/Util";
|
||||||
import { withdrawEnergy } from "../Actions/withdrawEnergy";
|
import { withdrawEnergy } from "../Actions/withdrawEnergy";
|
||||||
import { WorkerDefinition } from "./worker";
|
import { WorkerDefinition } from "./worker";
|
||||||
|
|
||||||
|
const action = (creep: Creep) => runAction(creep,
|
||||||
|
withdrawEnergy(closestStorageWithResource(creep.pos, RESOURCE_ENERGY)))
|
||||||
|
.or(withdrawEnergy(closestContainerWithEnergy(creep.pos)))
|
||||||
|
.or(harvestFromClosestActiveSource())
|
||||||
|
.andThen(notNull(creep.room.controller, upgradeController))
|
||||||
|
.repeat();
|
||||||
|
|
||||||
|
const body = (energy: number) =>
|
||||||
|
new Array(Math.floor(energy / 300))
|
||||||
|
.fill([WORK, WORK, MOVE, CARRY]).reduce((x, y) => x.concat(y), []);
|
||||||
|
|
||||||
export const Upgrader: WorkerDefinition = {
|
export const Upgrader: WorkerDefinition = {
|
||||||
runAction: (creep: Creep, spawn: StructureSpawn) => runAction(creep, withdrawEnergy(creep.pos.findClosestByRange(FIND_STRUCTURES, { filter: (str: Structure) => str.structureType === STRUCTURE_STORAGE && (str as StructureStorage).store.getUsedCapacity(RESOURCE_ENERGY) > 0 }) as StructureStorage | null))
|
runAction: action,
|
||||||
.or(withdrawEnergy(creep.pos.findClosestByRange(FIND_STRUCTURES, { filter: (str: Structure) => str.structureType === STRUCTURE_CONTAINER && (str as StructureContainer).store.getUsedCapacity(RESOURCE_ENERGY) > 0 }) as StructureContainer | null))
|
name: "upgrader",
|
||||||
.or(harvestFromClosestActiveSource())
|
requiredCreeps: () => 1,
|
||||||
.andThen(creep.room.controller ? upgradeController(creep.room.controller) : Fail)
|
bodyDefinition: body,
|
||||||
.repeat(),
|
motivationalThougts: [
|
||||||
name: 'upgrader',
|
"🏳️⚧️",
|
||||||
requiredCreeps: (room: Room) => 1,
|
],
|
||||||
bodyDefinition: (energy: number) => new Array(Math.floor(energy / 300)).fill([WORK, WORK, MOVE, CARRY]).reduce((x, y) => x.concat(y), []),
|
};
|
||||||
motivationalThougts: [
|
|
||||||
'🏳️⚧️'
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
export { Clerk } from "./Clerk";
|
export { Clerk } from "./Clerk";
|
||||||
export { Constructor } from "./Constructor";
|
export { Constructor } from "./Constructor";
|
||||||
export { Miner } from "./Miner";
|
export { Miner } from "./Miner";
|
||||||
export { Upgrader } from "./Upgrader";
|
export { Upgrader } from "./Upgrader";
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,16 @@
|
||||||
import BodyPartCosts from '../Constants/BodyPartCosts';
|
import BodyPartCosts from "../Constants/BodyPartCosts";
|
||||||
import * as Workers from './index';
|
import * as Workers from "./index";
|
||||||
|
|
||||||
describe('Test Creep Workers', () => {
|
describe("Test Creep Workers", () => {
|
||||||
console.log(Workers.Clerk)
|
console.log(Workers.Clerk);
|
||||||
for (const [moduleName, worker] of Object.entries(Workers)) {
|
for (const [moduleName, worker] of Object.entries(Workers)) {
|
||||||
test(`${moduleName}: Body parts cost calculation is correct`, () => {
|
test(`${moduleName}: Body parts cost calculation is correct`, () => {
|
||||||
for (let cost = 0; cost < 1500; cost++) {
|
for (let cost = 0; cost < 1500; cost++) {
|
||||||
expect(worker.bodyDefinition(cost).map((x) => BodyPartCosts[x]).reduce((x, y) => x + y, 0)).toBeLessThanOrEqual(cost);
|
expect(
|
||||||
}
|
worker.bodyDefinition(cost)
|
||||||
});
|
.map(x => BodyPartCosts[x]).reduce((x, y) => x + y, 0),
|
||||||
}
|
).toBeLessThanOrEqual(cost);
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,35 +1,45 @@
|
||||||
export interface WorkerDefinition {
|
export interface WorkerDefinition {
|
||||||
runAction: (creep: Creep, spawn: StructureSpawn) => void,
|
runAction: (creep: Creep, spawn: StructureSpawn) => void;
|
||||||
name: string,
|
name: string;
|
||||||
requiredCreeps: (room: Room) => number,
|
requiredCreeps: (room: Room) => number;
|
||||||
bodyDefinition: (energy: number) => BodyPartConstant[],
|
bodyDefinition: (energy: number) => BodyPartConstant[];
|
||||||
motivationalThougts?: string[]
|
motivationalThougts?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export const spawnWorkers = (spawn: StructureSpawn, workers: WorkerDefinition[]): void => {
|
export const spawnWorkers
|
||||||
|
= (spawn: StructureSpawn, workers: WorkerDefinition[]): void => {
|
||||||
for (const worker of workers) {
|
for (const worker of workers) {
|
||||||
for (let i = 0; i < worker.requiredCreeps(spawn.room); i++) {
|
for (let i = 0; i < worker.requiredCreeps(spawn.room); i++) {
|
||||||
const ret = spawn.spawnCreep(worker.bodyDefinition(
|
const ret = spawn.spawnCreep(worker.bodyDefinition(
|
||||||
spawn.store.getCapacity(RESOURCE_ENERGY) + (spawn.room.find(FIND_MY_STRUCTURES, { filter: { structureType: STRUCTURE_EXTENSION }}).length * (Object.keys(Game.creeps).length < 2 ? (25 * Object.keys(Game.creeps).length) : 50))), worker.name + i.toString());
|
spawn.store.getCapacity(RESOURCE_ENERGY)
|
||||||
if (ret === OK || ret === ERR_NOT_ENOUGH_ENERGY) {
|
+ (spawn.room.find(FIND_MY_STRUCTURES,
|
||||||
return;
|
{ filter: { structureType: STRUCTURE_EXTENSION } }).length
|
||||||
}
|
* (Object.keys(Game.creeps).length < 2
|
||||||
|
? (25 * Object.keys(Game.creeps).length)
|
||||||
|
: 50))), worker.name + i.toString());
|
||||||
|
if (ret === OK || ret === ERR_NOT_ENOUGH_ENERGY) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const runWorkers = (spawn: StructureSpawn, workers: WorkerDefinition[]): void => {
|
export const runWorkers
|
||||||
|
= (spawn: StructureSpawn, workers: WorkerDefinition[]): void => {
|
||||||
for (const worker of workers) {
|
for (const worker of workers) {
|
||||||
for (const creep of Object.values(Game.creeps)) {
|
for (const creep of Object.values(Game.creeps)) {
|
||||||
if (creep.spawning) {
|
if (creep.spawning) {
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
if (creep.name.startsWith(worker.name)) {
|
|
||||||
worker.runAction(creep, spawn);
|
|
||||||
if (worker.motivationalThougts != null && Math.random() < 0.1) {
|
|
||||||
creep.say(worker.motivationalThougts[Math.floor(worker.motivationalThougts.length * Math.random())], true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if (creep.name.startsWith(worker.name)) {
|
||||||
|
worker.runAction(creep, spawn);
|
||||||
|
if (worker.motivationalThougts != null && Math.random() < 0.1) {
|
||||||
|
creep.say(
|
||||||
|
worker.motivationalThougts[
|
||||||
|
Math.floor(worker.motivationalThougts.length * Math.random())
|
||||||
|
], true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
76
src/index.ts
76
src/index.ts
|
|
@ -1,8 +1,3 @@
|
||||||
import { runAction } from "./Actions/Action";
|
|
||||||
import { buildConstructionSite } from "./Actions/buildConstructionSite";
|
|
||||||
import { harvestFromClosestActiveSource } from "./Actions/harvest";
|
|
||||||
import { transferEnergy } from "./Actions/transferEnergy";
|
|
||||||
import { upgradeController } from "./Actions/upgradeController";
|
|
||||||
import { buildContainers } from "./RoomPlanner/Blueprints/Containers";
|
import { buildContainers } from "./RoomPlanner/Blueprints/Containers";
|
||||||
import { buildExtentions } from "./RoomPlanner/Blueprints/Extensions";
|
import { buildExtentions } from "./RoomPlanner/Blueprints/Extensions";
|
||||||
import { buildRoads } from "./RoomPlanner/Blueprints/Roads";
|
import { buildRoads } from "./RoomPlanner/Blueprints/Roads";
|
||||||
|
|
@ -12,25 +7,54 @@ import { Miner } from "./Workers/Miner";
|
||||||
import { Upgrader } from "./Workers/Upgrader";
|
import { Upgrader } from "./Workers/Upgrader";
|
||||||
import { runWorkers, spawnWorkers } from "./Workers/worker";
|
import { runWorkers, spawnWorkers } from "./Workers/worker";
|
||||||
|
|
||||||
|
const runTowers = (spawn: StructureSpawn) => {
|
||||||
|
const towers: StructureTower[] = spawn.room.find(FIND_MY_STRUCTURES,
|
||||||
|
{ filter: s => s.structureType === STRUCTURE_TOWER });
|
||||||
|
for (const tower of towers) {
|
||||||
|
const enemy = tower.pos.findClosestByRange(FIND_HOSTILE_CREEPS);
|
||||||
|
if (enemy != null) {
|
||||||
|
if (tower.attack(enemy) === OK) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const creep = tower.pos.findClosestByRange(FIND_MY_CREEPS, {
|
||||||
|
filter: (creep: Creep) => creep.hits < creep.hitsMax,
|
||||||
|
});
|
||||||
|
if (creep != null) {
|
||||||
|
if (tower.heal(creep) === OK) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const str = tower.pos.findClosestByRange(FIND_STRUCTURES, {
|
||||||
|
filter: s => s.hits < s.hitsMax * 0.8,
|
||||||
|
});
|
||||||
|
console.log(str);
|
||||||
|
if (str != null) {
|
||||||
|
console.log(tower.repair(str));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
export function loop() {
|
export function loop() {
|
||||||
const spawn = Game.spawns.Spawn1;
|
const spawn = Game.spawns.Spawn1;
|
||||||
const controller = spawn.room.controller;
|
const controller = spawn.room.controller;
|
||||||
if (!controller) {
|
if (!controller) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const workerTypes = [Clerk, Upgrader, Miner, Constructor];
|
const workerTypes = [Clerk, Upgrader, Miner, Constructor];
|
||||||
spawnWorkers(spawn, workerTypes);
|
spawnWorkers(spawn, workerTypes);
|
||||||
runWorkers(spawn, workerTypes);
|
runWorkers(spawn, workerTypes);
|
||||||
if (Game.time % 100 === 0) {
|
runTowers(spawn);
|
||||||
buildRoads(spawn.room);
|
if (Game.time % 100 === 0) {
|
||||||
}
|
buildRoads(spawn.room);
|
||||||
if (Game.time % 100 === 50) {
|
}
|
||||||
buildExtentions(spawn.room);
|
if (Game.time % 100 === 50) {
|
||||||
}
|
buildExtentions(spawn.room);
|
||||||
if (Game.time % 100 === 25) {
|
}
|
||||||
buildContainers(spawn.room);
|
if (Game.time % 100 === 25) {
|
||||||
}
|
buildContainers(spawn.room);
|
||||||
if (Game.cpu.bucket === 10000) {
|
}
|
||||||
Game.cpu.generatePixel();
|
if (Game.cpu.bucket === 10000) {
|
||||||
}
|
Game.cpu.generatePixel();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ const fs = require('fs');
|
||||||
var https = require('https');
|
var https = require('https');
|
||||||
|
|
||||||
var data = {
|
var data = {
|
||||||
branch: 'world',
|
branch: 'hurricane',
|
||||||
modules: {
|
modules: {
|
||||||
main: fs.readFileSync('./dist/screeps.js', 'utf-8').toString(),
|
main: fs.readFileSync('./dist/screeps.js', 'utf-8').toString(),
|
||||||
}
|
}
|
||||||
|
|
@ -22,4 +22,4 @@ var req = https.request({
|
||||||
});
|
});
|
||||||
|
|
||||||
req.write(JSON.stringify(data));
|
req.write(JSON.stringify(data));
|
||||||
req.end();
|
req.end();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue