@supalosa/chronodivide-bot 0.5.4 → 0.6.6-beta.1

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.
Files changed (124) hide show
  1. package/.env.template +4 -4
  2. package/.github/workflows/npm-publish.yml +24 -0
  3. package/README.md +108 -103
  4. package/dist/bot/bot.js +105 -105
  5. package/dist/bot/logic/awareness.js +136 -136
  6. package/dist/bot/logic/building/antiAirStaticDefence.js +42 -42
  7. package/dist/bot/logic/building/antiGroundStaticDefence.js +34 -34
  8. package/dist/bot/logic/building/{ArtilleryUnit.js → artilleryUnit.js} +18 -18
  9. package/dist/bot/logic/building/basicAirUnit.js +19 -19
  10. package/dist/bot/logic/building/basicBuilding.js +26 -26
  11. package/dist/bot/logic/building/basicGroundUnit.js +19 -19
  12. package/dist/bot/logic/building/buildingRules.js +175 -175
  13. package/dist/bot/logic/building/common.js +19 -19
  14. package/dist/bot/logic/building/harvester.js +16 -16
  15. package/dist/bot/logic/building/powerPlant.js +20 -20
  16. package/dist/bot/logic/building/queueController.js +183 -183
  17. package/dist/bot/logic/building/resourceCollectionBuilding.js +36 -36
  18. package/dist/bot/logic/common/scout.js +126 -126
  19. package/dist/bot/logic/common/utils.js +95 -95
  20. package/dist/bot/logic/composition/alliedCompositions.js +12 -12
  21. package/dist/bot/logic/composition/common.js +1 -1
  22. package/dist/bot/logic/composition/sovietCompositions.js +12 -12
  23. package/dist/bot/logic/map/map.js +44 -44
  24. package/dist/bot/logic/map/sector.js +137 -137
  25. package/dist/bot/logic/mission/actionBatcher.js +91 -91
  26. package/dist/bot/logic/mission/mission.js +122 -122
  27. package/dist/bot/logic/mission/missionController.js +321 -321
  28. package/dist/bot/logic/mission/missionFactories.js +12 -12
  29. package/dist/bot/logic/mission/missions/attackMission.js +214 -214
  30. package/dist/bot/logic/mission/missions/defenceMission.js +82 -82
  31. package/dist/bot/logic/mission/missions/engineerMission.js +63 -63
  32. package/dist/bot/logic/mission/missions/expansionMission.js +60 -60
  33. package/dist/bot/logic/mission/missions/retreatMission.js +33 -33
  34. package/dist/bot/logic/mission/missions/scoutingMission.js +133 -133
  35. package/dist/bot/logic/mission/missions/squads/combatSquad.js +115 -115
  36. package/dist/bot/logic/mission/missions/squads/common.js +57 -57
  37. package/dist/bot/logic/mission/missions/squads/squad.js +1 -1
  38. package/dist/bot/logic/threat/threat.js +22 -22
  39. package/dist/bot/logic/threat/threatCalculator.js +73 -73
  40. package/dist/exampleBot.js +100 -100
  41. package/package.json +32 -29
  42. package/src/bot/bot.ts +161 -161
  43. package/src/bot/logic/awareness.ts +245 -245
  44. package/src/bot/logic/building/antiAirStaticDefence.ts +64 -64
  45. package/src/bot/logic/building/antiGroundStaticDefence.ts +55 -55
  46. package/src/bot/logic/building/artilleryUnit.ts +39 -39
  47. package/src/bot/logic/building/basicAirUnit.ts +39 -39
  48. package/src/bot/logic/building/basicBuilding.ts +49 -49
  49. package/src/bot/logic/building/basicGroundUnit.ts +39 -39
  50. package/src/bot/logic/building/buildingRules.ts +250 -250
  51. package/src/bot/logic/building/common.ts +21 -21
  52. package/src/bot/logic/building/harvester.ts +31 -31
  53. package/src/bot/logic/building/powerPlant.ts +32 -32
  54. package/src/bot/logic/building/queueController.ts +297 -297
  55. package/src/bot/logic/building/resourceCollectionBuilding.ts +52 -52
  56. package/src/bot/logic/common/scout.ts +183 -183
  57. package/src/bot/logic/common/utils.ts +120 -120
  58. package/src/bot/logic/composition/alliedCompositions.ts +22 -22
  59. package/src/bot/logic/composition/common.ts +3 -3
  60. package/src/bot/logic/composition/sovietCompositions.ts +21 -21
  61. package/src/bot/logic/map/map.ts +66 -66
  62. package/src/bot/logic/map/sector.ts +174 -174
  63. package/src/bot/logic/mission/actionBatcher.ts +124 -124
  64. package/src/bot/logic/mission/mission.ts +232 -232
  65. package/src/bot/logic/mission/missionController.ts +413 -413
  66. package/src/bot/logic/mission/missionFactories.ts +51 -51
  67. package/src/bot/logic/mission/missions/attackMission.ts +336 -336
  68. package/src/bot/logic/mission/missions/defenceMission.ts +151 -151
  69. package/src/bot/logic/mission/missions/engineerMission.ts +113 -113
  70. package/src/bot/logic/mission/missions/expansionMission.ts +104 -104
  71. package/src/bot/logic/mission/missions/retreatMission.ts +54 -54
  72. package/src/bot/logic/mission/missions/scoutingMission.ts +186 -186
  73. package/src/bot/logic/mission/missions/squads/combatSquad.ts +160 -160
  74. package/src/bot/logic/mission/missions/squads/common.ts +63 -63
  75. package/src/bot/logic/mission/missions/squads/squad.ts +19 -19
  76. package/src/bot/logic/threat/threat.ts +15 -15
  77. package/src/bot/logic/threat/threatCalculator.ts +100 -100
  78. package/src/exampleBot.ts +111 -111
  79. package/tsconfig.json +73 -73
  80. package/dist/bot/logic/awarenessImpl.js +0 -132
  81. package/dist/bot/logic/awarenessImpl.js.map +0 -1
  82. package/dist/bot/logic/building/building.js +0 -126
  83. package/dist/bot/logic/building/building.js.map +0 -1
  84. package/dist/bot/logic/mission/behaviours/combatSquad.js +0 -124
  85. package/dist/bot/logic/mission/behaviours/combatSquad.js.map +0 -1
  86. package/dist/bot/logic/mission/behaviours/common.js +0 -58
  87. package/dist/bot/logic/mission/behaviours/common.js.map +0 -1
  88. package/dist/bot/logic/mission/behaviours/engineerSquad.js +0 -39
  89. package/dist/bot/logic/mission/behaviours/engineerSquad.js.map +0 -1
  90. package/dist/bot/logic/mission/behaviours/expansionSquad.js +0 -46
  91. package/dist/bot/logic/mission/behaviours/expansionSquad.js.map +0 -1
  92. package/dist/bot/logic/mission/behaviours/retreatSquad.js +0 -31
  93. package/dist/bot/logic/mission/behaviours/retreatSquad.js.map +0 -1
  94. package/dist/bot/logic/mission/behaviours/scoutingSquad.js +0 -94
  95. package/dist/bot/logic/mission/behaviours/scoutingSquad.js.map +0 -1
  96. package/dist/bot/logic/mission/missions/basicMission.js +0 -13
  97. package/dist/bot/logic/mission/missions/basicMission.js.map +0 -1
  98. package/dist/bot/logic/mission/missions/missionBehaviour.js +0 -2
  99. package/dist/bot/logic/mission/missions/missionBehaviour.js.map +0 -1
  100. package/dist/bot/logic/mission/missions/oneTimeMission.js +0 -27
  101. package/dist/bot/logic/mission/missions/oneTimeMission.js.map +0 -1
  102. package/dist/bot/logic/squad/behaviours/attackSquad.js +0 -89
  103. package/dist/bot/logic/squad/behaviours/combatSquad.js +0 -102
  104. package/dist/bot/logic/squad/behaviours/combatSquad.js.map +0 -1
  105. package/dist/bot/logic/squad/behaviours/common.js +0 -40
  106. package/dist/bot/logic/squad/behaviours/common.js.map +0 -1
  107. package/dist/bot/logic/squad/behaviours/defenceSquad.js +0 -61
  108. package/dist/bot/logic/squad/behaviours/engineerSquad.js +0 -36
  109. package/dist/bot/logic/squad/behaviours/engineerSquad.js.map +0 -1
  110. package/dist/bot/logic/squad/behaviours/expansionSquad.js +0 -43
  111. package/dist/bot/logic/squad/behaviours/expansionSquad.js.map +0 -1
  112. package/dist/bot/logic/squad/behaviours/retreatSquad.js +0 -28
  113. package/dist/bot/logic/squad/behaviours/retreatSquad.js.map +0 -1
  114. package/dist/bot/logic/squad/behaviours/scoutingSquad.js +0 -86
  115. package/dist/bot/logic/squad/behaviours/scoutingSquad.js.map +0 -1
  116. package/dist/bot/logic/squad/squad.js +0 -126
  117. package/dist/bot/logic/squad/squad.js.map +0 -1
  118. package/dist/bot/logic/squad/squadBehaviour.js +0 -6
  119. package/dist/bot/logic/squad/squadBehaviour.js.map +0 -1
  120. package/dist/bot/logic/squad/squadBehaviours.js +0 -7
  121. package/dist/bot/logic/squad/squadBehaviours.js.map +0 -1
  122. package/dist/bot/logic/squad/squadController.js +0 -199
  123. package/dist/bot/logic/squad/squadController.js.map +0 -1
  124. /package/dist/bot/logic/building/{ArtilleryUnit.js.map → artilleryUnit.js.map} +0 -0
@@ -1,64 +1,64 @@
1
- import { OrderType } from "@chronodivide/game-api";
2
- import { Mission, disbandMission, noop, requestUnits } from "../mission.js";
3
- const CAPTURE_COOLDOWN_TICKS = 30;
4
- /**
5
- * A mission that tries to send an engineer into a building (e.g. to capture tech building or repair bridge)
6
- */
7
- export class EngineerMission extends Mission {
8
- constructor(uniqueName, priority, captureTargetId, logger) {
9
- super(uniqueName, logger);
10
- this.priority = priority;
11
- this.captureTargetId = captureTargetId;
12
- this.hasAttemptedCaptureWith = null;
13
- }
14
- _onAiUpdate(gameApi, actionsApi, playerData, matchAwareness, actionBatcher) {
15
- const engineerTypes = ["ENGINEER", "SENGINEER"];
16
- const engineers = this.getUnitsOfTypes(gameApi, ...engineerTypes);
17
- if (engineers.length === 0) {
18
- // Perhaps we deployed already (or the unit was destroyed), end the mission.
19
- if (this.hasAttemptedCaptureWith !== null) {
20
- return disbandMission();
21
- }
22
- return requestUnits(engineerTypes, this.priority);
23
- }
24
- else if (!this.hasAttemptedCaptureWith ||
25
- gameApi.getCurrentTick() > this.hasAttemptedCaptureWith.gameTick + CAPTURE_COOLDOWN_TICKS) {
26
- actionsApi.orderUnits(engineers.map((engineer) => engineer.id), OrderType.Capture, this.captureTargetId);
27
- // Add a cooldown to deploy attempts.
28
- this.hasAttemptedCaptureWith = {
29
- unitId: engineers[0].id,
30
- gameTick: gameApi.getCurrentTick(),
31
- };
32
- }
33
- return noop();
34
- }
35
- getGlobalDebugText() {
36
- return undefined;
37
- }
38
- getPriority() {
39
- return this.priority;
40
- }
41
- }
42
- // Only try to capture tech buildings within this radius of the starting point.
43
- const MAX_TECH_CAPTURE_RADIUS = 50;
44
- const TECH_CHECK_INTERVAL_TICKS = 300;
45
- export class EngineerMissionFactory {
46
- constructor() {
47
- this.lastCheckAt = 0;
48
- }
49
- getName() {
50
- return "EngineerMissionFactory";
51
- }
52
- maybeCreateMissions(gameApi, playerData, matchAwareness, missionController, logger) {
53
- if (!(gameApi.getCurrentTick() > this.lastCheckAt + TECH_CHECK_INTERVAL_TICKS)) {
54
- return;
55
- }
56
- this.lastCheckAt = gameApi.getCurrentTick();
57
- const eligibleTechBuildings = gameApi.getVisibleUnits(playerData.name, "hostile", (r) => r.capturable && r.produceCashAmount > 0);
58
- eligibleTechBuildings.forEach((techBuildingId) => {
59
- missionController.addMission(new EngineerMission("capture-" + techBuildingId, 100, techBuildingId, logger));
60
- });
61
- }
62
- onMissionFailed(gameApi, playerData, matchAwareness, failedMission, failureReason, missionController) { }
63
- }
1
+ import { OrderType } from "@chronodivide/game-api";
2
+ import { Mission, disbandMission, noop, requestUnits } from "../mission.js";
3
+ const CAPTURE_COOLDOWN_TICKS = 30;
4
+ /**
5
+ * A mission that tries to send an engineer into a building (e.g. to capture tech building or repair bridge)
6
+ */
7
+ export class EngineerMission extends Mission {
8
+ constructor(uniqueName, priority, captureTargetId, logger) {
9
+ super(uniqueName, logger);
10
+ this.priority = priority;
11
+ this.captureTargetId = captureTargetId;
12
+ this.hasAttemptedCaptureWith = null;
13
+ }
14
+ _onAiUpdate(gameApi, actionsApi, playerData, matchAwareness, actionBatcher) {
15
+ const engineerTypes = ["ENGINEER", "SENGINEER"];
16
+ const engineers = this.getUnitsOfTypes(gameApi, ...engineerTypes);
17
+ if (engineers.length === 0) {
18
+ // Perhaps we deployed already (or the unit was destroyed), end the mission.
19
+ if (this.hasAttemptedCaptureWith !== null) {
20
+ return disbandMission();
21
+ }
22
+ return requestUnits(engineerTypes, this.priority);
23
+ }
24
+ else if (!this.hasAttemptedCaptureWith ||
25
+ gameApi.getCurrentTick() > this.hasAttemptedCaptureWith.gameTick + CAPTURE_COOLDOWN_TICKS) {
26
+ actionsApi.orderUnits(engineers.map((engineer) => engineer.id), OrderType.Capture, this.captureTargetId);
27
+ // Add a cooldown to deploy attempts.
28
+ this.hasAttemptedCaptureWith = {
29
+ unitId: engineers[0].id,
30
+ gameTick: gameApi.getCurrentTick(),
31
+ };
32
+ }
33
+ return noop();
34
+ }
35
+ getGlobalDebugText() {
36
+ return undefined;
37
+ }
38
+ getPriority() {
39
+ return this.priority;
40
+ }
41
+ }
42
+ // Only try to capture tech buildings within this radius of the starting point.
43
+ const MAX_TECH_CAPTURE_RADIUS = 50;
44
+ const TECH_CHECK_INTERVAL_TICKS = 300;
45
+ export class EngineerMissionFactory {
46
+ constructor() {
47
+ this.lastCheckAt = 0;
48
+ }
49
+ getName() {
50
+ return "EngineerMissionFactory";
51
+ }
52
+ maybeCreateMissions(gameApi, playerData, matchAwareness, missionController, logger) {
53
+ if (!(gameApi.getCurrentTick() > this.lastCheckAt + TECH_CHECK_INTERVAL_TICKS)) {
54
+ return;
55
+ }
56
+ this.lastCheckAt = gameApi.getCurrentTick();
57
+ const eligibleTechBuildings = gameApi.getVisibleUnits(playerData.name, "hostile", (r) => r.capturable && r.produceCashAmount > 0);
58
+ eligibleTechBuildings.forEach((techBuildingId) => {
59
+ missionController.addMission(new EngineerMission("capture-" + techBuildingId, 100, techBuildingId, logger));
60
+ });
61
+ }
62
+ onMissionFailed(gameApi, playerData, matchAwareness, failedMission, failureReason, missionController) { }
63
+ }
64
64
  //# sourceMappingURL=engineerMission.js.map
@@ -1,61 +1,61 @@
1
- import { OrderType } from "@chronodivide/game-api";
2
- import { Mission, disbandMission, noop, requestSpecificUnits, requestUnits } from "../mission.js";
3
- const DEPLOY_COOLDOWN_TICKS = 30;
4
- /**
5
- * A mission that tries to create an MCV (if it doesn't exist) and deploy it somewhere it can be deployed.
6
- */
7
- export class ExpansionMission extends Mission {
8
- constructor(uniqueName, priority, selectedMcv, logger) {
9
- super(uniqueName, logger);
10
- this.priority = priority;
11
- this.selectedMcv = selectedMcv;
12
- this.hasAttemptedDeployWith = null;
13
- }
14
- _onAiUpdate(gameApi, actionsApi, playerData, matchAwareness, actionBatcher) {
15
- const mcvTypes = ["AMCV", "SMCV"];
16
- const mcvs = this.getUnitsOfTypes(gameApi, ...mcvTypes);
17
- if (mcvs.length === 0) {
18
- // Perhaps we deployed already (or the unit was destroyed), end the mission.
19
- if (this.hasAttemptedDeployWith !== null) {
20
- return disbandMission();
21
- }
22
- // We need an mcv!
23
- if (this.selectedMcv) {
24
- return requestSpecificUnits([this.selectedMcv], this.priority);
25
- }
26
- else {
27
- return requestUnits(mcvTypes, this.priority);
28
- }
29
- }
30
- else if (!this.hasAttemptedDeployWith ||
31
- gameApi.getCurrentTick() > this.hasAttemptedDeployWith.gameTick + DEPLOY_COOLDOWN_TICKS) {
32
- actionsApi.orderUnits(mcvs.map((mcv) => mcv.id), OrderType.DeploySelected);
33
- // Add a cooldown to deploy attempts.
34
- this.hasAttemptedDeployWith = {
35
- unitId: mcvs[0].id,
36
- gameTick: gameApi.getCurrentTick(),
37
- };
38
- }
39
- return noop();
40
- }
41
- getGlobalDebugText() {
42
- return `Expand with MCV ${this.selectedMcv}`;
43
- }
44
- getPriority() {
45
- return this.priority;
46
- }
47
- }
48
- export class ExpansionMissionFactory {
49
- getName() {
50
- return "ExpansionMissionFactory";
51
- }
52
- maybeCreateMissions(gameApi, playerData, matchAwareness, missionController, logger) {
53
- // At this point, only expand if we have a loose MCV.
54
- const mcvs = gameApi.getVisibleUnits(playerData.name, "self", (r) => gameApi.getGeneralRules().baseUnit.includes(r.name));
55
- mcvs.forEach((mcv) => {
56
- missionController.addMission(new ExpansionMission("expand-with-" + mcv, 100, mcv, logger));
57
- });
58
- }
59
- onMissionFailed(gameApi, playerData, matchAwareness, failedMission, failureReason, missionController) { }
60
- }
1
+ import { OrderType } from "@chronodivide/game-api";
2
+ import { Mission, disbandMission, noop, requestSpecificUnits, requestUnits } from "../mission.js";
3
+ const DEPLOY_COOLDOWN_TICKS = 30;
4
+ /**
5
+ * A mission that tries to create an MCV (if it doesn't exist) and deploy it somewhere it can be deployed.
6
+ */
7
+ export class ExpansionMission extends Mission {
8
+ constructor(uniqueName, priority, selectedMcv, logger) {
9
+ super(uniqueName, logger);
10
+ this.priority = priority;
11
+ this.selectedMcv = selectedMcv;
12
+ this.hasAttemptedDeployWith = null;
13
+ }
14
+ _onAiUpdate(gameApi, actionsApi, playerData, matchAwareness, actionBatcher) {
15
+ const mcvTypes = ["AMCV", "SMCV"];
16
+ const mcvs = this.getUnitsOfTypes(gameApi, ...mcvTypes);
17
+ if (mcvs.length === 0) {
18
+ // Perhaps we deployed already (or the unit was destroyed), end the mission.
19
+ if (this.hasAttemptedDeployWith !== null) {
20
+ return disbandMission();
21
+ }
22
+ // We need an mcv!
23
+ if (this.selectedMcv) {
24
+ return requestSpecificUnits([this.selectedMcv], this.priority);
25
+ }
26
+ else {
27
+ return requestUnits(mcvTypes, this.priority);
28
+ }
29
+ }
30
+ else if (!this.hasAttemptedDeployWith ||
31
+ gameApi.getCurrentTick() > this.hasAttemptedDeployWith.gameTick + DEPLOY_COOLDOWN_TICKS) {
32
+ actionsApi.orderUnits(mcvs.map((mcv) => mcv.id), OrderType.DeploySelected);
33
+ // Add a cooldown to deploy attempts.
34
+ this.hasAttemptedDeployWith = {
35
+ unitId: mcvs[0].id,
36
+ gameTick: gameApi.getCurrentTick(),
37
+ };
38
+ }
39
+ return noop();
40
+ }
41
+ getGlobalDebugText() {
42
+ return `Expand with MCV ${this.selectedMcv}`;
43
+ }
44
+ getPriority() {
45
+ return this.priority;
46
+ }
47
+ }
48
+ export class ExpansionMissionFactory {
49
+ getName() {
50
+ return "ExpansionMissionFactory";
51
+ }
52
+ maybeCreateMissions(gameApi, playerData, matchAwareness, missionController, logger) {
53
+ // At this point, only expand if we have a loose MCV.
54
+ const mcvs = gameApi.getVisibleUnits(playerData.name, "self", (r) => gameApi.getGeneralRules().baseUnit.includes(r.name));
55
+ mcvs.forEach((mcv) => {
56
+ missionController.addMission(new ExpansionMission("expand-with-" + mcv, 100, mcv, logger));
57
+ });
58
+ }
59
+ onMissionFailed(gameApi, playerData, matchAwareness, failedMission, failureReason, missionController) { }
60
+ }
61
61
  //# sourceMappingURL=expansionMission.js.map
@@ -1,34 +1,34 @@
1
- import { OrderType } from "@chronodivide/game-api";
2
- import { Mission, disbandMission, requestSpecificUnits } from "../mission.js";
3
- export class RetreatMission extends Mission {
4
- constructor(uniqueName, retreatToPoint, withUnitIds, logger) {
5
- super(uniqueName, logger);
6
- this.retreatToPoint = retreatToPoint;
7
- this.withUnitIds = withUnitIds;
8
- this.createdAt = null;
9
- }
10
- _onAiUpdate(gameApi, actionsApi, playerData, matchAwareness, actionBatcher) {
11
- if (!this.createdAt) {
12
- this.createdAt = gameApi.getCurrentTick();
13
- }
14
- if (this.getUnitIds().length > 0) {
15
- // Only send the order once we have managed to claim some units.
16
- actionsApi.orderUnits(this.getUnitIds(), OrderType.AttackMove, this.retreatToPoint.x, this.retreatToPoint.y);
17
- return disbandMission();
18
- }
19
- if (this.createdAt && gameApi.getCurrentTick() > this.createdAt + 240) {
20
- // Disband automatically after 240 ticks in case we couldn't actually claim any units.
21
- return disbandMission();
22
- }
23
- else {
24
- return requestSpecificUnits(this.withUnitIds, 1000);
25
- }
26
- }
27
- getGlobalDebugText() {
28
- return `retreat with ${this.withUnitIds.length} units`;
29
- }
30
- getPriority() {
31
- return 100;
32
- }
33
- }
1
+ import { OrderType } from "@chronodivide/game-api";
2
+ import { Mission, disbandMission, requestSpecificUnits } from "../mission.js";
3
+ export class RetreatMission extends Mission {
4
+ constructor(uniqueName, retreatToPoint, withUnitIds, logger) {
5
+ super(uniqueName, logger);
6
+ this.retreatToPoint = retreatToPoint;
7
+ this.withUnitIds = withUnitIds;
8
+ this.createdAt = null;
9
+ }
10
+ _onAiUpdate(gameApi, actionsApi, playerData, matchAwareness, actionBatcher) {
11
+ if (!this.createdAt) {
12
+ this.createdAt = gameApi.getCurrentTick();
13
+ }
14
+ if (this.getUnitIds().length > 0) {
15
+ // Only send the order once we have managed to claim some units.
16
+ actionsApi.orderUnits(this.getUnitIds(), OrderType.AttackMove, this.retreatToPoint.x, this.retreatToPoint.y);
17
+ return disbandMission();
18
+ }
19
+ if (this.createdAt && gameApi.getCurrentTick() > this.createdAt + 240) {
20
+ // Disband automatically after 240 ticks in case we couldn't actually claim any units.
21
+ return disbandMission();
22
+ }
23
+ else {
24
+ return requestSpecificUnits(this.withUnitIds, 1000);
25
+ }
26
+ }
27
+ getGlobalDebugText() {
28
+ return `retreat with ${this.withUnitIds.length} units`;
29
+ }
30
+ getPriority() {
31
+ return 100;
32
+ }
33
+ }
34
34
  //# sourceMappingURL=retreatMission.js.map
@@ -1,134 +1,134 @@
1
- import { OrderType } from "@chronodivide/game-api";
2
- import { Mission, disbandMission, noop, requestUnits } from "../mission.js";
3
- import { AttackMission } from "./attackMission.js";
4
- import { getDistanceBetweenTileAndPoint } from "../../map/map.js";
5
- const SCOUT_MOVE_COOLDOWN_TICKS = 30;
6
- // Max units to spend on a particular scout target.
7
- const MAX_ATTEMPTS_PER_TARGET = 5;
8
- // Maximum ticks to spend trying to scout a target *without making progress towards it*.
9
- // Every time a unit gets closer to the target, the timer refreshes.
10
- const MAX_TICKS_PER_TARGET = 600;
11
- /**
12
- * A mission that tries to scout around the map with a cheap, fast unit (usually attack dogs)
13
- */
14
- export class ScoutingMission extends Mission {
15
- constructor(uniqueName, priority, logger) {
16
- super(uniqueName, logger);
17
- this.priority = priority;
18
- this.scoutTarget = null;
19
- this.attemptsOnCurrentTarget = 0;
20
- this.scoutTargetRefreshedAt = 0;
21
- this.lastMoveCommandTick = 0;
22
- this.scoutTargetIsPermanent = false;
23
- this.hadUnit = false;
24
- }
25
- _onAiUpdate(gameApi, actionsApi, playerData, matchAwareness, actionBatcher) {
26
- const scoutNames = ["ADOG", "DOG", "E1", "E2", "FV", "HTK"];
27
- const scouts = this.getUnitsOfTypes(gameApi, ...scoutNames);
28
- if ((matchAwareness.getSectorCache().getOverallVisibility() || 0) > 0.9) {
29
- return disbandMission();
30
- }
31
- if (scouts.length === 0) {
32
- // Count the number of times the scout dies trying to uncover the current scoutTarget.
33
- if (this.scoutTarget && this.hadUnit) {
34
- this.attemptsOnCurrentTarget++;
35
- this.hadUnit = false;
36
- }
37
- return requestUnits(scoutNames, this.priority);
38
- }
39
- else if (this.scoutTarget) {
40
- this.hadUnit = true;
41
- if (!this.scoutTargetIsPermanent) {
42
- if (this.attemptsOnCurrentTarget > MAX_ATTEMPTS_PER_TARGET) {
43
- this.logger(`Scout target ${this.scoutTarget.x},${this.scoutTarget.y} took too many attempts, moving to next`);
44
- this.setScoutTarget(null, 0);
45
- return noop();
46
- }
47
- if (gameApi.getCurrentTick() > this.scoutTargetRefreshedAt + MAX_TICKS_PER_TARGET) {
48
- this.logger(`Scout target ${this.scoutTarget.x},${this.scoutTarget.y} took too long, moving to next`);
49
- this.setScoutTarget(null, 0);
50
- return noop();
51
- }
52
- }
53
- const targetTile = gameApi.mapApi.getTile(this.scoutTarget.x, this.scoutTarget.y);
54
- if (!targetTile) {
55
- throw new Error(`target tile ${this.scoutTarget.x},${this.scoutTarget.y} does not exist`);
56
- }
57
- if (gameApi.getCurrentTick() > this.lastMoveCommandTick + SCOUT_MOVE_COOLDOWN_TICKS) {
58
- this.lastMoveCommandTick = gameApi.getCurrentTick();
59
- scouts.forEach((unit) => {
60
- if (this.scoutTarget) {
61
- actionsApi.orderUnits([unit.id], OrderType.AttackMove, this.scoutTarget.x, this.scoutTarget.y);
62
- }
63
- });
64
- // Check that a scout is actually moving closer to the target.
65
- const distances = scouts.map((unit) => getDistanceBetweenTileAndPoint(unit.tile, this.scoutTarget));
66
- const newMinDistance = Math.min(...distances);
67
- if (!this.scoutMinDistance || newMinDistance < this.scoutMinDistance) {
68
- this.logger(`Scout timeout refreshed because unit moved closer to point (${newMinDistance} < ${this.scoutMinDistance})`);
69
- this.scoutTargetRefreshedAt = gameApi.getCurrentTick();
70
- this.scoutMinDistance = newMinDistance;
71
- }
72
- }
73
- if (gameApi.mapApi.isVisibleTile(targetTile, playerData.name)) {
74
- this.logger(`Scout target ${this.scoutTarget.x},${this.scoutTarget.y} successfully scouted, moving to next`);
75
- this.setScoutTarget(null, gameApi.getCurrentTick());
76
- }
77
- }
78
- else {
79
- const nextScoutTarget = matchAwareness.getScoutingManager().getNewScoutTarget();
80
- if (!nextScoutTarget) {
81
- this.logger(`No more scouting targets available, disbanding.`);
82
- return disbandMission();
83
- }
84
- this.setScoutTarget(nextScoutTarget, gameApi.getCurrentTick());
85
- }
86
- return noop();
87
- }
88
- setScoutTarget(target, currentTick) {
89
- this.attemptsOnCurrentTarget = 0;
90
- this.scoutTargetRefreshedAt = currentTick;
91
- this.scoutTarget = target?.asVector2() ?? null;
92
- this.scoutMinDistance = undefined;
93
- this.scoutTargetIsPermanent = target?.isPermanent ?? false;
94
- }
95
- getGlobalDebugText() {
96
- return "scouting";
97
- }
98
- getPriority() {
99
- return this.priority;
100
- }
101
- }
102
- const SCOUT_COOLDOWN_TICKS = 300;
103
- export class ScoutingMissionFactory {
104
- constructor(lastScoutAt = -SCOUT_COOLDOWN_TICKS) {
105
- this.lastScoutAt = lastScoutAt;
106
- }
107
- getName() {
108
- return "ScoutingMissionFactory";
109
- }
110
- maybeCreateMissions(gameApi, playerData, matchAwareness, missionController, logger) {
111
- if (gameApi.getCurrentTick() < this.lastScoutAt + SCOUT_COOLDOWN_TICKS) {
112
- return;
113
- }
114
- if (!matchAwareness.getScoutingManager().hasScoutTargets()) {
115
- return;
116
- }
117
- if (!missionController.addMission(new ScoutingMission("globalScout", 10, logger))) {
118
- this.lastScoutAt = gameApi.getCurrentTick();
119
- }
120
- }
121
- onMissionFailed(gameApi, playerData, matchAwareness, failedMission, failureReason, missionController, logger) {
122
- if (gameApi.getCurrentTick() < this.lastScoutAt + SCOUT_COOLDOWN_TICKS) {
123
- return;
124
- }
125
- if (!matchAwareness.getScoutingManager().hasScoutTargets()) {
126
- return;
127
- }
128
- if (failedMission instanceof AttackMission) {
129
- missionController.addMission(new ScoutingMission("globalScout", 10, logger));
130
- this.lastScoutAt = gameApi.getCurrentTick();
131
- }
132
- }
133
- }
1
+ import { OrderType } from "@chronodivide/game-api";
2
+ import { Mission, disbandMission, noop, requestUnits } from "../mission.js";
3
+ import { AttackMission } from "./attackMission.js";
4
+ import { getDistanceBetweenTileAndPoint } from "../../map/map.js";
5
+ const SCOUT_MOVE_COOLDOWN_TICKS = 30;
6
+ // Max units to spend on a particular scout target.
7
+ const MAX_ATTEMPTS_PER_TARGET = 5;
8
+ // Maximum ticks to spend trying to scout a target *without making progress towards it*.
9
+ // Every time a unit gets closer to the target, the timer refreshes.
10
+ const MAX_TICKS_PER_TARGET = 600;
11
+ /**
12
+ * A mission that tries to scout around the map with a cheap, fast unit (usually attack dogs)
13
+ */
14
+ export class ScoutingMission extends Mission {
15
+ constructor(uniqueName, priority, logger) {
16
+ super(uniqueName, logger);
17
+ this.priority = priority;
18
+ this.scoutTarget = null;
19
+ this.attemptsOnCurrentTarget = 0;
20
+ this.scoutTargetRefreshedAt = 0;
21
+ this.lastMoveCommandTick = 0;
22
+ this.scoutTargetIsPermanent = false;
23
+ this.hadUnit = false;
24
+ }
25
+ _onAiUpdate(gameApi, actionsApi, playerData, matchAwareness, actionBatcher) {
26
+ const scoutNames = ["ADOG", "DOG", "E1", "E2", "FV", "HTK"];
27
+ const scouts = this.getUnitsOfTypes(gameApi, ...scoutNames);
28
+ if ((matchAwareness.getSectorCache().getOverallVisibility() || 0) > 0.9) {
29
+ return disbandMission();
30
+ }
31
+ if (scouts.length === 0) {
32
+ // Count the number of times the scout dies trying to uncover the current scoutTarget.
33
+ if (this.scoutTarget && this.hadUnit) {
34
+ this.attemptsOnCurrentTarget++;
35
+ this.hadUnit = false;
36
+ }
37
+ return requestUnits(scoutNames, this.priority);
38
+ }
39
+ else if (this.scoutTarget) {
40
+ this.hadUnit = true;
41
+ if (!this.scoutTargetIsPermanent) {
42
+ if (this.attemptsOnCurrentTarget > MAX_ATTEMPTS_PER_TARGET) {
43
+ this.logger(`Scout target ${this.scoutTarget.x},${this.scoutTarget.y} took too many attempts, moving to next`);
44
+ this.setScoutTarget(null, 0);
45
+ return noop();
46
+ }
47
+ if (gameApi.getCurrentTick() > this.scoutTargetRefreshedAt + MAX_TICKS_PER_TARGET) {
48
+ this.logger(`Scout target ${this.scoutTarget.x},${this.scoutTarget.y} took too long, moving to next`);
49
+ this.setScoutTarget(null, 0);
50
+ return noop();
51
+ }
52
+ }
53
+ const targetTile = gameApi.mapApi.getTile(this.scoutTarget.x, this.scoutTarget.y);
54
+ if (!targetTile) {
55
+ throw new Error(`target tile ${this.scoutTarget.x},${this.scoutTarget.y} does not exist`);
56
+ }
57
+ if (gameApi.getCurrentTick() > this.lastMoveCommandTick + SCOUT_MOVE_COOLDOWN_TICKS) {
58
+ this.lastMoveCommandTick = gameApi.getCurrentTick();
59
+ scouts.forEach((unit) => {
60
+ if (this.scoutTarget) {
61
+ actionsApi.orderUnits([unit.id], OrderType.AttackMove, this.scoutTarget.x, this.scoutTarget.y);
62
+ }
63
+ });
64
+ // Check that a scout is actually moving closer to the target.
65
+ const distances = scouts.map((unit) => getDistanceBetweenTileAndPoint(unit.tile, this.scoutTarget));
66
+ const newMinDistance = Math.min(...distances);
67
+ if (!this.scoutMinDistance || newMinDistance < this.scoutMinDistance) {
68
+ this.logger(`Scout timeout refreshed because unit moved closer to point (${newMinDistance} < ${this.scoutMinDistance})`);
69
+ this.scoutTargetRefreshedAt = gameApi.getCurrentTick();
70
+ this.scoutMinDistance = newMinDistance;
71
+ }
72
+ }
73
+ if (gameApi.mapApi.isVisibleTile(targetTile, playerData.name)) {
74
+ this.logger(`Scout target ${this.scoutTarget.x},${this.scoutTarget.y} successfully scouted, moving to next`);
75
+ this.setScoutTarget(null, gameApi.getCurrentTick());
76
+ }
77
+ }
78
+ else {
79
+ const nextScoutTarget = matchAwareness.getScoutingManager().getNewScoutTarget();
80
+ if (!nextScoutTarget) {
81
+ this.logger(`No more scouting targets available, disbanding.`);
82
+ return disbandMission();
83
+ }
84
+ this.setScoutTarget(nextScoutTarget, gameApi.getCurrentTick());
85
+ }
86
+ return noop();
87
+ }
88
+ setScoutTarget(target, currentTick) {
89
+ this.attemptsOnCurrentTarget = 0;
90
+ this.scoutTargetRefreshedAt = currentTick;
91
+ this.scoutTarget = target?.asVector2() ?? null;
92
+ this.scoutMinDistance = undefined;
93
+ this.scoutTargetIsPermanent = target?.isPermanent ?? false;
94
+ }
95
+ getGlobalDebugText() {
96
+ return "scouting";
97
+ }
98
+ getPriority() {
99
+ return this.priority;
100
+ }
101
+ }
102
+ const SCOUT_COOLDOWN_TICKS = 300;
103
+ export class ScoutingMissionFactory {
104
+ constructor(lastScoutAt = -SCOUT_COOLDOWN_TICKS) {
105
+ this.lastScoutAt = lastScoutAt;
106
+ }
107
+ getName() {
108
+ return "ScoutingMissionFactory";
109
+ }
110
+ maybeCreateMissions(gameApi, playerData, matchAwareness, missionController, logger) {
111
+ if (gameApi.getCurrentTick() < this.lastScoutAt + SCOUT_COOLDOWN_TICKS) {
112
+ return;
113
+ }
114
+ if (!matchAwareness.getScoutingManager().hasScoutTargets()) {
115
+ return;
116
+ }
117
+ if (!missionController.addMission(new ScoutingMission("globalScout", 10, logger))) {
118
+ this.lastScoutAt = gameApi.getCurrentTick();
119
+ }
120
+ }
121
+ onMissionFailed(gameApi, playerData, matchAwareness, failedMission, failureReason, missionController, logger) {
122
+ if (gameApi.getCurrentTick() < this.lastScoutAt + SCOUT_COOLDOWN_TICKS) {
123
+ return;
124
+ }
125
+ if (!matchAwareness.getScoutingManager().hasScoutTargets()) {
126
+ return;
127
+ }
128
+ if (failedMission instanceof AttackMission) {
129
+ missionController.addMission(new ScoutingMission("globalScout", 10, logger));
130
+ this.lastScoutAt = gameApi.getCurrentTick();
131
+ }
132
+ }
133
+ }
134
134
  //# sourceMappingURL=scoutingMission.js.map