@v12-engine/engine 0.0.0-stage → 0.1.0
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/LICENSE +21 -0
- package/dist/abilities/buffs.d.ts +83 -0
- package/dist/abilities/castTold.d.ts +12 -0
- package/dist/abilities/charges.d.ts +28 -0
- package/dist/abilities/dispel.d.ts +9 -0
- package/dist/abilities/effectFields.d.ts +10 -0
- package/dist/abilities/effects/buff.d.ts +8 -0
- package/dist/abilities/effects/core.d.ts +1 -0
- package/dist/abilities/effects/damage.d.ts +1 -0
- package/dist/abilities/effects/heal.d.ts +2 -0
- package/dist/abilities/effects/missile.d.ts +1 -0
- package/dist/abilities/effects/moves.d.ts +11 -0
- package/dist/abilities/effects/passives.d.ts +15 -0
- package/dist/abilities/effects/sight.d.ts +4 -0
- package/dist/abilities/effects/spawn.d.ts +2 -0
- package/dist/abilities/effects/timed.d.ts +4 -0
- package/dist/abilities/effects/trade.d.ts +1 -0
- package/dist/abilities/effects.d.ts +122 -0
- package/dist/abilities/land.d.ts +21 -0
- package/dist/abilities/scaled.d.ts +21 -0
- package/dist/abilities/text.d.ts +113 -0
- package/dist/ai/area.d.ts +53 -0
- package/dist/ai/brain.d.ts +528 -0
- package/dist/ai/budget.d.ts +67 -0
- package/dist/ai/checks.d.ts +115 -0
- package/dist/ai/computer.d.ts +166 -0
- package/dist/ai/defence.d.ts +108 -0
- package/dist/ai/define.d.ts +21 -0
- package/dist/ai/economy.d.ts +129 -0
- package/dist/ai/geometry.d.ts +35 -0
- package/dist/ai/goals.d.ts +360 -0
- package/dist/ai/index.d.ts +38 -0
- package/dist/ai/knowledge.d.ts +418 -0
- package/dist/ai/lanes.d.ts +232 -0
- package/dist/ai/melee/build.d.ts +61 -0
- package/dist/ai/melee/goals.d.ts +299 -0
- package/dist/ai/melee/heroes.d.ts +27 -0
- package/dist/ai/melee/index.d.ts +14 -0
- package/dist/ai/melee/production.d.ts +8 -0
- package/dist/ai/melee/surrender.d.ts +24 -0
- package/dist/ai/micro.d.ts +278 -0
- package/dist/ai/mission.d.ts +195 -0
- package/dist/ai/missionRules.d.ts +18 -0
- package/dist/ai/module.d.ts +116 -0
- package/dist/ai/options.d.ts +61 -0
- package/dist/ai/plans/build.d.ts +280 -0
- package/dist/ai/plans/placement.d.ts +82 -0
- package/dist/ai/plans/plans.d.ts +105 -0
- package/dist/ai/plans/production.d.ts +210 -0
- package/dist/ai/plans/purse.d.ts +73 -0
- package/dist/ai/plans/tech.d.ts +37 -0
- package/dist/ai/profiles.d.ts +204 -0
- package/dist/ai/reach.d.ts +4 -0
- package/dist/ai/report.d.ts +203 -0
- package/dist/ai/roles.d.ts +133 -0
- package/dist/ai/rules.d.ts +288 -0
- package/dist/ai/scouting.d.ts +98 -0
- package/dist/ai/settings.d.ts +73 -0
- package/dist/ai/squads.d.ts +429 -0
- package/dist/ai/strength.d.ts +167 -0
- package/dist/ai/task.d.ts +118 -0
- package/dist/ai/tasks/attack.d.ts +7 -0
- package/dist/ai/tasks/capture.d.ts +21 -0
- package/dist/ai/tasks/creep.d.ts +16 -0
- package/dist/ai/tasks/defend.d.ts +29 -0
- package/dist/ai/tasks/drop.d.ts +34 -0
- package/dist/ai/tasks/escort.d.ts +16 -0
- package/dist/ai/tasks/gather.d.ts +23 -0
- package/dist/ai/tasks/harass.d.ts +7 -0
- package/dist/ai/tasks/hold.d.ts +20 -0
- package/dist/ai/tasks/index.d.ts +32 -0
- package/dist/ai/tasks/move.d.ts +19 -0
- package/dist/ai/tasks/patrol.d.ts +8 -0
- package/dist/ai/tasks/retreat.d.ts +20 -0
- package/dist/ai/tasks/scout.d.ts +29 -0
- package/dist/ai/tasks/shared.d.ts +74 -0
- package/dist/ai/team.d.ts +155 -0
- package/dist/ai/threat.d.ts +91 -0
- package/dist/ai/view.d.ts +366 -0
- package/dist/ai/waves.d.ts +126 -0
- package/dist/ai.js +6239 -0
- package/dist/ai.js.map +1 -0
- package/dist/aiTesting.d.ts +179 -0
- package/dist/areas.d.ts +149 -0
- package/dist/attacks.d.ts +66 -0
- package/dist/attributes.d.ts +66 -0
- package/dist/brain-BvVdUhX8.js +7659 -0
- package/dist/brain-BvVdUhX8.js.map +1 -0
- package/dist/builds-C6LfgvEU.js +460 -0
- package/dist/builds-C6LfgvEU.js.map +1 -0
- package/dist/bytes.d.ts +6 -0
- package/dist/camps.d.ts +95 -0
- package/dist/capture.d.ts +131 -0
- package/dist/cellLayers.d.ts +75 -0
- package/dist/cinematics.d.ts +194 -0
- package/dist/clock.d.ts +32 -0
- package/dist/commands.d.ts +235 -0
- package/dist/components.d.ts +184 -0
- package/dist/computers.d.ts +108 -0
- package/dist/concealment.d.ts +61 -0
- package/dist/coreComponents-syuh2fPG.js +5149 -0
- package/dist/coreComponents-syuh2fPG.js.map +1 -0
- package/dist/coreComponents.d.ts +1 -0
- package/dist/dashing.d.ts +8 -0
- package/dist/debug.d.ts +36 -0
- package/dist/debug.js +3 -0
- package/dist/debugCommands-CzjrSm66.js +14739 -0
- package/dist/debugCommands-CzjrSm66.js.map +1 -0
- package/dist/debugCommands.d.ts +213 -0
- package/dist/debugging.d.ts +10 -0
- package/dist/definitions.d.ts +43 -0
- package/dist/defs.d.ts +1162 -0
- package/dist/denying.d.ts +81 -0
- package/dist/destructibles.d.ts +27 -0
- package/dist/determinism-BCymQwiE.js +518 -0
- package/dist/determinism-BCymQwiE.js.map +1 -0
- package/dist/determinism.d.ts +121 -0
- package/dist/dialog.d.ts +94 -0
- package/dist/effectRefs.d.ts +16 -0
- package/dist/effects.d.ts +80 -0
- package/dist/endings.d.ts +22 -0
- package/dist/engagement.d.ts +108 -0
- package/dist/engineEvents.d.ts +710 -0
- package/dist/entity.d.ts +409 -0
- package/dist/entityIndex.d.ts +50 -0
- package/dist/errors.d.ts +85 -0
- package/dist/events.d.ts +97 -0
- package/dist/exactMath.d.ts +63 -0
- package/dist/features.d.ts +10 -0
- package/dist/fields.d.ts +114 -0
- package/dist/fixture.d.ts +17 -0
- package/dist/fog.d.ts +110 -0
- package/dist/formation.d.ts +111 -0
- package/dist/friendlyFire.d.ts +26 -0
- package/dist/game-DiJEN-Ks.js +5800 -0
- package/dist/game-DiJEN-Ks.js.map +1 -0
- package/dist/game.d.ts +501 -0
- package/dist/gameData.d.ts +325 -0
- package/dist/gameFiles.d.ts +26 -0
- package/dist/gates.d.ts +28 -0
- package/dist/generate.d.ts +403 -0
- package/dist/generateWorker.d.ts +39 -0
- package/dist/grid.d.ts +53 -0
- package/dist/ground.d.ts +127 -0
- package/dist/groundSpeed.d.ts +22 -0
- package/dist/hero.d.ts +177 -0
- package/dist/home.d.ts +14 -0
- package/dist/hooks.d.ts +780 -0
- package/dist/hotReload.d.ts +76 -0
- package/dist/ids.d.ts +26 -0
- package/dist/index.d.ts +227 -0
- package/dist/index.js +4701 -0
- package/dist/index.js.map +1 -0
- package/dist/inspect-D9dWHmZ0.js +491 -0
- package/dist/inspect-D9dWHmZ0.js.map +1 -0
- package/dist/inspect.d.ts +176 -0
- package/dist/inventory.d.ts +18 -0
- package/dist/items.d.ts +91 -0
- package/dist/lanes.d.ts +213 -0
- package/dist/life.d.ts +53 -0
- package/dist/local-Dkovq42k.js +1379 -0
- package/dist/local-Dkovq42k.js.map +1 -0
- package/dist/log.d.ts +140 -0
- package/dist/manaBurn.d.ts +39 -0
- package/dist/map/file.d.ts +114 -0
- package/dist/map/images.d.ts +18 -0
- package/dist/map/look.d.ts +47 -0
- package/dist/map/pathProfile.d.ts +13 -0
- package/dist/map/resize.d.ts +54 -0
- package/dist/map/schema.d.ts +10 -0
- package/dist/map/terrain.d.ts +32 -0
- package/dist/map/types.d.ts +613 -0
- package/dist/map.d.ts +7 -0
- package/dist/mapCheck/cells.d.ts +19 -0
- package/dist/mapCheck/rule.d.ts +30 -0
- package/dist/mapCheck/rules/names.d.ts +3 -0
- package/dist/mapCheck/rules/objects.d.ts +3 -0
- package/dist/mapCheck/rules/paths.d.ts +3 -0
- package/dist/mapCheck/rules/players.d.ts +3 -0
- package/dist/mapCheck/rules/races.d.ts +3 -0
- package/dist/mapCheck/rules/random.d.ts +3 -0
- package/dist/mapCheck/rules/regions.d.ts +3 -0
- package/dist/mapCheck/rules/targets.d.ts +3 -0
- package/dist/mapCheck/rules/walking.d.ts +3 -0
- package/dist/mapCheck.d.ts +23 -0
- package/dist/mapFields.d.ts +364 -0
- package/dist/mapFile.d.ts +23 -0
- package/dist/mapMeasure.d.ts +95 -0
- package/dist/mapMerge.d.ts +19 -0
- package/dist/mapObjectives.d.ts +82 -0
- package/dist/mapObjects.d.ts +1 -0
- package/dist/math.d.ts +44 -0
- package/dist/messages.d.ts +150 -0
- package/dist/missionRules-C-bGxm0Q.js +523 -0
- package/dist/missionRules-C-bGxm0Q.js.map +1 -0
- package/dist/missionRules.d.ts +179 -0
- package/dist/mods.d.ts +146 -0
- package/dist/names.d.ts +93 -0
- package/dist/navigation/agentParams.d.ts +4 -0
- package/dist/navigation/air.d.ts +89 -0
- package/dist/navigation/builds.d.ts +140 -0
- package/dist/navigation/groundAreas.d.ts +23 -0
- package/dist/navigation/navigation.d.ts +127 -0
- package/dist/navigation/recast.d.ts +214 -0
- package/dist/navigation/sidePaths.d.ts +69 -0
- package/dist/navigation/sized.d.ts +1 -0
- package/dist/navigation-worker.js +11 -0
- package/dist/navigation-worker.js.map +1 -0
- package/dist/nearest.d.ts +8 -0
- package/dist/noise.d.ts +12 -0
- package/dist/objectives.d.ts +93 -0
- package/dist/orders/basic.d.ts +96 -0
- package/dist/orders/build.d.ts +91 -0
- package/dist/orders/cast.d.ts +105 -0
- package/dist/orders/facts.d.ts +14 -0
- package/dist/orders/harvest.d.ts +94 -0
- package/dist/orders/idle.d.ts +7 -0
- package/dist/orders/items.d.ts +14 -0
- package/dist/orders/queue.d.ts +24 -0
- package/dist/pack.schema.json +6621 -0
- package/dist/packs/director/index.d.ts +81 -0
- package/dist/packs/heroes/campaign.d.ts +137 -0
- package/dist/packs/heroes/carry.d.ts +59 -0
- package/dist/packs/heroes/commands.d.ts +6 -0
- package/dist/packs/heroes/hire.d.ts +9 -0
- package/dist/packs/heroes/index.d.ts +12 -0
- package/dist/packs/heroes/making.d.ts +16 -0
- package/dist/packs/heroes/respawn.d.ts +42 -0
- package/dist/packs/moba/index.d.ts +34 -0
- package/dist/packs/pack.d.ts +84 -0
- package/dist/packs-g5thvmGn.js +3199 -0
- package/dist/packs-g5thvmGn.js.map +1 -0
- package/dist/packs.d.ts +84 -0
- package/dist/paths.d.ts +51 -0
- package/dist/plain.d.ts +17 -0
- package/dist/player.d.ts +117 -0
- package/dist/portals.d.ts +66 -0
- package/dist/prefabs.d.ts +139 -0
- package/dist/presetBuildings.d.ts +52 -0
- package/dist/presetGround.d.ts +22 -0
- package/dist/profiles-B3NS9jwk.js +335 -0
- package/dist/profiles-B3NS9jwk.js.map +1 -0
- package/dist/races.d.ts +136 -0
- package/dist/randomGroups.d.ts +2 -0
- package/dist/registry.d.ts +464 -0
- package/dist/remains.d.ts +119 -0
- package/dist/replication.d.ts +103 -0
- package/dist/rng.d.ts +17 -0
- package/dist/rules.d.ts +395 -0
- package/dist/rulesCheck.d.ts +37 -0
- package/dist/runes.d.ts +41 -0
- package/dist/save.d.ts +277 -0
- package/dist/scenario.d.ts +56 -0
- package/dist/scheduler.d.ts +67 -0
- package/dist/score.d.ts +306 -0
- package/dist/sequences.d.ts +132 -0
- package/dist/server/doorman.d.ts +21 -0
- package/dist/server/gameServer.d.ts +346 -0
- package/dist/server/index.d.ts +24 -0
- package/dist/server/lobby.d.ts +1 -0
- package/dist/server/log.d.ts +13 -0
- package/dist/server/match.d.ts +24 -0
- package/dist/server/mode.d.ts +168 -0
- package/dist/server/navigation-worker.d.ts +1 -0
- package/dist/server/navigation.d.ts +11 -0
- package/dist/server/ops.d.ts +78 -0
- package/dist/server/packs.d.ts +15 -0
- package/dist/server/ratings.d.ts +62 -0
- package/dist/server/relay.d.ts +34 -0
- package/dist/server/rooms.d.ts +162 -0
- package/dist/server/seat.d.ts +2 -0
- package/dist/server/seatSettings.d.ts +15 -0
- package/dist/server/secret.d.ts +5 -0
- package/dist/server/start.d.ts +54 -0
- package/dist/server/websocket.d.ts +74 -0
- package/dist/server.js +2861 -0
- package/dist/server.js.map +1 -0
- package/dist/session/can.d.ts +20 -0
- package/dist/session/commandReplay.d.ts +92 -0
- package/dist/session/debug.d.ts +65 -0
- package/dist/session/delay.d.ts +15 -0
- package/dist/session/delta.d.ts +98 -0
- package/dist/session/entityState.d.ts +1 -0
- package/dist/session/local.d.ts +214 -0
- package/dist/session/memory.d.ts +27 -0
- package/dist/session/protocol.d.ts +1155 -0
- package/dist/session/remote.d.ts +530 -0
- package/dist/session/replay.d.ts +114 -0
- package/dist/session/seed.d.ts +7 -0
- package/dist/session/share.d.ts +78 -0
- package/dist/session/socket.d.ts +8 -0
- package/dist/session/wire.d.ts +153 -0
- package/dist/session/worker.d.ts +227 -0
- package/dist/shared.d.ts +171 -0
- package/dist/sides.d.ts +75 -0
- package/dist/sight.d.ts +27 -0
- package/dist/simulate-oXBiw1Ff.js +167 -0
- package/dist/simulate-oXBiw1Ff.js.map +1 -0
- package/dist/simulate-worker.d.ts +1 -0
- package/dist/simulate-worker.js +28 -0
- package/dist/simulate-worker.js.map +1 -0
- package/dist/simulate.d.ts +154 -0
- package/dist/smart.d.ts +9 -0
- package/dist/spatial.d.ts +62 -0
- package/dist/spawning.d.ts +33 -0
- package/dist/stances.d.ts +76 -0
- package/dist/start.d.ts +71 -0
- package/dist/stats.d.ts +122 -0
- package/dist/summons.d.ts +63 -0
- package/dist/systems/abilities.d.ts +3 -0
- package/dist/systems/combat.d.ts +71 -0
- package/dist/systems/combatTold.d.ts +14 -0
- package/dist/systems/construction.d.ts +34 -0
- package/dist/systems/economy.d.ts +21 -0
- package/dist/systems/fog.d.ts +19 -0
- package/dist/systems/life.d.ts +3 -0
- package/dist/systems/movement.d.ts +105 -0
- package/dist/systems/orders.d.ts +7 -0
- package/dist/systems/production.d.ts +49 -0
- package/dist/systems/productionQueue.d.ts +40 -0
- package/dist/systems/victory.d.ts +14 -0
- package/dist/talk.d.ts +65 -0
- package/dist/tech.d.ts +62 -0
- package/dist/techTree.d.ts +38 -0
- package/dist/terrain.d.ts +173 -0
- package/dist/terrainSave.d.ts +29 -0
- package/dist/testing.d.ts +58 -0
- package/dist/testing.js +822 -0
- package/dist/testing.js.map +1 -0
- package/dist/tiles.d.ts +34 -0
- package/dist/timers.d.ts +146 -0
- package/dist/tomes.d.ts +48 -0
- package/dist/trade.d.ts +28 -0
- package/dist/transport.d.ts +76 -0
- package/dist/tunables.d.ts +45 -0
- package/dist/upkeep.d.ts +16 -0
- package/dist/veterancy.d.ts +80 -0
- package/dist/walls.d.ts +86 -0
- package/dist/world.d.ts +1118 -0
- package/package.json +80 -5
- package/README.md +0 -3
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type { Layer } from '#engine/defs';
|
|
2
|
+
import { type Vec2 } from '#engine/math';
|
|
3
|
+
import type { AiView } from './view';
|
|
4
|
+
/**
|
|
5
|
+
* What the threat map reads at a place: the strength of the friendly units (one's own and allies') and of the enemy
|
|
6
|
+
* units (rivals' and creeps') that can reach it, and the difference
|
|
7
|
+
*
|
|
8
|
+
* @beta
|
|
9
|
+
*/
|
|
10
|
+
export interface Threat {
|
|
11
|
+
/** The strength of one's own and allies' units that reach the place */
|
|
12
|
+
friendly: number;
|
|
13
|
+
/** The strength of rivals' and creeps' units that reach it */
|
|
14
|
+
enemy: number;
|
|
15
|
+
/** `friendly - enemy`: above 0 where one's own side is stronger */
|
|
16
|
+
net: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* A cell of the threat map with what it reads (`ThreatMap.hot`, `cells`)
|
|
20
|
+
*
|
|
21
|
+
* @beta
|
|
22
|
+
*/
|
|
23
|
+
export interface ThreatCell extends Threat {
|
|
24
|
+
/** The middle of the cell */
|
|
25
|
+
at: Vec2;
|
|
26
|
+
col: number;
|
|
27
|
+
row: number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* What a read of the map is for: the layer the thing asked about is on (`ground` when left out: what can reach things
|
|
31
|
+
* on the ground), and whether the enemy structures remembered and out of sight count too (a tower seen before)
|
|
32
|
+
*
|
|
33
|
+
* @beta
|
|
34
|
+
*/
|
|
35
|
+
export interface ThreatQuery {
|
|
36
|
+
layer?: Layer;
|
|
37
|
+
remembered?: boolean;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Where the strength is, on a coarse grid over the map (`AiView.threat`, `Brain.threat`): `at(point)` reads a place,
|
|
41
|
+
* `around(point, radius)` the worst cell near it, `hot()` the cells where the enemy is strongest near what is one's
|
|
42
|
+
* own, `cells()` every cell with something in it (for a drawing of it). Made from the view's picture when first asked,
|
|
43
|
+
* once a think; all zeros for no point, or one off the map, so that a question about "the first base known" needs no
|
|
44
|
+
* guard
|
|
45
|
+
*
|
|
46
|
+
* @beta
|
|
47
|
+
*/
|
|
48
|
+
export declare class ThreatMap {
|
|
49
|
+
/** The picture it is made from */
|
|
50
|
+
readonly view: AiView;
|
|
51
|
+
/** Cells across and down, and the side of one */
|
|
52
|
+
readonly cols: number;
|
|
53
|
+
readonly rows: number;
|
|
54
|
+
readonly cell = 8;
|
|
55
|
+
private seen;
|
|
56
|
+
private withRemembered;
|
|
57
|
+
constructor(
|
|
58
|
+
/** The picture it is made from */
|
|
59
|
+
view: AiView);
|
|
60
|
+
/** The grids of a reading, made when first asked */
|
|
61
|
+
private grids;
|
|
62
|
+
/** One pass over the picture: each fighter painted onto the cells it reaches, on the layers it can hit */
|
|
63
|
+
private build;
|
|
64
|
+
/** A unit's strength onto the cells within its reach: in full within its range, fading to nothing at the edge */
|
|
65
|
+
private paint;
|
|
66
|
+
private col;
|
|
67
|
+
private row;
|
|
68
|
+
/** Whether a point is on the map */
|
|
69
|
+
private onMap;
|
|
70
|
+
private read;
|
|
71
|
+
/**
|
|
72
|
+
* What reaches a place: the friendly and the enemy strength at its cell, on a layer (`ground` when left out). All
|
|
73
|
+
* zeros for no point or one off the map
|
|
74
|
+
*/
|
|
75
|
+
at(point: Vec2 | undefined, query?: ThreatQuery): Threat;
|
|
76
|
+
/** The worst cell within a distance of a point: the one the most enemy strength reaches. Zeros off the map */
|
|
77
|
+
around(point: Vec2 | undefined, radius: number, query?: ThreatQuery): Threat;
|
|
78
|
+
/**
|
|
79
|
+
* Where the enemy is strongest near what is one's own: the cells that enemy strength reaches and that hold a unit or
|
|
80
|
+
* building of the player's (an ally's with `owner`), the hottest first. A raid at an expansion reads here while the
|
|
81
|
+
* main is quiet
|
|
82
|
+
*/
|
|
83
|
+
hot(query?: ThreatQuery & {
|
|
84
|
+
owner?: number;
|
|
85
|
+
}): ThreatCell[];
|
|
86
|
+
/** Every cell that any strength reaches on a layer, in the grid's order: for a drawing of the map */
|
|
87
|
+
cells(query?: ThreatQuery): ThreatCell[];
|
|
88
|
+
private cellOf;
|
|
89
|
+
/** Whether a reading has been made this think: for the timing and the debug tools */
|
|
90
|
+
get built(): boolean;
|
|
91
|
+
}
|
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
import type { Component } from '#engine/components';
|
|
2
|
+
import type { ResourceKind, UnitTypeDef } from '#engine/defs';
|
|
3
|
+
import type { PlayerId } from '#engine/entity';
|
|
4
|
+
import type { EventKey } from '#engine/events';
|
|
5
|
+
import type { Lane } from '#engine/lanes';
|
|
6
|
+
import type { MapRegion } from '#engine/map';
|
|
7
|
+
import { type Vec2 } from '#engine/math';
|
|
8
|
+
import type { Message } from '#engine/messages';
|
|
9
|
+
import type { ObjectiveState } from '#engine/objectives';
|
|
10
|
+
import type { Registry } from '#engine/registry';
|
|
11
|
+
import type { CampInfo, EntityState, GameSession, GroundItemState, HeroSummary, MineInfo, PlayerState, SessionEvent, Snapshot } from '#engine/session/protocol';
|
|
12
|
+
import { type AiRole, type Roles, type RolesFinder } from './roles';
|
|
13
|
+
import { Strength, type StrengthFormula } from './strength';
|
|
14
|
+
import { ThreatMap } from './threat';
|
|
15
|
+
/**
|
|
16
|
+
* A set of entities as the view gives them, in the snapshot's order, with the questions a brain asks as methods, each
|
|
17
|
+
* giving a set again, so that they chain: `ai.view.mine.withRole('worker').idle()`, `ai.view.enemies.near(home,
|
|
18
|
+
* 20).fighters()`. It reads as an array (`length`, `for..of`, `map`, `filter`, `find`, `some`, `every`, `forEach`,
|
|
19
|
+
* `first`, `at`; `items` is the plain array) but is not one: `map` and `filter` give plain arrays, `where` gives a set.
|
|
20
|
+
* (Not an `Array` subclass on purpose: the engines run `filter` and `find` on one several times slower, species
|
|
21
|
+
* lookup, and a think asks dozens.) A set is of one think: it reads the view it came from
|
|
22
|
+
*
|
|
23
|
+
* @beta
|
|
24
|
+
*/
|
|
25
|
+
export declare class UnitSet implements Iterable<EntityState> {
|
|
26
|
+
/** The view the set reads: the definitions, the roles, the grid */
|
|
27
|
+
readonly view: AiView;
|
|
28
|
+
/** The entities, as a plain array, in the snapshot's order */
|
|
29
|
+
readonly items: readonly EntityState[];
|
|
30
|
+
/** What this set remembers beside what is in sight (`known`): the structures seen before, for the view's own sets */
|
|
31
|
+
private readonly remembered;
|
|
32
|
+
/** The answers to the questions that are asked again and again, by their name */
|
|
33
|
+
private memo;
|
|
34
|
+
private idSet;
|
|
35
|
+
private strengthSum;
|
|
36
|
+
constructor(
|
|
37
|
+
/** The view the set reads: the definitions, the roles, the grid */
|
|
38
|
+
view: AiView,
|
|
39
|
+
/** The entities, as a plain array, in the snapshot's order */
|
|
40
|
+
items?: readonly EntityState[], remembered?: EntityState[]);
|
|
41
|
+
/** How many */
|
|
42
|
+
get length(): number;
|
|
43
|
+
[Symbol.iterator](): Iterator<EntityState>;
|
|
44
|
+
/** The first of them: none in an empty set */
|
|
45
|
+
first(): EntityState | undefined;
|
|
46
|
+
/** Some of them, as an array's `slice` takes them: as a set */
|
|
47
|
+
slice(start?: number, end?: number): UnitSet;
|
|
48
|
+
/** The one at an index, from the end for a negative one */
|
|
49
|
+
at(index: number): EntityState | undefined;
|
|
50
|
+
/** As an array does: a plain array */
|
|
51
|
+
map<T>(fn: (entity: EntityState, index: number) => T): T[];
|
|
52
|
+
/** As an array does: a plain array. `where` gives a set */
|
|
53
|
+
filter(fn: (entity: EntityState, index: number) => unknown): EntityState[];
|
|
54
|
+
find(fn: (entity: EntityState, index: number) => unknown): EntityState | undefined;
|
|
55
|
+
some(fn: (entity: EntityState, index: number) => unknown): boolean;
|
|
56
|
+
every(fn: (entity: EntityState, index: number) => unknown): boolean;
|
|
57
|
+
forEach(fn: (entity: EntityState, index: number) => void): void;
|
|
58
|
+
/** A set of these, of the same view */
|
|
59
|
+
private make;
|
|
60
|
+
/** The answer to a question asked by name, worked out once */
|
|
61
|
+
private cached;
|
|
62
|
+
/** Those that satisfy a predicate, as a set */
|
|
63
|
+
where(predicate: (entity: EntityState, def: UnitTypeDef) => boolean): UnitSet;
|
|
64
|
+
/** Those of a unit type, or that count as it (`UnitTypeDef.provides`: a keep is a town hall too) */
|
|
65
|
+
ofType(type: string): UnitSet;
|
|
66
|
+
/** Those whose type has a role (`AiRole`: `'worker'`, `'hall'`, a game's own word) */
|
|
67
|
+
withRole(role: AiRole): UnitSet;
|
|
68
|
+
/** Those whose type has a tag: the kit's (`ranged`, `melee`, `hitsAir`) or the game's (`UnitTypeDef.ai.tags`) */
|
|
69
|
+
withTag(tag: string): UnitSet;
|
|
70
|
+
/** Those that fight: soldiers and heroes */
|
|
71
|
+
fighters(): UnitSet;
|
|
72
|
+
/** Those that gather and build (role `worker`) */
|
|
73
|
+
workers(): UnitSet;
|
|
74
|
+
/** The heroes among them */
|
|
75
|
+
heroes(): UnitSet;
|
|
76
|
+
/** The buildings among them, under construction too (`finished` leaves those out) */
|
|
77
|
+
buildings(): UnitSet;
|
|
78
|
+
/** The units among them: what moves, buildings and resources left out */
|
|
79
|
+
units(): UnitSet;
|
|
80
|
+
/** Those that stand finished: not under construction (a building turning into another type stands) */
|
|
81
|
+
finished(): UnitSet;
|
|
82
|
+
/** Those of mine with nothing to do: no order, and not inside something (a worker in a mine). Only one's own say what they do */
|
|
83
|
+
idle(): UnitSet;
|
|
84
|
+
/** Those in sight now: a structure seen before and out of sight is not (`EntityState.visible`) */
|
|
85
|
+
visible(): UnitSet;
|
|
86
|
+
/** Those with health left */
|
|
87
|
+
alive(): UnitSet;
|
|
88
|
+
/** Deposits of a resource with something left in them (a gold mine, a tree): for the view's `resources` */
|
|
89
|
+
ofResource(kind: ResourceKind): UnitSet;
|
|
90
|
+
/** Those of a player */
|
|
91
|
+
ofOwner(player: PlayerId): UnitSet;
|
|
92
|
+
/**
|
|
93
|
+
* Those within a distance of a point, in the snapshot's order. A big set is asked of the view's grid, a small one is
|
|
94
|
+
* scanned: the answer is the same
|
|
95
|
+
*/
|
|
96
|
+
near(point: Vec2, radius: number): UnitSet;
|
|
97
|
+
/** The one nearest a point: none in an empty set. The first of two as near */
|
|
98
|
+
nearest(point: Vec2): EntityState | undefined;
|
|
99
|
+
/** The middle of them: none for an empty set */
|
|
100
|
+
centre(): Vec2 | undefined;
|
|
101
|
+
/**
|
|
102
|
+
* How strong they are together: the strength of each (`Strength.of`: by its stats and the health it has left),
|
|
103
|
+
* summed. 0 for what does not fight. Against someone in particular, ask `view.strength.odds(these, those)`
|
|
104
|
+
*/
|
|
105
|
+
strength(): number;
|
|
106
|
+
/** Their ids, as a set: for "is it one of these" */
|
|
107
|
+
ids(): ReadonlySet<number>;
|
|
108
|
+
/** Whether an entity, by id, is one of these */
|
|
109
|
+
has(id: number): boolean;
|
|
110
|
+
/** These and another set's, together, in the snapshot's order, each once */
|
|
111
|
+
and(other: UnitSet): UnitSet;
|
|
112
|
+
/**
|
|
113
|
+
* These and what is remembered of them beside what is in sight: for `view.enemies`, the enemy structures seen before
|
|
114
|
+
* and out of sight now (`visible: false`), which may be gone. Ask it of the view's set before narrowing it
|
|
115
|
+
* (`view.enemies.known().buildings()`): a narrowed set remembers nothing more
|
|
116
|
+
*/
|
|
117
|
+
known(): UnitSet;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* The player a brain plays, as its picture of the game shows them: what the snapshot has of one's own player
|
|
121
|
+
* (`PlayerState.own`), beside who they are. Mutable for the think: a module that sends a `train` bumps `supplyUsed`
|
|
122
|
+
* itself, so that the next module does not queue past the cap before the command lands
|
|
123
|
+
*
|
|
124
|
+
* @beta
|
|
125
|
+
*/
|
|
126
|
+
export interface Me {
|
|
127
|
+
id: PlayerId;
|
|
128
|
+
name: string;
|
|
129
|
+
team: number;
|
|
130
|
+
/** The race they play (`raceOf`): left out in a game without races */
|
|
131
|
+
race?: string;
|
|
132
|
+
defeated: boolean;
|
|
133
|
+
/** What they have of each resource, by resource id */
|
|
134
|
+
resources: Record<ResourceKind, number>;
|
|
135
|
+
supplyUsed: number;
|
|
136
|
+
supplyCap: number;
|
|
137
|
+
/** The game's other pools of supply, by name (`GameRules.supply.pools`) */
|
|
138
|
+
supplies?: Record<string, {
|
|
139
|
+
used: number;
|
|
140
|
+
cap: number;
|
|
141
|
+
}>;
|
|
142
|
+
/** What the size of the army costs in income */
|
|
143
|
+
upkeep: {
|
|
144
|
+
tier: number;
|
|
145
|
+
name: string;
|
|
146
|
+
income: number;
|
|
147
|
+
};
|
|
148
|
+
upgrades: Record<string, number>;
|
|
149
|
+
researching: string[];
|
|
150
|
+
/** Types of the finished buildings the player has, with what those count as */
|
|
151
|
+
tech: string[];
|
|
152
|
+
heroes: HeroSummary[];
|
|
153
|
+
/** What the player is set to do, in a mission. Empty in a game without objectives */
|
|
154
|
+
objectives: ObjectiveState[];
|
|
155
|
+
/** What the game's `requirement` hook decided, where it differs from what the requirements say (`PlayerState.own.unlocks`) */
|
|
156
|
+
unlocks?: Record<string, Message | null>;
|
|
157
|
+
/** What the game's `available` hook decided, where it differs from what their race says (`PlayerState.own.availability`) */
|
|
158
|
+
availability?: Record<string, boolean>;
|
|
159
|
+
/**
|
|
160
|
+
* What the player gathers of each resource a minute, of late, as the brain's knowledge works it out
|
|
161
|
+
* (`Knowledge.own.income`): set by the brain after the view is made; left out for a view of no brain's
|
|
162
|
+
*/
|
|
163
|
+
income?: Record<ResourceKind, number>;
|
|
164
|
+
/**
|
|
165
|
+
* What is free to spend this think, by resource: the resources less what is promised and held, less what the think
|
|
166
|
+
* spent so far (the brain's purse, `ai.purse`). Set by the brain after the view is made; left out for a view of no brain's
|
|
167
|
+
*/
|
|
168
|
+
purse?: Readonly<Record<ResourceKind, number>>;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* One of a player's bases, as the view clusters its buildings: around each building that takes deposits (a hall, what
|
|
172
|
+
* stands on a mine), or around any building where none does
|
|
173
|
+
*
|
|
174
|
+
* @beta
|
|
175
|
+
*/
|
|
176
|
+
export interface Base {
|
|
177
|
+
/** Where it is: the building it is around */
|
|
178
|
+
at: Vec2;
|
|
179
|
+
/** The building it is around: a hall where there is one */
|
|
180
|
+
centre: EntityState;
|
|
181
|
+
/** Its buildings, the centre among them */
|
|
182
|
+
buildings: UnitSet;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* The events of a think, by kind (`AiView.events`): what happened in the tick of the picture that cannot be read from
|
|
186
|
+
* the state (deaths, damage, pings, the game's own)
|
|
187
|
+
*
|
|
188
|
+
* @beta
|
|
189
|
+
*/
|
|
190
|
+
export declare class ViewEvents {
|
|
191
|
+
/** Every event of the tick, in order */
|
|
192
|
+
readonly all: readonly SessionEvent[];
|
|
193
|
+
private byType;
|
|
194
|
+
constructor(
|
|
195
|
+
/** Every event of the tick, in order */
|
|
196
|
+
all: readonly SessionEvent[]);
|
|
197
|
+
/** The events of one kind, typed: `events.of('death')`, `events.of('ping')` */
|
|
198
|
+
of<T extends SessionEvent['type']>(type: T): Extract<SessionEvent, {
|
|
199
|
+
type: T;
|
|
200
|
+
}>[];
|
|
201
|
+
/** What an event of the game's own said this tick (`defineEvent`, replicated to this player), each time it was emitted */
|
|
202
|
+
game<T>(key: EventKey<T>): T[];
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* What the view is handed beside the snapshot: the last think's view, whose roles it keeps where the game's
|
|
206
|
+
* definitions stand, and a game's own way of finding the roles (`AiOptions.roles`)
|
|
207
|
+
*
|
|
208
|
+
* @beta
|
|
209
|
+
*/
|
|
210
|
+
export interface ViewOptions {
|
|
211
|
+
/** The view of the think before: what cost and did not change is kept from it (the roles, the player's reach) */
|
|
212
|
+
before?: AiView;
|
|
213
|
+
/** A game's own say on what unit types are for, in place of the kit's inference (`AiOptions.roles`) */
|
|
214
|
+
roles?: RolesFinder;
|
|
215
|
+
/** A game's own formula for how strong a unit is, in place of the kit's (`AiOptions.strength`, `BrainDef.strength`) */
|
|
216
|
+
strength?: StrengthFormula;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* A computer player's reading of its picture of the game (`Brain.view`): the snapshot of its seat, indexed once a
|
|
220
|
+
* think and queried as sets (`UnitSet`): `mine`, `allies`, `enemies` (what is in sight now; `enemies.known()` adds
|
|
221
|
+
* the structures remembered), `hostile` (enemies and creeps), `creeps`, `neutral`, `resources`, `all`; the player's
|
|
222
|
+
* own state (`me`); what unit types are for (`roles`, `typesOf`); where things are (`near`, `home`, `bases`, `mines`,
|
|
223
|
+
* `camps`, `regions`); how strong things are (`strength`: `odds`, `matchup`, `counterFor`) and where the strength
|
|
224
|
+
* is (`threat`, the map made when first asked); what the game tells this player (`report`, `component`,
|
|
225
|
+
* `events.game`); and the map's facts (`canPlace`, `findPath`, `cellAt`). Made from the snapshot as the think begins; a set of
|
|
226
|
+
* it is good for the think
|
|
227
|
+
*
|
|
228
|
+
* @beta
|
|
229
|
+
*/
|
|
230
|
+
export declare class AiView {
|
|
231
|
+
/** The picture it reads: the snapshot of the seat, plain data, the only input a brain has */
|
|
232
|
+
readonly snapshot: Snapshot;
|
|
233
|
+
/** The seat, for the map's facts: the ground, the regions, the mines, the camps */
|
|
234
|
+
readonly session: GameSession;
|
|
235
|
+
/** The game's definitions, as the seat has them */
|
|
236
|
+
readonly registry: Registry;
|
|
237
|
+
/** The player it reads for */
|
|
238
|
+
readonly playerId: PlayerId;
|
|
239
|
+
/** Every entity the player knows of, in the snapshot's order: in sight, and the structures remembered */
|
|
240
|
+
readonly all: UnitSet;
|
|
241
|
+
/** The player's own units and buildings */
|
|
242
|
+
readonly mine: UnitSet;
|
|
243
|
+
/** The allies' units and buildings (one's own left out) */
|
|
244
|
+
readonly allies: UnitSet;
|
|
245
|
+
/** The enemies' units and buildings in sight now, creeps left out. `enemies.known()` adds their structures seen before */
|
|
246
|
+
readonly enemies: UnitSet;
|
|
247
|
+
/** Whatever attacks the player and is in sight: enemies and creeps */
|
|
248
|
+
readonly hostile: UnitSet;
|
|
249
|
+
/** The creeps in sight: hostile to everyone, no one's rival */
|
|
250
|
+
readonly creeps: UnitSet;
|
|
251
|
+
/** What is nobody's and not a resource, in sight: a shop, a neutral building. `neutral.known()` adds those seen before */
|
|
252
|
+
readonly neutral: UnitSet;
|
|
253
|
+
/** The deposits the player knows of: mines and trees in sight, and those seen before (`ofResource(kind)` for one kind) */
|
|
254
|
+
readonly resources: UnitSet;
|
|
255
|
+
/** Every player, as the snapshot has them */
|
|
256
|
+
readonly players: readonly PlayerState[];
|
|
257
|
+
/** The player a brain plays: resources, supply, tech, heroes, objectives. Mutable for the think */
|
|
258
|
+
readonly me: Me;
|
|
259
|
+
/** What happened in the tick of the picture, by kind */
|
|
260
|
+
readonly events: ViewEvents;
|
|
261
|
+
/** What unit types are for, by the game's definitions: found once, kept while they stand */
|
|
262
|
+
readonly roles: Roles;
|
|
263
|
+
/** The unit types the player has or can come to make: what the roles are narrowed to for it (`typesOf`) */
|
|
264
|
+
readonly reachable: ReadonlySet<string>;
|
|
265
|
+
/**
|
|
266
|
+
* How strong things are: a unit, a group, one force against another (`odds`), what answers what (`counterFor`). The
|
|
267
|
+
* kit's formula unless the brain was given one; what a type's numbers come to is kept between thinks
|
|
268
|
+
*/
|
|
269
|
+
readonly strength: Strength;
|
|
270
|
+
private threatMap;
|
|
271
|
+
private readonly grid;
|
|
272
|
+
private readonly byIdMap;
|
|
273
|
+
private readonly indexById;
|
|
274
|
+
private readonly playerById;
|
|
275
|
+
private readonly namesMap;
|
|
276
|
+
private readonly typesByRole;
|
|
277
|
+
/** The race the view's reach was found for: a player given another race finds it anew */
|
|
278
|
+
private readonly race;
|
|
279
|
+
private basesFound;
|
|
280
|
+
private lanesFound;
|
|
281
|
+
constructor(
|
|
282
|
+
/** The picture it reads: the snapshot of the seat, plain data, the only input a brain has */
|
|
283
|
+
snapshot: Snapshot,
|
|
284
|
+
/** The seat, for the map's facts: the ground, the regions, the mines, the camps */
|
|
285
|
+
session: GameSession, options?: ViewOptions);
|
|
286
|
+
/**
|
|
287
|
+
* Where the strength is: an influence map over the picture, the friendly and the enemy strength that reaches each
|
|
288
|
+
* cell of a coarse grid, by layer (`threat.at(point)`, `around`, `hot`). Made when first asked, once a think
|
|
289
|
+
*/
|
|
290
|
+
get threat(): ThreatMap;
|
|
291
|
+
/** The tick of the picture */
|
|
292
|
+
get tick(): number;
|
|
293
|
+
/** Seconds into the game, as of the picture */
|
|
294
|
+
get time(): number;
|
|
295
|
+
/** Items lying on the ground where the player sees it */
|
|
296
|
+
get items(): readonly GroundItemState[];
|
|
297
|
+
/** What the game tells the player about itself (`GameModule.report`): a wave number, a score */
|
|
298
|
+
get report(): Record<string, unknown> | undefined;
|
|
299
|
+
/** An entity the player knows of, by id: none for one gone, or never seen */
|
|
300
|
+
byId(id: number | undefined): EntityState | undefined;
|
|
301
|
+
/** The definition of an entity's type */
|
|
302
|
+
def(entity: EntityState): UnitTypeDef;
|
|
303
|
+
/** A player, by id */
|
|
304
|
+
player(id: PlayerId): PlayerState | undefined;
|
|
305
|
+
/** What an entity's owner is to the player: `self`, `ally`, `enemy`, `neutral`. Creeps are `enemy` */
|
|
306
|
+
relation(entity: EntityState): PlayerState['relation'] | undefined;
|
|
307
|
+
/** Whether an entity is a rival's, or a creep */
|
|
308
|
+
isHostile(entity: EntityState): boolean;
|
|
309
|
+
/** Whether an entity is a creep's */
|
|
310
|
+
isCreep(entity: EntityState): boolean;
|
|
311
|
+
/** Whether an entity is the player's own or an ally's */
|
|
312
|
+
isFriendly(entity: EntityState): boolean;
|
|
313
|
+
/** The roles of an entity's type, or of a type by id */
|
|
314
|
+
roleOf(entity: EntityState | string): readonly AiRole[];
|
|
315
|
+
/** Whether an entity's type, or a type by id, has a role */
|
|
316
|
+
hasRole(entity: EntityState | string, role: AiRole): boolean;
|
|
317
|
+
/**
|
|
318
|
+
* The unit types with a role that are the player's own: those it has or can come to make (`reachable`), in the
|
|
319
|
+
* game's order, so that the first of a kind is the one meant first. A game of two races gives each player its own
|
|
320
|
+
*/
|
|
321
|
+
typesOf(role: AiRole): readonly UnitTypeDef[];
|
|
322
|
+
/** Whether the player has the finished buildings something asks for (`UnitTypeDef.requires`) */
|
|
323
|
+
has(requires: readonly string[] | undefined): boolean;
|
|
324
|
+
/** The player's home: its first hall, or its first building where it has no hall. None with no buildings */
|
|
325
|
+
home(): EntityState | undefined;
|
|
326
|
+
/**
|
|
327
|
+
* The player's bases: its buildings clustered around what takes deposits (halls, what stands on a mine), each to
|
|
328
|
+
* the nearest of those within reach; and where there is nothing that takes deposits (a game with no economy), around
|
|
329
|
+
* any building, the clusters made as the buildings come. Home first
|
|
330
|
+
*/
|
|
331
|
+
bases(): readonly Base[];
|
|
332
|
+
/** The deposits near a base, in sight or remembered: what it gathers from */
|
|
333
|
+
resourcesNear(base: Base | Vec2, radius?: number): UnitSet;
|
|
334
|
+
/**
|
|
335
|
+
* Where the game's money is mined, as the map shows them, under the fog too (`GameSession.mines`): what a computer
|
|
336
|
+
* player looks to for another hall. Where the session does not say, the deposits of the money it knows of
|
|
337
|
+
*/
|
|
338
|
+
mines(): readonly MineInfo[];
|
|
339
|
+
/** The creep camps of the map: where they are is part of the map, which everyone knows */
|
|
340
|
+
camps(): readonly CampInfo[];
|
|
341
|
+
/**
|
|
342
|
+
* The lanes of the map (`GameSession.lanes`: its paths with a spawner of each side at their ends), as the map shows
|
|
343
|
+
* them: none where the session does not say, or the map has none. Read once a think
|
|
344
|
+
*/
|
|
345
|
+
lanes(): readonly Lane[];
|
|
346
|
+
/** The regions of the map, by name, as the map was made */
|
|
347
|
+
get regions(): readonly MapRegion[];
|
|
348
|
+
/** A region of the map, by name */
|
|
349
|
+
region(name: string): MapRegion | undefined;
|
|
350
|
+
/** Whether a point is in a named region of the map. False for a region the map does not have */
|
|
351
|
+
inRegion(name: string, point: Vec2): boolean;
|
|
352
|
+
/** An entity the map or the rules named (`world.named`), where the player knows of it: "the gate", "the hero" */
|
|
353
|
+
named(name: string): EntityState | undefined;
|
|
354
|
+
/** What the game replicates to this player of an entity (`Component.replicate`), with the component's type */
|
|
355
|
+
component<T, S = T>(entity: EntityState, component: Component<T, S>): S | undefined;
|
|
356
|
+
/** Whether the player could build this here, as far as it can tell: no on ground it has not explored */
|
|
357
|
+
canPlace(unitType: string, point: Vec2): boolean;
|
|
358
|
+
/** The value of one of the game's layers of cells at a point (`Terrain.cells`, `CellLayerDef`): 0 where it is not painted */
|
|
359
|
+
cellAt(layer: string, x: number, z: number): number;
|
|
360
|
+
/** One of the game's layers of cells whole, row by row (`Terrain.cells`), to read and not to change: none where nothing is painted */
|
|
361
|
+
cells(layer: string): Readonly<Uint8Array> | undefined;
|
|
362
|
+
/** The route a unit would take, over the ground the player knows */
|
|
363
|
+
findPath(from: Vec2, to: Vec2, flying?: boolean): Vec2[] | null;
|
|
364
|
+
/** What the view found of the roles, for the debug tools: each role and its types among the player's own */
|
|
365
|
+
inspect(): Record<string, unknown>;
|
|
366
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { type Vec2 } from '#engine/math';
|
|
2
|
+
import { type Brain } from './brain';
|
|
3
|
+
import { type AiModuleDef } from './module';
|
|
4
|
+
import { type AiCondition } from './rules';
|
|
5
|
+
/**
|
|
6
|
+
* What a wave is made of: so many of each unit type (by id) or role (`caster`, a game's own), by name, under a condition
|
|
7
|
+
*
|
|
8
|
+
* @beta
|
|
9
|
+
*/
|
|
10
|
+
export interface AttackGroup {
|
|
11
|
+
/** Its name: what a wave names it by */
|
|
12
|
+
id: string;
|
|
13
|
+
/** So many of each unit type or role: `{ footman: 4, rifleman: 2 }` */
|
|
14
|
+
units: Record<string, number>;
|
|
15
|
+
/** Only while this holds: a wave of a group whose condition fails is skipped as its own would be */
|
|
16
|
+
when?: AiCondition;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Where a wave goes: their base nearest home, their weakest (the fewest towers and army seen there), an expansion of
|
|
20
|
+
* theirs, their army as last seen, a place, or a function of the brain
|
|
21
|
+
*
|
|
22
|
+
* @beta
|
|
23
|
+
*/
|
|
24
|
+
export type WaveTarget = 'nearestBase' | 'weakestBase' | 'expansion' | 'army' | Vec2 | ((ai: Brain) => Vec2 | undefined);
|
|
25
|
+
/**
|
|
26
|
+
* One wave (the classic attack wave): its group, when it goes, how much of it is enough, how long it gathers, whether it
|
|
27
|
+
* goes again, together or not, and where to
|
|
28
|
+
*
|
|
29
|
+
* @beta
|
|
30
|
+
*/
|
|
31
|
+
export interface AttackWave {
|
|
32
|
+
/** Its group: a group's name (`WavesOptions.groups`), or the units in place (`{ footman: 4 }`) */
|
|
33
|
+
group: string | Record<string, number>;
|
|
34
|
+
/** Seconds after the wave before it (after the start, for the first) before it may go: 0 when left out */
|
|
35
|
+
after?: number;
|
|
36
|
+
/** The share of its group that is enough to go with, 0 to 1: all of it when left out */
|
|
37
|
+
minForces?: number;
|
|
38
|
+
/** Seconds it gathers at the rally before it goes, whoever is late: 15 when left out */
|
|
39
|
+
gatherFor?: number;
|
|
40
|
+
/** Whether it goes again once sent: `true` for ever, a number for so many times in all. Once when left out */
|
|
41
|
+
repeat?: boolean | number;
|
|
42
|
+
/** Only when this holds as its turn comes: a wave whose condition fails is skipped */
|
|
43
|
+
when?: AiCondition;
|
|
44
|
+
/** Whether it waits for its team's attack together (`TeamOptions.together`, C5) */
|
|
45
|
+
together?: boolean;
|
|
46
|
+
/** Where it goes: their base nearest home when left out */
|
|
47
|
+
target?: WaveTarget;
|
|
48
|
+
/** Where it gathers: a place, or a name the map or the rules gave. A little out of home towards the target when left out */
|
|
49
|
+
rally?: Vec2 | string;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* How a brain sends its waves (`BrainDef.waves`; the seat's `AiOptions.waves` and `groups`, the data of it, go over)
|
|
53
|
+
*
|
|
54
|
+
* @beta
|
|
55
|
+
*/
|
|
56
|
+
export interface WavesOptions {
|
|
57
|
+
/** The groups waves are made of, by name */
|
|
58
|
+
groups?: AttackGroup[];
|
|
59
|
+
/** The waves, in order, or a function giving the wave whose turn it is (by its index), none for no more */
|
|
60
|
+
waves?: AttackWave[] | ((ai: Brain, index: number) => AttackWave | undefined);
|
|
61
|
+
/** Whether a wave's group is trained (wants of the production plan): yes when left out. No for units that are given (a lanes game) */
|
|
62
|
+
train?: boolean;
|
|
63
|
+
/** How important a wave's units are to the purse, as wants: 30 when left out (under a hall, a barracks, a hero) */
|
|
64
|
+
priority?: number;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* What the waves module remembers between thinks, as a save keeps it
|
|
68
|
+
*
|
|
69
|
+
* @beta
|
|
70
|
+
*/
|
|
71
|
+
export interface WavesMemory {
|
|
72
|
+
v: 1;
|
|
73
|
+
/** The index of the wave whose turn it is: the waves sent and skipped before it */
|
|
74
|
+
index: number;
|
|
75
|
+
/** Where in the list it is (for a list), and how many times the wave there went */
|
|
76
|
+
entry: number;
|
|
77
|
+
went: number;
|
|
78
|
+
/** The tick the last wave went at (or was skipped at): what the next one's `after` counts from */
|
|
79
|
+
last: number;
|
|
80
|
+
/** The waves sent, the last ten: index, squad, size, target, tick */
|
|
81
|
+
sent: {
|
|
82
|
+
index: number;
|
|
83
|
+
squad: string;
|
|
84
|
+
size: number;
|
|
85
|
+
at: Vec2;
|
|
86
|
+
tick: number;
|
|
87
|
+
}[];
|
|
88
|
+
/** How many were skipped, their condition failing */
|
|
89
|
+
skipped: number;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* The waves as the report shows them (`AiReport.waves`): the wave whose turn it is, its group as it stands, when it may go;
|
|
93
|
+
* the waves sent
|
|
94
|
+
*
|
|
95
|
+
* @beta
|
|
96
|
+
*/
|
|
97
|
+
export interface WavesReport {
|
|
98
|
+
index: number;
|
|
99
|
+
current?: {
|
|
100
|
+
units: Record<string, [free: number, wanted: number]>;
|
|
101
|
+
in: number;
|
|
102
|
+
ready: boolean;
|
|
103
|
+
status: string;
|
|
104
|
+
};
|
|
105
|
+
sent: {
|
|
106
|
+
index: number;
|
|
107
|
+
squad: string;
|
|
108
|
+
size: number;
|
|
109
|
+
at: [number, number];
|
|
110
|
+
tick: number;
|
|
111
|
+
}[];
|
|
112
|
+
skipped: number;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* The waves module: the wave whose turn it is, each think (`ai.waves.think`): its group wanted, sent once enough of it is
|
|
116
|
+
* free and its time has come, gathering at the rally, then attacking. Idle without waves given. With how it sends waves
|
|
117
|
+
* where the brain's definition and the seat's options say nothing (`WavesOptions`)
|
|
118
|
+
*
|
|
119
|
+
* @beta
|
|
120
|
+
*/
|
|
121
|
+
export declare const waves: (options?: WavesOptions) => AiModuleDef;
|
|
122
|
+
declare module './area' {
|
|
123
|
+
interface AreaMemories {
|
|
124
|
+
waves?: WavesMemory;
|
|
125
|
+
}
|
|
126
|
+
}
|