@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,429 @@
|
|
|
1
|
+
import type { OrderInit } from '#engine/registry';
|
|
2
|
+
import type { AiArea } from './area';
|
|
3
|
+
import { type Vec2 } from '#engine/math';
|
|
4
|
+
import type { EntityState } from '#engine/session/protocol';
|
|
5
|
+
import { type Brain } from './brain';
|
|
6
|
+
import { type AiModuleDef } from './module';
|
|
7
|
+
import { UnitSet } from './view';
|
|
8
|
+
import type { TaskCommon, TaskData, TaskDef, TaskDone, TaskOrder, TaskState } from './task';
|
|
9
|
+
/**
|
|
10
|
+
* How a squad behaves around its task (`SquadsOptions`, `ai.squads.make(name, units, options)`): when it regroups,
|
|
11
|
+
* reinforces, retreats. Plain data, kept in a save
|
|
12
|
+
*
|
|
13
|
+
* @beta
|
|
14
|
+
*/
|
|
15
|
+
export interface SquadOptions {
|
|
16
|
+
/**
|
|
17
|
+
* How far from its middle a unit may be before it counts as strayed: what a regroup brings in. Grows with the squad
|
|
18
|
+
* when left out (8, and three times the square root of its size above that: 12 for sixteen units)
|
|
19
|
+
*/
|
|
20
|
+
spread?: number;
|
|
21
|
+
/** The share of its units strayed (`spread`) at which it stops to regroup, on its way and out of a fight: 0.4. `false` never */
|
|
22
|
+
regroupWhen?: number | false;
|
|
23
|
+
/** Whether it makes up what it lost since its task began from the pool (the idle fighters nothing holds): no when left out */
|
|
24
|
+
reinforce?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Its odds in a fight (`Strength.odds`) under which it falls back home, away from home: 0.3. `false` fights on to the
|
|
27
|
+
* last (a mission's guards)
|
|
28
|
+
*/
|
|
29
|
+
retreatAt?: number | false;
|
|
30
|
+
/** How near home it fights on whatever the odds: there is nowhere to fall back to. 20 when left out */
|
|
31
|
+
home?: number;
|
|
32
|
+
/**
|
|
33
|
+
* Whether the micro module (`micro()`, C2) fights for it once it is in a fight: focus fire, kiting, fleeing, siege.
|
|
34
|
+
* Yes when left out; `false` for a squad left to its units (a scout, a mission's guards on an order of the game's)
|
|
35
|
+
*/
|
|
36
|
+
micro?: boolean;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* How a brain's squads behave, where a squad says nothing for itself (`BrainDef.squads`, the seat's `AiOptions.squads`
|
|
40
|
+
* over it); and the tasks of the game's own (`defineTask`) a save of the brain may name
|
|
41
|
+
*
|
|
42
|
+
* @beta
|
|
43
|
+
*/
|
|
44
|
+
export interface SquadsOptions extends SquadOptions {
|
|
45
|
+
/** Tasks of the game's own: registered with the brain, so that a squad on one is carried on after a load */
|
|
46
|
+
tasks?: TaskDef[];
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* A squad as the brain remembers it: plain data, kept in a save
|
|
50
|
+
*
|
|
51
|
+
* @beta
|
|
52
|
+
*/
|
|
53
|
+
export interface SquadData {
|
|
54
|
+
/** Unique among the brain's squads */
|
|
55
|
+
name: string;
|
|
56
|
+
/** Who it belongs to: a goal's id, a rule's or a module's hold (`squad:<name>` for one of its own) */
|
|
57
|
+
owner: string;
|
|
58
|
+
/** Its units, by id, in the picture's order */
|
|
59
|
+
units: number[];
|
|
60
|
+
/** How it behaves: its own, over the brain's */
|
|
61
|
+
options: SquadOptions;
|
|
62
|
+
/** What it is doing. None for a squad told nothing yet */
|
|
63
|
+
task?: TaskState;
|
|
64
|
+
/** How many units its task began with, or was given since: what reinforcements make up */
|
|
65
|
+
size: number;
|
|
66
|
+
/** The tick it was made at */
|
|
67
|
+
made: number;
|
|
68
|
+
/** How many times it fell back from a fight it was losing */
|
|
69
|
+
retreats: number;
|
|
70
|
+
/** The last time its units or its task changed, and why, in words */
|
|
71
|
+
changed?: {
|
|
72
|
+
tick: number;
|
|
73
|
+
why: string;
|
|
74
|
+
};
|
|
75
|
+
/** The tick it may next call for reinforcements */
|
|
76
|
+
nextReinforce?: number;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* What the squads remember between thinks, for a save
|
|
80
|
+
*
|
|
81
|
+
* @beta
|
|
82
|
+
*/
|
|
83
|
+
export interface SquadsMemory {
|
|
84
|
+
v: 1;
|
|
85
|
+
squads: SquadData[];
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* A squad as the report shows it: who it belongs to, its units and their strength, where it is, its task and how it goes
|
|
89
|
+
*
|
|
90
|
+
* @beta
|
|
91
|
+
*/
|
|
92
|
+
export interface SquadReport {
|
|
93
|
+
name: string;
|
|
94
|
+
owner: string;
|
|
95
|
+
units: number[];
|
|
96
|
+
strength: number;
|
|
97
|
+
/** Its middle */
|
|
98
|
+
at?: [number, number];
|
|
99
|
+
size: number;
|
|
100
|
+
task?: {
|
|
101
|
+
kind: string;
|
|
102
|
+
phase: string;
|
|
103
|
+
since: number;
|
|
104
|
+
at?: [number, number];
|
|
105
|
+
done?: TaskDone;
|
|
106
|
+
};
|
|
107
|
+
retreats: number;
|
|
108
|
+
changed?: {
|
|
109
|
+
tick: number;
|
|
110
|
+
why: string;
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* A squad of the brain (`ai.squads.make`, `named`, `all`): a handle over its data, with the task methods. A squad's
|
|
115
|
+
* units are as of the think's picture: the dead and those its owner no longer holds are dropped as the squads module
|
|
116
|
+
* looks at it
|
|
117
|
+
*
|
|
118
|
+
* @beta
|
|
119
|
+
*/
|
|
120
|
+
export declare class Squad {
|
|
121
|
+
/** The squads it is one of */
|
|
122
|
+
readonly squads: Squads;
|
|
123
|
+
/** What it is, as plain data: what a save keeps */
|
|
124
|
+
readonly data: SquadData;
|
|
125
|
+
constructor(
|
|
126
|
+
/** The squads it is one of */
|
|
127
|
+
squads: Squads,
|
|
128
|
+
/** What it is, as plain data: what a save keeps */
|
|
129
|
+
data: SquadData);
|
|
130
|
+
/** Its name: unique among the brain's squads */
|
|
131
|
+
get name(): string;
|
|
132
|
+
/** Who it belongs to: the goal, rule or module that made it */
|
|
133
|
+
get owner(): string;
|
|
134
|
+
/** What it is doing: none for a squad told nothing yet */
|
|
135
|
+
get current(): TaskState | undefined;
|
|
136
|
+
/** How its task ended: none while it goes on, or while it has none */
|
|
137
|
+
get done(): TaskDone | undefined;
|
|
138
|
+
/** Whether it has nothing to do: no task, or its task is over */
|
|
139
|
+
get idle(): boolean;
|
|
140
|
+
/** Whether it is still one of the brain's squads: not once disbanded */
|
|
141
|
+
get alive(): boolean;
|
|
142
|
+
/** How it behaves: its own options over the brain's */
|
|
143
|
+
get options(): SquadOptions;
|
|
144
|
+
/** Its units, as of the think's picture: those alive and the player's */
|
|
145
|
+
units(): UnitSet;
|
|
146
|
+
/** How many units it has */
|
|
147
|
+
get length(): number;
|
|
148
|
+
/** How strong it is together (`UnitSet.strength`) */
|
|
149
|
+
strength(): number;
|
|
150
|
+
/** Its middle: none with no unit left */
|
|
151
|
+
centre(): Vec2 | undefined;
|
|
152
|
+
/**
|
|
153
|
+
* How far from its middle a unit may be before it counts as strayed (`SquadOptions.spread`): grows with the squad
|
|
154
|
+
* when not given
|
|
155
|
+
*/
|
|
156
|
+
spread(): number;
|
|
157
|
+
/** Adds units: what its owner may have (see `Squads.make`), taken out of any other squad */
|
|
158
|
+
add(units: Iterable<EntityState | number>, why?: string): this;
|
|
159
|
+
/** Takes units out: they go back to the pool (its owner lets go of them) */
|
|
160
|
+
remove(units: Iterable<EntityState | number>, why?: string): this;
|
|
161
|
+
/** Disbands it: its units go back to its owner (a goal's), or to the pool (a squad of its own) */
|
|
162
|
+
disband(why?: string): void;
|
|
163
|
+
/** Writes down the last change of its units or task, for the report */
|
|
164
|
+
changed(why: string): void;
|
|
165
|
+
/**
|
|
166
|
+
* Gives it a task: one of the kit's by its word (`attack`), or of the game's (`defineTask`, by its def or its id).
|
|
167
|
+
* What it was doing is over. Its first orders go at once; the squads module watches it from then on
|
|
168
|
+
*/
|
|
169
|
+
task<D extends object, M extends object>(def: TaskDef<D, M>, data: D & TaskCommon): this;
|
|
170
|
+
task(kind: string, data?: TaskData): this;
|
|
171
|
+
/** Ends its task, saying how: what a task's `think` calls once it is over */
|
|
172
|
+
finish(done: TaskDone): void;
|
|
173
|
+
/**
|
|
174
|
+
* Goes to fight at a place or a target (an entity, or its id): attack-moves there, fighting what it meets, regroups
|
|
175
|
+
* on the way, retreats on the odds. Done `cleared` once there with nothing left to fight, `lost` when the target is
|
|
176
|
+
* gone. `avoid: 'army'` goes round where their strength is on the way (the threat map and their army as last seen),
|
|
177
|
+
* when there is a way round. `via`: a place to go by on the way (a way of its own: Random Paths). `then`: the task after it
|
|
178
|
+
*/
|
|
179
|
+
attack(target: Vec2 | EntityState | number, options?: {
|
|
180
|
+
avoid?: 'army' | false;
|
|
181
|
+
via?: Vec2;
|
|
182
|
+
then?: TaskOrder;
|
|
183
|
+
}): this;
|
|
184
|
+
/** Attack-moves to a place, as a group of units would on a click: the squad's attack without its regroup */
|
|
185
|
+
attackMove(at: Vec2, options?: {
|
|
186
|
+
then?: TaskOrder;
|
|
187
|
+
}): this;
|
|
188
|
+
/**
|
|
189
|
+
* Holds a place against what comes within `radius` of it (16 when left out): fights what comes, goes back once it is
|
|
190
|
+
* gone. Never over by itself: its owner says when
|
|
191
|
+
*/
|
|
192
|
+
defend(at: Vec2, radius?: number): this;
|
|
193
|
+
/** Goes to a place (where it stands when left out) and holds it: stands, fighting only what comes within reach */
|
|
194
|
+
hold(at?: Vec2): this;
|
|
195
|
+
/** Walks to a place, fighting nothing on the way. Done `arrived` */
|
|
196
|
+
move(at: Vec2, options?: {
|
|
197
|
+
then?: TaskOrder;
|
|
198
|
+
}): this;
|
|
199
|
+
/** Goes with a unit of the player's or an ally's, fighting what comes near it. Done `lost` when it is gone */
|
|
200
|
+
escort(target: EntityState | number): this;
|
|
201
|
+
/**
|
|
202
|
+
* Goes for the workers at a place, round where their army is (`avoid: 'army'` unless told otherwise), the workers
|
|
203
|
+
* first once there. Done `cleared`
|
|
204
|
+
*/
|
|
205
|
+
harass(at: Vec2, options?: {
|
|
206
|
+
avoid?: 'army' | false;
|
|
207
|
+
then?: TaskOrder;
|
|
208
|
+
}): this;
|
|
209
|
+
/** Goes to look at places, one after the other: each is looked at once in sight, or reached as near as the ground lets. Done `arrived` */
|
|
210
|
+
scout(points: readonly Vec2[]): this;
|
|
211
|
+
/**
|
|
212
|
+
* Gathers at a rally point before going on (`then`): until `minForces` of it (a share, 1 when left out) is there,
|
|
213
|
+
* or `seconds` have gone by. Done `arrived`, and on to `then`
|
|
214
|
+
*/
|
|
215
|
+
gather(at: Vec2, options?: {
|
|
216
|
+
minForces?: number;
|
|
217
|
+
seconds?: number;
|
|
218
|
+
then?: TaskOrder;
|
|
219
|
+
}): this;
|
|
220
|
+
/** Falls back to a place (home when left out), fighting nothing on the way. Done `retreated` */
|
|
221
|
+
retreat(to?: Vec2, why?: string): this;
|
|
222
|
+
/**
|
|
223
|
+
* Walks a round of places, one after the other and back to the first, fighting what it meets on the way (an
|
|
224
|
+
* attack-move to each): a mission's guards on the road, a watch round the walls. Never over by itself: its owner
|
|
225
|
+
* says when
|
|
226
|
+
*/
|
|
227
|
+
patrol(points: readonly Vec2[]): this;
|
|
228
|
+
/** Takes a camp of creeps: fights there until the camp is cleared. Done `cleared` */
|
|
229
|
+
creep(camp: Vec2): this;
|
|
230
|
+
/**
|
|
231
|
+
* Carried by transports to a place it cannot walk to, let out on the land nearest it (the `drop` task): done
|
|
232
|
+
* `landed`, then what `then` says (an attack where it landed)
|
|
233
|
+
*/
|
|
234
|
+
drop(at: Vec2, transports: readonly number[], options?: {
|
|
235
|
+
then?: TaskOrder;
|
|
236
|
+
}): this;
|
|
237
|
+
/** Sends its units an order (`move`, `hold`, the game's), all or some of them: counted as the task's last */
|
|
238
|
+
order(order: OrderInit, units?: readonly number[], queue?: boolean): void;
|
|
239
|
+
/**
|
|
240
|
+
* Puts its units, all or some, in a stance, where the game has stances (`withStances`): those not in it already. A
|
|
241
|
+
* squad that holds is defensive, one sent to fight aggressive
|
|
242
|
+
*/
|
|
243
|
+
setStance(id: string, units?: readonly number[]): void;
|
|
244
|
+
/**
|
|
245
|
+
* Sends its units to take a capture point of the game's (`withCapture`), by its id: they fight their way in and
|
|
246
|
+
* stand in it until it is theirs (`captured`), or it is gone (`lost`)
|
|
247
|
+
*/
|
|
248
|
+
capture(id: string): this;
|
|
249
|
+
/** Sends its units, all or some, to fight at a place, or a target there: an attack-move, or an attack */
|
|
250
|
+
fight(at: Vec2, units?: readonly number[], target?: number, queue?: boolean): void;
|
|
251
|
+
/**
|
|
252
|
+
* Of some of its units, those the picture has: a unit that died since the squads were last looked at (a task given by a
|
|
253
|
+
* goal before the `squads()` module ran) is no one to order
|
|
254
|
+
*/
|
|
255
|
+
private living;
|
|
256
|
+
/** Its units that stand with nothing to do: what lost its order, or never had one */
|
|
257
|
+
idleUnits(): EntityState[];
|
|
258
|
+
/** Whether its last order was sent long enough ago to send one again (`RESEND` seconds): what keeps a stuck unit from being told every think */
|
|
259
|
+
mayResend(): boolean;
|
|
260
|
+
private sent;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Some squads together (`ai.squads.all()`, `idle()`): read as a list, told as one (`ai.squads.all().defend(home)`:
|
|
264
|
+
* each squad is given the task)
|
|
265
|
+
*
|
|
266
|
+
* @beta
|
|
267
|
+
*/
|
|
268
|
+
export declare class SquadGroup implements Iterable<Squad> {
|
|
269
|
+
/** The brain they are of */
|
|
270
|
+
readonly ai: Brain;
|
|
271
|
+
/** The squads */
|
|
272
|
+
readonly squads: readonly Squad[];
|
|
273
|
+
constructor(
|
|
274
|
+
/** The brain they are of */
|
|
275
|
+
ai: Brain,
|
|
276
|
+
/** The squads */
|
|
277
|
+
squads: readonly Squad[]);
|
|
278
|
+
[Symbol.iterator](): Iterator<Squad>;
|
|
279
|
+
/** How many squads */
|
|
280
|
+
get length(): number;
|
|
281
|
+
/** Their units together, as a set */
|
|
282
|
+
units(): UnitSet;
|
|
283
|
+
/** How strong they are together */
|
|
284
|
+
strength(): number;
|
|
285
|
+
/** Each given the same task */
|
|
286
|
+
task<D extends object, M extends object>(def: TaskDef<D, M>, data: D & TaskCommon): this;
|
|
287
|
+
task(kind: string, data?: TaskData): this;
|
|
288
|
+
attack(target: Vec2 | EntityState | number, options?: {
|
|
289
|
+
avoid?: 'army' | false;
|
|
290
|
+
then?: TaskOrder;
|
|
291
|
+
}): this;
|
|
292
|
+
defend(at: Vec2 | undefined, radius?: number): this;
|
|
293
|
+
hold(at?: Vec2): this;
|
|
294
|
+
move(at: Vec2): this;
|
|
295
|
+
retreat(to?: Vec2): this;
|
|
296
|
+
/** Each disbanded */
|
|
297
|
+
disband(why?: string): void;
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* A brain's squads (`ai.squads`): made by its goals, rules and modules, watched by the `squads()` module each think
|
|
301
|
+
* (`think`): the dead dropped, what the owner let go of let go of, each task looked at, regroups, retreats and
|
|
302
|
+
* reinforcements seen to. Kept in the brain's memory (`BrainMemory.squads`)
|
|
303
|
+
*
|
|
304
|
+
* @beta
|
|
305
|
+
*/
|
|
306
|
+
export declare class Squads implements AiArea {
|
|
307
|
+
/** The brain they are the squads of */
|
|
308
|
+
readonly ai: Brain;
|
|
309
|
+
/** Its id among the brain's areas: what its memory and its report are kept under */
|
|
310
|
+
readonly id = "squads";
|
|
311
|
+
/** What the log says where a save's memory of it is of a shape it does not read */
|
|
312
|
+
readonly afresh = "the save remembers the computer player\u2019s squads in a shape this brain does not read: they are let go of";
|
|
313
|
+
private list;
|
|
314
|
+
private readonly tasks;
|
|
315
|
+
private thoughtAt;
|
|
316
|
+
/** How a squad behaves where it says nothing and the brain's settings say nothing either: the `squads()` module's */
|
|
317
|
+
private moduleOptions;
|
|
318
|
+
constructor(
|
|
319
|
+
/** The brain they are the squads of */
|
|
320
|
+
ai: Brain,
|
|
321
|
+
/** The tasks of the game's own its squads may be on (`AiSettings.squads.tasks`) */
|
|
322
|
+
tasks?: readonly TaskDef[]);
|
|
323
|
+
/** Puts the `squads()` module's options under the brain's settings */
|
|
324
|
+
configure(options: SquadOptions): void;
|
|
325
|
+
/** How a squad behaves where it says nothing: the module's options, the brain's settings over them (`ai.settings.squads`) */
|
|
326
|
+
get defaults(): SquadOptions;
|
|
327
|
+
/** Registers a task of the game's own, so that a squad on it is carried on after a load. Given by `BrainDef.squads.tasks` */
|
|
328
|
+
define(def: TaskDef): void;
|
|
329
|
+
/** A kind of task by its id: the kit's, or one registered */
|
|
330
|
+
taskDef(id: string): TaskDef | undefined;
|
|
331
|
+
/**
|
|
332
|
+
* Makes a squad of units under a name (one of that name already is disbanded first), with how it behaves where it
|
|
333
|
+
* is not the brain's way. Whose it is (`owner`): what `options.owner` names (a goal makes its own with
|
|
334
|
+
* `claimed.squad`), else its own (`squad:<name>`). A goal's squad is made of what the goal holds, and what
|
|
335
|
+
* nothing holds is given to it; a squad of a rule or a module takes its units from whatever holds them (the goal
|
|
336
|
+
* told: `stop('told')`) and holds them until it is disbanded. A unit in another squad leaves it
|
|
337
|
+
*/
|
|
338
|
+
make(name: string, units: Iterable<EntityState | number>, options?: SquadOptions & {
|
|
339
|
+
owner?: string;
|
|
340
|
+
}): Squad;
|
|
341
|
+
/**
|
|
342
|
+
* Puts units in a squad: those its owner may have (held by it, or given from the pool for a goal; taken for a rule's
|
|
343
|
+
* or a module's), out of any other squad. Those put in, by id
|
|
344
|
+
*/
|
|
345
|
+
enlist(squad: Squad, wanted: number[]): number[];
|
|
346
|
+
/** A squad by name: none for one there is not */
|
|
347
|
+
named(name: string): Squad | undefined;
|
|
348
|
+
/** Every squad, as made */
|
|
349
|
+
all(): SquadGroup;
|
|
350
|
+
/** The squads with nothing to do: told nothing, or their task over */
|
|
351
|
+
idle(): SquadGroup;
|
|
352
|
+
/** The squads a goal, rule or module owns */
|
|
353
|
+
of(owner: string): SquadGroup;
|
|
354
|
+
/** The squad a unit is in, by the unit or its id: none for a unit in none */
|
|
355
|
+
squadOf(unit: EntityState | number): Squad | undefined;
|
|
356
|
+
/** The player's units nothing holds (`ai.goals.pool`, buildings left out): what a squad is made of, or reinforced from */
|
|
357
|
+
pool(): UnitSet;
|
|
358
|
+
/** Disbands a squad: a squad that held its units itself lets them go back to the pool */
|
|
359
|
+
disband(squad: Squad, why?: string, letGo?: boolean): void;
|
|
360
|
+
/**
|
|
361
|
+
* Gives a squad a task: what it was doing is over, and the new one's first orders go at once. What it has now is what
|
|
362
|
+
* reinforcements make up to from then on (`SquadData.size`), but for a task it goes on to by itself (`going on`: a
|
|
363
|
+
* task's `then`, a fall back on the odds), which keeps what the task before was given. The task it is on given
|
|
364
|
+
* again changes nothing, its `size` kept: what it lost since is what reinforcements make up
|
|
365
|
+
*/
|
|
366
|
+
give(squad: Squad, kind: string | TaskDef, data: TaskData, goingOn?: boolean): void;
|
|
367
|
+
/**
|
|
368
|
+
* Looks at every squad, once a think: its units (the dead, and what its owner let go of, dropped; a squad of a goal
|
|
369
|
+
* that stopped disbanded), then its task (retreat on the odds, the task's own look, regroup, reinforcements). What the
|
|
370
|
+
* `squads()` module runs; a module may call it sooner
|
|
371
|
+
*/
|
|
372
|
+
think(): void;
|
|
373
|
+
/** The squads still to be looked at this think, where a pass stopped for the tick's budget, and the next of them */
|
|
374
|
+
private advancing;
|
|
375
|
+
private cursor;
|
|
376
|
+
/** Every squad's units looked at, as a think begins: the dead and what its owner let go of dropped, a squad with none left disbanded */
|
|
377
|
+
private prune;
|
|
378
|
+
/** One squad's think: retreat on the odds, the task's own look, then on to the next task, regroup, reinforcements */
|
|
379
|
+
private advance;
|
|
380
|
+
/**
|
|
381
|
+
* Whether a squad in a fight away from home is losing it (its odds under `retreatAt`), and so falls back: its task
|
|
382
|
+
* becomes `retreat`, home, and it is said why
|
|
383
|
+
*/
|
|
384
|
+
private losing;
|
|
385
|
+
/**
|
|
386
|
+
* Regroups a squad that is strung out on its way: too many of its units (`regroupWhen`) further than `spread` from its
|
|
387
|
+
* middle, and no fight near. It gathers on its middle and goes on once together, or once it has waited long enough
|
|
388
|
+
*/
|
|
389
|
+
private regroup;
|
|
390
|
+
/**
|
|
391
|
+
* Makes up what a squad lost since its task began from the pool: the idle fighters nothing holds, the nearest
|
|
392
|
+
* first, given to its owner and sent to join it. Never a hero: one crossing the map alone to a fight dies on the
|
|
393
|
+
* way, and heroes are sent with a squad, not after it. Not while it falls back, nor more often than every few seconds
|
|
394
|
+
*/
|
|
395
|
+
private reinforce;
|
|
396
|
+
/** The place a squad's task is about: none for a task about no place */
|
|
397
|
+
whereOf(squad: Squad): Vec2 | undefined;
|
|
398
|
+
/**
|
|
399
|
+
* The way to a place round where the enemy is strong (`avoid: 'army'`): the waypoint to go by, where the straight way
|
|
400
|
+
* crosses their strength (the threat map, with what is remembered of their towers, and their army as last seen) and a
|
|
401
|
+
* way round is less hot, tried on either side and then further out, twice at most. A heuristic, not a safe route:
|
|
402
|
+
* none where the straight way is cool enough, or where there is no way round (`note` says so)
|
|
403
|
+
*/
|
|
404
|
+
route(from: Vec2, to: Vec2, squad: Squad): {
|
|
405
|
+
waypoints: Vec2[];
|
|
406
|
+
note?: string;
|
|
407
|
+
};
|
|
408
|
+
/** Every squad as the report shows it */
|
|
409
|
+
report(): SquadReport[];
|
|
410
|
+
/** What the squads are, for a save: copies */
|
|
411
|
+
/** Whether it has anything to remember now: one that does not is left out of a save */
|
|
412
|
+
remembers(): boolean;
|
|
413
|
+
save(): SquadsMemory;
|
|
414
|
+
/** Takes back what `save` gave: whether it was read. A squad on a task the brain does not know is kept, and does nothing */
|
|
415
|
+
restore(memory: unknown): boolean;
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* The squads module: looks at every squad of the brain each think (`ai.squads.think`), after the goals, the rules and
|
|
419
|
+
* the words that make them: their units, their tasks, regroups, retreats, reinforcements. With how they behave where the
|
|
420
|
+
* brain's definition and the seat's options say nothing
|
|
421
|
+
*
|
|
422
|
+
* @beta
|
|
423
|
+
*/
|
|
424
|
+
export declare const squads: (options?: SquadsOptions) => AiModuleDef;
|
|
425
|
+
declare module './area' {
|
|
426
|
+
interface AreaMemories {
|
|
427
|
+
squads?: SquadsMemory;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { type Stats, type UnitTypeDef } from '#engine/defs';
|
|
2
|
+
import type { Registry } from '#engine/registry';
|
|
3
|
+
import type { EntityState } from '#engine/session/protocol';
|
|
4
|
+
import type { AiView, UnitSet } from './view';
|
|
5
|
+
/**
|
|
6
|
+
* A force to weigh: a set of entities as the view gives them (`view.enemies.fighters()`), a plain array of them, or
|
|
7
|
+
* types with counts (`{ footman: 6, gryphon: 2 }`), as the knowledge keeps an army it saw (`ArmySighting.types`,
|
|
8
|
+
* `TypeSeen`): those are taken at full health with the stats their type starts with
|
|
9
|
+
*
|
|
10
|
+
* @beta
|
|
11
|
+
*/
|
|
12
|
+
export type Force = UnitSet | readonly EntityState[] | Readonly<Record<string, number>>;
|
|
13
|
+
/**
|
|
14
|
+
* What a strength formula is given of one unit or type: its definition, its stats as they stand (the type's, with what
|
|
15
|
+
* the snapshot shows of a seen unit's own: upgrades, items, levels, buffs), the entity where there is one (its health,
|
|
16
|
+
* its level) and the view, for the roles and the registry
|
|
17
|
+
*
|
|
18
|
+
* @beta
|
|
19
|
+
*/
|
|
20
|
+
export interface StrengthInput {
|
|
21
|
+
/** The unit type */
|
|
22
|
+
def: UnitTypeDef;
|
|
23
|
+
/** The stats as they stand: the type's, with a seen unit's own over them */
|
|
24
|
+
stats: Readonly<Stats>;
|
|
25
|
+
/** The unit, where one is weighed; none for a type */
|
|
26
|
+
entity?: EntityState;
|
|
27
|
+
/** 0..1: the health it has left, as a part of its most; 1 for a type */
|
|
28
|
+
health: number;
|
|
29
|
+
/** The picture it is weighed in: for the roles (`view.roles`) and the definitions (`view.registry`) */
|
|
30
|
+
view: AiView;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* How strong a unit or a type is, as a number that adds up over a group: the kit's formula (`defaultStrength`), or a
|
|
34
|
+
* game's own in its place (`AiOptions.strength`, `BrainDef.strength`). Given the unit's definition and stats as they
|
|
35
|
+
* stand, the entity where there is one, and the health it has left as a part of its most. Must give a finite number,
|
|
36
|
+
* 0 for what does not fight
|
|
37
|
+
*
|
|
38
|
+
* @beta
|
|
39
|
+
*/
|
|
40
|
+
export type StrengthFormula = (input: StrengthInput) => number;
|
|
41
|
+
/**
|
|
42
|
+
* What one side of a matchup is worth against the other, with how (`Strength.matchup`): the strength of each of its
|
|
43
|
+
* units against the opponent, summed
|
|
44
|
+
*
|
|
45
|
+
* @beta
|
|
46
|
+
*/
|
|
47
|
+
export interface Matchup {
|
|
48
|
+
/** The side's strength against the opponent: 0 where none of it can hit any of them */
|
|
49
|
+
strength: number;
|
|
50
|
+
/** The side's strength on its own, against no one in particular */
|
|
51
|
+
plain: number;
|
|
52
|
+
/** How many fought: units with health left and an attack */
|
|
53
|
+
count: number;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* How well a type answers a force (`Strength.counterFor`): its strength against them over its plain strength. 1 is as
|
|
57
|
+
* good as it is against anyone, 0 is useless (it cannot hit them), above 1 it is the answer
|
|
58
|
+
*
|
|
59
|
+
* @beta
|
|
60
|
+
*/
|
|
61
|
+
export interface Counter {
|
|
62
|
+
/** The type ranked */
|
|
63
|
+
def: UnitTypeDef;
|
|
64
|
+
/** Its strength against the force over its plain strength */
|
|
65
|
+
score: number;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* What a game declares a type good against (`UnitTypeDef.ai.counters`): a tag (`'air'`), a role (`'siege'`) or a type
|
|
69
|
+
* id, as a word, or with how much it counts (`weight`, 0.5 when left out: a unit whose whole opponent it counters is
|
|
70
|
+
* worth half again)
|
|
71
|
+
*
|
|
72
|
+
* @beta
|
|
73
|
+
*/
|
|
74
|
+
export type CounterHint = string | {
|
|
75
|
+
target: string;
|
|
76
|
+
weight?: number;
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* The kit's formula for how strong a unit is, under a square root so that it adds up over a group (Lanchester):
|
|
80
|
+
*
|
|
81
|
+
* `sqrt(toughness × offence) × hero`, where
|
|
82
|
+
*
|
|
83
|
+
* - `toughness` is the health it has left, more by its armour and magic resist (the middle of the two, since no
|
|
84
|
+
* opponent is in question: 100 of armour doubles it, as the engine's `mitigation` halves what arrives),
|
|
85
|
+
* - `offence` is its damage a second (`attackDamage × attackSpeed`), up to a quarter more for reach (at 10 of range)
|
|
86
|
+
* and a tenth for speed (at 8),
|
|
87
|
+
* - `hero` is 1 for a unit, and `1.1 + 0.1 × (level − 1)` for a hero: its spells, and more as they level.
|
|
88
|
+
*
|
|
89
|
+
* 0 for what has no attack: a building that does not shoot, a worker with no weapon. A declared strength
|
|
90
|
+
* (`UnitTypeDef.ai.strength`) is taken in its place by `Strength`, before this is asked
|
|
91
|
+
*
|
|
92
|
+
* @beta
|
|
93
|
+
*/
|
|
94
|
+
export declare const defaultStrength: StrengthFormula;
|
|
95
|
+
/**
|
|
96
|
+
* How strong things are, to a brain (`AiView.strength`, `Brain.strength`): one unit or type (`of`), a group (`sum`,
|
|
97
|
+
* what `UnitSet.strength()` asks), one force against another (`matchup`, `odds`), and what to train against what was
|
|
98
|
+
* seen (`counterFor`). The formula is the kit's (`defaultStrength`) unless the brain was given one
|
|
99
|
+
* (`AiOptions.strength`, `BrainDef.strength`); a type's declared strength (`UnitTypeDef.ai.strength`) goes before
|
|
100
|
+
* either. What a type's numbers come to is worked out once and kept across thinks; a seen unit's own stats
|
|
101
|
+
* (`EntityState.stats`: its upgrades, items, levels, buffs) are read each time
|
|
102
|
+
*
|
|
103
|
+
* @beta
|
|
104
|
+
*/
|
|
105
|
+
export declare class Strength {
|
|
106
|
+
/** The game's definitions */
|
|
107
|
+
readonly registry: Registry;
|
|
108
|
+
/** The formula a unit's strength comes from: the kit's unless the brain was given one */
|
|
109
|
+
readonly formula: StrengthFormula;
|
|
110
|
+
private readonly profiles;
|
|
111
|
+
private readonly plainByType;
|
|
112
|
+
constructor(
|
|
113
|
+
/** The game's definitions */
|
|
114
|
+
registry: Registry,
|
|
115
|
+
/** The formula a unit's strength comes from: the kit's unless the brain was given one */
|
|
116
|
+
formula?: StrengthFormula);
|
|
117
|
+
/**
|
|
118
|
+
* How strong a unit is, with the health it has left and its own stats as the snapshot shows them; or a type at full
|
|
119
|
+
* health with the stats it starts with. 0 for what does not fight. A finite number always
|
|
120
|
+
*/
|
|
121
|
+
of(what: EntityState | UnitTypeDef | string): number;
|
|
122
|
+
/** A type at full health: worked out once */
|
|
123
|
+
private ofType;
|
|
124
|
+
/** The formula asked, the declared strength first; whatever comes back made finite */
|
|
125
|
+
private evaluate;
|
|
126
|
+
/** The stats of a seen unit as they stand: its type's, with its own over them (`EntityState.stats`: upgrades, items, levels, buffs) */
|
|
127
|
+
statsOf(entity: EntityState, def?: UnitTypeDef): Readonly<Stats>;
|
|
128
|
+
/** How strong a group is: the strength of each, summed */
|
|
129
|
+
sum(force: Force): number;
|
|
130
|
+
/**
|
|
131
|
+
* One force against another: the strength of each of `a`'s units against `b` (what it cannot hit counts for nothing
|
|
132
|
+
* of its damage; its damage meets their armour, theirs meets its; what it is declared to counter weighs it up),
|
|
133
|
+
* summed. `matchup(a, b).strength / matchup(b, a).strength` is how `a` compares; `odds` turns it into a chance
|
|
134
|
+
*/
|
|
135
|
+
matchup(a: Force, b: Force): Matchup;
|
|
136
|
+
/**
|
|
137
|
+
* The chance that `a` beats `b` in a fight to the end, 0..1: `A² / (A² + B²)` of the two matchups (Lanchester's
|
|
138
|
+
* square law: numbers count twice, since each unit both deals and takes). 0.5 for a mirror, and when neither can hit
|
|
139
|
+
* the other. **An estimate**: it reads stats, layers, armour and declared counters, and knows nothing of spells,
|
|
140
|
+
* terrain, focus fire, who shoots first or who runs; the plan's E3 checks it against fights played out, and a game
|
|
141
|
+
* that knows better gives its own formula (`AiOptions.strength`)
|
|
142
|
+
*/
|
|
143
|
+
odds(a: Force, b: Force): number;
|
|
144
|
+
/**
|
|
145
|
+
* What answers a force best among some types: each with its strength against them over its plain strength (1 is as
|
|
146
|
+
* good as against anyone, 0 cannot hit them, above 1 is the answer), the best first, equals in the order given.
|
|
147
|
+
* Against nothing, every type scores 1
|
|
148
|
+
*/
|
|
149
|
+
counterFor(enemies: Force, candidates: readonly (UnitTypeDef | string)[]): Counter[];
|
|
150
|
+
/** What a game declares a type good against, as `{ target, weight }` each */
|
|
151
|
+
countersOf(type: UnitTypeDef | string): readonly {
|
|
152
|
+
target: string;
|
|
153
|
+
weight: number;
|
|
154
|
+
}[];
|
|
155
|
+
/**
|
|
156
|
+
* A profile's strength against a force over its plain strength: what its damage comes to against them (what it can
|
|
157
|
+
* hit, through their armour) and what theirs comes to against it (through its armour), each as a part of the
|
|
158
|
+
* plain, under the same square root, times what it is declared to counter. 1 against nothing
|
|
159
|
+
*/
|
|
160
|
+
private edge;
|
|
161
|
+
/** Whether a declared counter's word is one of a profile's: its type, a role or a tag of it */
|
|
162
|
+
private matches;
|
|
163
|
+
/** What a type comes to for a matchup, kept */
|
|
164
|
+
private profile;
|
|
165
|
+
/** A force as groups: a profile and how many, those with health left and an attack. Units with stats of their own stand apart */
|
|
166
|
+
private groups;
|
|
167
|
+
}
|