@supalosa/chronodivide-bot 0.5.3 → 0.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.template +4 -4
- package/.github/workflows/npm-publish.yml +24 -0
- package/README.md +108 -97
- package/dist/bot/bot.js +105 -105
- package/dist/bot/bot.js.map +1 -1
- package/dist/bot/logic/awareness.js +136 -136
- package/dist/bot/logic/building/antiAirStaticDefence.js +42 -42
- package/dist/bot/logic/building/antiGroundStaticDefence.js +34 -30
- package/dist/bot/logic/building/antiGroundStaticDefence.js.map +1 -1
- package/dist/bot/logic/building/{ArtilleryUnit.js → artilleryUnit.js} +18 -18
- package/dist/bot/logic/building/basicAirUnit.js +19 -19
- package/dist/bot/logic/building/basicBuilding.js +26 -26
- package/dist/bot/logic/building/basicGroundUnit.js +19 -19
- package/dist/bot/logic/building/buildingRules.js +175 -174
- package/dist/bot/logic/building/buildingRules.js.map +1 -1
- package/dist/bot/logic/building/common.js +19 -18
- package/dist/bot/logic/building/common.js.map +1 -1
- package/dist/bot/logic/building/harvester.js +16 -16
- package/dist/bot/logic/building/powerPlant.js +20 -20
- package/dist/bot/logic/building/queueController.js +183 -183
- package/dist/bot/logic/building/resourceCollectionBuilding.js +36 -36
- package/dist/bot/logic/common/scout.js +126 -126
- package/dist/bot/logic/common/utils.js +95 -85
- package/dist/bot/logic/common/utils.js.map +1 -1
- package/dist/bot/logic/composition/alliedCompositions.js +12 -12
- package/dist/bot/logic/composition/common.js +1 -1
- package/dist/bot/logic/composition/sovietCompositions.js +12 -12
- package/dist/bot/logic/map/map.js +44 -44
- package/dist/bot/logic/map/sector.js +137 -137
- package/dist/bot/logic/mission/actionBatcher.js +91 -91
- package/dist/bot/logic/mission/mission.js +122 -122
- package/dist/bot/logic/mission/missionController.js +321 -321
- package/dist/bot/logic/mission/missionFactories.js +12 -12
- package/dist/bot/logic/mission/missions/attackMission.js +214 -214
- package/dist/bot/logic/mission/missions/defenceMission.js +82 -82
- package/dist/bot/logic/mission/missions/engineerMission.js +63 -63
- package/dist/bot/logic/mission/missions/expansionMission.js +60 -60
- package/dist/bot/logic/mission/missions/retreatMission.js +33 -33
- package/dist/bot/logic/mission/missions/scoutingMission.js +133 -133
- package/dist/bot/logic/mission/missions/squads/combatSquad.js +115 -115
- package/dist/bot/logic/mission/missions/squads/common.js +57 -57
- package/dist/bot/logic/mission/missions/squads/squad.js +1 -1
- package/dist/bot/logic/threat/threat.js +22 -22
- package/dist/bot/logic/threat/threatCalculator.js +73 -73
- package/dist/exampleBot.js +100 -112
- package/dist/exampleBot.js.map +1 -1
- package/package.json +32 -29
- package/src/bot/bot.ts +161 -161
- package/src/bot/logic/awareness.ts +245 -245
- package/src/bot/logic/building/antiAirStaticDefence.ts +64 -64
- package/src/bot/logic/building/antiGroundStaticDefence.ts +55 -51
- package/src/bot/logic/building/artilleryUnit.ts +39 -39
- package/src/bot/logic/building/basicAirUnit.ts +39 -39
- package/src/bot/logic/building/basicBuilding.ts +49 -49
- package/src/bot/logic/building/basicGroundUnit.ts +39 -39
- package/src/bot/logic/building/buildingRules.ts +250 -247
- package/src/bot/logic/building/common.ts +21 -23
- package/src/bot/logic/building/harvester.ts +31 -31
- package/src/bot/logic/building/powerPlant.ts +32 -32
- package/src/bot/logic/building/queueController.ts +297 -297
- package/src/bot/logic/building/resourceCollectionBuilding.ts +52 -52
- package/src/bot/logic/common/scout.ts +183 -183
- package/src/bot/logic/common/utils.ts +120 -112
- package/src/bot/logic/composition/alliedCompositions.ts +22 -22
- package/src/bot/logic/composition/common.ts +3 -3
- package/src/bot/logic/composition/sovietCompositions.ts +21 -21
- package/src/bot/logic/map/map.ts +66 -66
- package/src/bot/logic/map/sector.ts +174 -174
- package/src/bot/logic/mission/actionBatcher.ts +124 -124
- package/src/bot/logic/mission/mission.ts +232 -232
- package/src/bot/logic/mission/missionController.ts +413 -413
- package/src/bot/logic/mission/missionFactories.ts +51 -51
- package/src/bot/logic/mission/missions/attackMission.ts +336 -336
- package/src/bot/logic/mission/missions/defenceMission.ts +151 -151
- package/src/bot/logic/mission/missions/engineerMission.ts +113 -113
- package/src/bot/logic/mission/missions/expansionMission.ts +104 -104
- package/src/bot/logic/mission/missions/retreatMission.ts +54 -54
- package/src/bot/logic/mission/missions/scoutingMission.ts +186 -186
- package/src/bot/logic/mission/missions/squads/combatSquad.ts +160 -160
- package/src/bot/logic/mission/missions/squads/common.ts +63 -63
- package/src/bot/logic/mission/missions/squads/squad.ts +19 -19
- package/src/bot/logic/threat/threatCalculator.ts +100 -100
- package/src/exampleBot.ts +111 -124
- package/tsconfig.json +73 -73
- package/dist/bot/logic/building/building.js +0 -82
- package/dist/bot/logic/building/massedAntiGroundUnit.js +0 -20
- package/dist/bot/logic/building/queues.js +0 -19
- package/dist/bot/logic/knowledge.js +0 -1
- package/dist/bot/logic/mission/basicMission.js +0 -26
- package/dist/bot/logic/mission/behaviours/combatSquad.js +0 -124
- package/dist/bot/logic/mission/behaviours/combatSquad.js.map +0 -1
- package/dist/bot/logic/mission/behaviours/common.js +0 -56
- package/dist/bot/logic/mission/behaviours/common.js.map +0 -1
- package/dist/bot/logic/mission/behaviours/engineerSquad.js +0 -39
- package/dist/bot/logic/mission/behaviours/engineerSquad.js.map +0 -1
- package/dist/bot/logic/mission/behaviours/expansionSquad.js +0 -46
- package/dist/bot/logic/mission/behaviours/expansionSquad.js.map +0 -1
- package/dist/bot/logic/mission/behaviours/retreatSquad.js +0 -31
- package/dist/bot/logic/mission/behaviours/retreatSquad.js.map +0 -1
- package/dist/bot/logic/mission/behaviours/scoutingSquad.js +0 -94
- package/dist/bot/logic/mission/behaviours/scoutingSquad.js.map +0 -1
- package/dist/bot/logic/mission/expansionMission.js +0 -32
- package/dist/bot/logic/mission/missions/basicMission.js +0 -13
- package/dist/bot/logic/mission/missions/basicMission.js.map +0 -1
- package/dist/bot/logic/mission/missions/missionBehaviour.js +0 -2
- package/dist/bot/logic/mission/missions/missionBehaviour.js.map +0 -1
- package/dist/bot/logic/mission/missions/oneTimeMission.js +0 -27
- package/dist/bot/logic/mission/missions/oneTimeMission.js.map +0 -1
- package/dist/bot/logic/squad/behaviours/actionBatcher.js +0 -36
- package/dist/bot/logic/squad/behaviours/actionBatcher.js.map +0 -1
- package/dist/bot/logic/squad/behaviours/attackSquad.js +0 -82
- package/dist/bot/logic/squad/behaviours/combatSquad.js +0 -106
- package/dist/bot/logic/squad/behaviours/combatSquad.js.map +0 -1
- package/dist/bot/logic/squad/behaviours/common.js +0 -55
- package/dist/bot/logic/squad/behaviours/common.js.map +0 -1
- package/dist/bot/logic/squad/behaviours/defenceSquad.js +0 -48
- package/dist/bot/logic/squad/behaviours/engineerSquad.js +0 -38
- package/dist/bot/logic/squad/behaviours/engineerSquad.js.map +0 -1
- package/dist/bot/logic/squad/behaviours/expansionSquad.js +0 -45
- package/dist/bot/logic/squad/behaviours/expansionSquad.js.map +0 -1
- package/dist/bot/logic/squad/behaviours/retreatSquad.js +0 -31
- package/dist/bot/logic/squad/behaviours/retreatSquad.js.map +0 -1
- package/dist/bot/logic/squad/behaviours/scoutingSquad.js +0 -93
- package/dist/bot/logic/squad/behaviours/scoutingSquad.js.map +0 -1
- package/dist/bot/logic/squad/behaviours/squadExpansion.js +0 -31
- package/dist/bot/logic/squad/behaviours/squadScouters.js +0 -8
- package/dist/bot/logic/squad/squad.js +0 -126
- package/dist/bot/logic/squad/squad.js.map +0 -1
- package/dist/bot/logic/squad/squadBehaviour.js +0 -6
- package/dist/bot/logic/squad/squadBehaviour.js.map +0 -1
- package/dist/bot/logic/squad/squadBehaviours.js +0 -7
- package/dist/bot/logic/squad/squadBehaviours.js.map +0 -1
- package/dist/bot/logic/squad/squadController.js +0 -215
- package/dist/bot/logic/squad/squadController.js.map +0 -1
|
@@ -1,123 +1,123 @@
|
|
|
1
|
-
import { Vector2 } from "@chronodivide/game-api";
|
|
2
|
-
import { getDistanceBetweenTileAndPoint } from "../map/map.js";
|
|
3
|
-
const calculateCenterOfMass = (unitTiles) => {
|
|
4
|
-
if (unitTiles.length === 0) {
|
|
5
|
-
return null;
|
|
6
|
-
}
|
|
7
|
-
// TODO: use median here
|
|
8
|
-
const sums = unitTiles.reduce(({ x, y }, tile) => {
|
|
9
|
-
return {
|
|
10
|
-
x: x + (tile?.rx || 0),
|
|
11
|
-
y: y + (tile?.ry || 0),
|
|
12
|
-
};
|
|
13
|
-
}, { x: 0, y: 0 });
|
|
14
|
-
const centerOfMass = new Vector2(Math.round(sums.x / unitTiles.length), Math.round(sums.y / unitTiles.length));
|
|
15
|
-
// max distance of units to the center of mass
|
|
16
|
-
const distances = unitTiles.map((tile) => getDistanceBetweenTileAndPoint(tile, centerOfMass));
|
|
17
|
-
const maxDistance = Math.max(...distances);
|
|
18
|
-
return { centerOfMass, maxDistance };
|
|
19
|
-
};
|
|
20
|
-
// AI starts Missions based on heuristics.
|
|
21
|
-
export class Mission {
|
|
22
|
-
constructor(uniqueName, logger) {
|
|
23
|
-
this.uniqueName = uniqueName;
|
|
24
|
-
this.logger = logger;
|
|
25
|
-
this.active = true;
|
|
26
|
-
this.unitIds = [];
|
|
27
|
-
this.centerOfMass = null;
|
|
28
|
-
this.maxDistanceToCenterOfMass = null;
|
|
29
|
-
this.onFinish = () => { };
|
|
30
|
-
}
|
|
31
|
-
// TODO call this
|
|
32
|
-
updateCenterOfMass(gameApi) {
|
|
33
|
-
const movableUnitTiles = this.unitIds
|
|
34
|
-
.map((unitId) => gameApi.getUnitData(unitId))
|
|
35
|
-
.filter((unit) => unit?.canMove)
|
|
36
|
-
.map((unit) => unit?.tile)
|
|
37
|
-
.filter((tile) => !!tile);
|
|
38
|
-
const tileMetrics = calculateCenterOfMass(movableUnitTiles);
|
|
39
|
-
if (tileMetrics) {
|
|
40
|
-
this.centerOfMass = tileMetrics.centerOfMass;
|
|
41
|
-
this.maxDistanceToCenterOfMass = tileMetrics.maxDistance;
|
|
42
|
-
}
|
|
43
|
-
else {
|
|
44
|
-
this.centerOfMass = null;
|
|
45
|
-
this.maxDistanceToCenterOfMass = null;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
onAiUpdate(gameApi, actionsApi, playerData, matchAwareness, actionBatcher) {
|
|
49
|
-
this.updateCenterOfMass(gameApi);
|
|
50
|
-
return this._onAiUpdate(gameApi, actionsApi, playerData, matchAwareness, actionBatcher);
|
|
51
|
-
}
|
|
52
|
-
isActive() {
|
|
53
|
-
return this.active;
|
|
54
|
-
}
|
|
55
|
-
getUnitIds() {
|
|
56
|
-
return this.unitIds;
|
|
57
|
-
}
|
|
58
|
-
removeUnit(unitIdToRemove) {
|
|
59
|
-
this.unitIds = this.unitIds.filter((unitId) => unitId != unitIdToRemove);
|
|
60
|
-
}
|
|
61
|
-
addUnit(unitIdToAdd) {
|
|
62
|
-
this.unitIds.push(unitIdToAdd);
|
|
63
|
-
}
|
|
64
|
-
getUnits(gameApi) {
|
|
65
|
-
return this.unitIds
|
|
66
|
-
.map((unitId) => gameApi.getUnitData(unitId))
|
|
67
|
-
.filter((unit) => unit != null)
|
|
68
|
-
.map((unit) => unit);
|
|
69
|
-
}
|
|
70
|
-
getUnitsOfTypes(gameApi, ...names) {
|
|
71
|
-
return this.unitIds
|
|
72
|
-
.map((unitId) => gameApi.getUnitData(unitId))
|
|
73
|
-
.filter((unit) => !!unit && names.includes(unit.name))
|
|
74
|
-
.map((unit) => unit);
|
|
75
|
-
}
|
|
76
|
-
getUnitsMatching(gameApi, filter) {
|
|
77
|
-
return this.unitIds
|
|
78
|
-
.map((unitId) => gameApi.getUnitData(unitId))
|
|
79
|
-
.filter((unit) => !!unit && filter(unit))
|
|
80
|
-
.map((unit) => unit);
|
|
81
|
-
}
|
|
82
|
-
getCenterOfMass() {
|
|
83
|
-
return this.centerOfMass;
|
|
84
|
-
}
|
|
85
|
-
getMaxDistanceToCenterOfMass() {
|
|
86
|
-
return this.maxDistanceToCenterOfMass;
|
|
87
|
-
}
|
|
88
|
-
getUniqueName() {
|
|
89
|
-
return this.uniqueName;
|
|
90
|
-
}
|
|
91
|
-
// Don't call this from the mission itself
|
|
92
|
-
endMission(reason) {
|
|
93
|
-
this.onFinish(this.unitIds, reason);
|
|
94
|
-
this.active = false;
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Declare a callback that is executed when the mission is disbanded for whatever reason.
|
|
98
|
-
*/
|
|
99
|
-
then(onFinish) {
|
|
100
|
-
this.onFinish = onFinish;
|
|
101
|
-
return this;
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* Determines whether units can be stolen from this mission by other missions with higher priority.
|
|
105
|
-
*/
|
|
106
|
-
isUnitsLocked() {
|
|
107
|
-
return true;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
export const noop = () => ({
|
|
111
|
-
type: "noop",
|
|
112
|
-
});
|
|
113
|
-
export const disbandMission = (reason) => ({ type: "disband", reason });
|
|
114
|
-
export const isDisbandMission = (a) => a.action.type === "disband";
|
|
115
|
-
export const requestUnits = (unitNames, priority) => ({ type: "request", unitNames, priority });
|
|
116
|
-
export const isRequestUnits = (a) => a.action.type === "request";
|
|
117
|
-
export const requestSpecificUnits = (unitIds, priority) => ({ type: "requestSpecific", unitIds, priority });
|
|
118
|
-
export const isRequestSpecificUnits = (a) => a.action.type === "requestSpecific";
|
|
119
|
-
export const grabCombatants = (point, radius) => ({ type: "requestCombatants", point, radius });
|
|
120
|
-
export const isGrabCombatants = (a) => a.action.type === "requestCombatants";
|
|
121
|
-
export const releaseUnits = (unitIds) => ({ type: "releaseUnits", unitIds });
|
|
122
|
-
export const isReleaseUnits = (a) => a.action.type === "releaseUnits";
|
|
1
|
+
import { Vector2 } from "@chronodivide/game-api";
|
|
2
|
+
import { getDistanceBetweenTileAndPoint } from "../map/map.js";
|
|
3
|
+
const calculateCenterOfMass = (unitTiles) => {
|
|
4
|
+
if (unitTiles.length === 0) {
|
|
5
|
+
return null;
|
|
6
|
+
}
|
|
7
|
+
// TODO: use median here
|
|
8
|
+
const sums = unitTiles.reduce(({ x, y }, tile) => {
|
|
9
|
+
return {
|
|
10
|
+
x: x + (tile?.rx || 0),
|
|
11
|
+
y: y + (tile?.ry || 0),
|
|
12
|
+
};
|
|
13
|
+
}, { x: 0, y: 0 });
|
|
14
|
+
const centerOfMass = new Vector2(Math.round(sums.x / unitTiles.length), Math.round(sums.y / unitTiles.length));
|
|
15
|
+
// max distance of units to the center of mass
|
|
16
|
+
const distances = unitTiles.map((tile) => getDistanceBetweenTileAndPoint(tile, centerOfMass));
|
|
17
|
+
const maxDistance = Math.max(...distances);
|
|
18
|
+
return { centerOfMass, maxDistance };
|
|
19
|
+
};
|
|
20
|
+
// AI starts Missions based on heuristics.
|
|
21
|
+
export class Mission {
|
|
22
|
+
constructor(uniqueName, logger) {
|
|
23
|
+
this.uniqueName = uniqueName;
|
|
24
|
+
this.logger = logger;
|
|
25
|
+
this.active = true;
|
|
26
|
+
this.unitIds = [];
|
|
27
|
+
this.centerOfMass = null;
|
|
28
|
+
this.maxDistanceToCenterOfMass = null;
|
|
29
|
+
this.onFinish = () => { };
|
|
30
|
+
}
|
|
31
|
+
// TODO call this
|
|
32
|
+
updateCenterOfMass(gameApi) {
|
|
33
|
+
const movableUnitTiles = this.unitIds
|
|
34
|
+
.map((unitId) => gameApi.getUnitData(unitId))
|
|
35
|
+
.filter((unit) => unit?.canMove)
|
|
36
|
+
.map((unit) => unit?.tile)
|
|
37
|
+
.filter((tile) => !!tile);
|
|
38
|
+
const tileMetrics = calculateCenterOfMass(movableUnitTiles);
|
|
39
|
+
if (tileMetrics) {
|
|
40
|
+
this.centerOfMass = tileMetrics.centerOfMass;
|
|
41
|
+
this.maxDistanceToCenterOfMass = tileMetrics.maxDistance;
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
this.centerOfMass = null;
|
|
45
|
+
this.maxDistanceToCenterOfMass = null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
onAiUpdate(gameApi, actionsApi, playerData, matchAwareness, actionBatcher) {
|
|
49
|
+
this.updateCenterOfMass(gameApi);
|
|
50
|
+
return this._onAiUpdate(gameApi, actionsApi, playerData, matchAwareness, actionBatcher);
|
|
51
|
+
}
|
|
52
|
+
isActive() {
|
|
53
|
+
return this.active;
|
|
54
|
+
}
|
|
55
|
+
getUnitIds() {
|
|
56
|
+
return this.unitIds;
|
|
57
|
+
}
|
|
58
|
+
removeUnit(unitIdToRemove) {
|
|
59
|
+
this.unitIds = this.unitIds.filter((unitId) => unitId != unitIdToRemove);
|
|
60
|
+
}
|
|
61
|
+
addUnit(unitIdToAdd) {
|
|
62
|
+
this.unitIds.push(unitIdToAdd);
|
|
63
|
+
}
|
|
64
|
+
getUnits(gameApi) {
|
|
65
|
+
return this.unitIds
|
|
66
|
+
.map((unitId) => gameApi.getUnitData(unitId))
|
|
67
|
+
.filter((unit) => unit != null)
|
|
68
|
+
.map((unit) => unit);
|
|
69
|
+
}
|
|
70
|
+
getUnitsOfTypes(gameApi, ...names) {
|
|
71
|
+
return this.unitIds
|
|
72
|
+
.map((unitId) => gameApi.getUnitData(unitId))
|
|
73
|
+
.filter((unit) => !!unit && names.includes(unit.name))
|
|
74
|
+
.map((unit) => unit);
|
|
75
|
+
}
|
|
76
|
+
getUnitsMatching(gameApi, filter) {
|
|
77
|
+
return this.unitIds
|
|
78
|
+
.map((unitId) => gameApi.getUnitData(unitId))
|
|
79
|
+
.filter((unit) => !!unit && filter(unit))
|
|
80
|
+
.map((unit) => unit);
|
|
81
|
+
}
|
|
82
|
+
getCenterOfMass() {
|
|
83
|
+
return this.centerOfMass;
|
|
84
|
+
}
|
|
85
|
+
getMaxDistanceToCenterOfMass() {
|
|
86
|
+
return this.maxDistanceToCenterOfMass;
|
|
87
|
+
}
|
|
88
|
+
getUniqueName() {
|
|
89
|
+
return this.uniqueName;
|
|
90
|
+
}
|
|
91
|
+
// Don't call this from the mission itself
|
|
92
|
+
endMission(reason) {
|
|
93
|
+
this.onFinish(this.unitIds, reason);
|
|
94
|
+
this.active = false;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Declare a callback that is executed when the mission is disbanded for whatever reason.
|
|
98
|
+
*/
|
|
99
|
+
then(onFinish) {
|
|
100
|
+
this.onFinish = onFinish;
|
|
101
|
+
return this;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Determines whether units can be stolen from this mission by other missions with higher priority.
|
|
105
|
+
*/
|
|
106
|
+
isUnitsLocked() {
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
export const noop = () => ({
|
|
111
|
+
type: "noop",
|
|
112
|
+
});
|
|
113
|
+
export const disbandMission = (reason) => ({ type: "disband", reason });
|
|
114
|
+
export const isDisbandMission = (a) => a.action.type === "disband";
|
|
115
|
+
export const requestUnits = (unitNames, priority) => ({ type: "request", unitNames, priority });
|
|
116
|
+
export const isRequestUnits = (a) => a.action.type === "request";
|
|
117
|
+
export const requestSpecificUnits = (unitIds, priority) => ({ type: "requestSpecific", unitIds, priority });
|
|
118
|
+
export const isRequestSpecificUnits = (a) => a.action.type === "requestSpecific";
|
|
119
|
+
export const grabCombatants = (point, radius) => ({ type: "requestCombatants", point, radius });
|
|
120
|
+
export const isGrabCombatants = (a) => a.action.type === "requestCombatants";
|
|
121
|
+
export const releaseUnits = (unitIds) => ({ type: "releaseUnits", unitIds });
|
|
122
|
+
export const isReleaseUnits = (a) => a.action.type === "releaseUnits";
|
|
123
123
|
//# sourceMappingURL=mission.js.map
|