@v12-engine/engine 0.1.0 → 0.4.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/dist/abilities/amounts.d.ts +28 -0
- package/dist/abilities/amounts.js +74 -0
- package/dist/abilities/amounts.js.map +1 -0
- package/dist/abilities/buffs.d.ts +106 -6
- package/dist/abilities/buffs.js +443 -0
- package/dist/abilities/buffs.js.map +1 -0
- package/dist/abilities/castTold.d.ts +2 -0
- package/dist/abilities/castTold.js +66 -0
- package/dist/abilities/castTold.js.map +1 -0
- package/dist/abilities/chance.d.ts +38 -0
- package/dist/abilities/chance.js +77 -0
- package/dist/abilities/chance.js.map +1 -0
- package/dist/abilities/charges.d.ts +18 -0
- package/dist/abilities/charges.js +101 -0
- package/dist/abilities/charges.js.map +1 -0
- package/dist/abilities/control.d.ts +28 -0
- package/dist/abilities/control.js +113 -0
- package/dist/abilities/control.js.map +1 -0
- package/dist/abilities/dispel.js +51 -0
- package/dist/abilities/dispel.js.map +1 -0
- package/dist/abilities/effectFields.d.ts +1 -1
- package/dist/abilities/effectFields.js +676 -0
- package/dist/abilities/effectFields.js.map +1 -0
- package/dist/abilities/effectIndex.d.ts +27 -0
- package/dist/abilities/effectIndex.js +64 -0
- package/dist/abilities/effectIndex.js.map +1 -0
- package/dist/abilities/effects/buff.d.ts +9 -3
- package/dist/abilities/effects/buff.js +84 -0
- package/dist/abilities/effects/buff.js.map +1 -0
- package/dist/abilities/effects/conditions.d.ts +2 -0
- package/dist/abilities/effects/conditions.js +41 -0
- package/dist/abilities/effects/conditions.js.map +1 -0
- package/dist/abilities/effects/core.js +54 -0
- package/dist/abilities/effects/core.js.map +1 -0
- package/dist/abilities/effects/damage.d.ts +1 -1
- package/dist/abilities/effects/damage.js +43 -0
- package/dist/abilities/effects/damage.js.map +1 -0
- package/dist/abilities/effects/heal.d.ts +2 -2
- package/dist/abilities/effects/heal.js +51 -0
- package/dist/abilities/effects/heal.js.map +1 -0
- package/dist/abilities/effects/missile.d.ts +13 -1
- package/dist/abilities/effects/missile.js +104 -0
- package/dist/abilities/effects/missile.js.map +1 -0
- package/dist/abilities/effects/morph.d.ts +5 -0
- package/dist/abilities/effects/morph.js +43 -0
- package/dist/abilities/effects/morph.js.map +1 -0
- package/dist/abilities/effects/moves.d.ts +16 -4
- package/dist/abilities/effects/moves.js +212 -0
- package/dist/abilities/effects/moves.js.map +1 -0
- package/dist/abilities/effects/passives.d.ts +19 -9
- package/dist/abilities/effects/passives.js +131 -0
- package/dist/abilities/effects/passives.js.map +1 -0
- package/dist/abilities/effects/proxy.d.ts +5 -0
- package/dist/abilities/effects/proxy.js +60 -0
- package/dist/abilities/effects/proxy.js.map +1 -0
- package/dist/abilities/effects/sight.d.ts +2 -2
- package/dist/abilities/effects/sight.js +39 -0
- package/dist/abilities/effects/sight.js.map +1 -0
- package/dist/abilities/effects/spawn.d.ts +5 -2
- package/dist/abilities/effects/spawn.js +40 -0
- package/dist/abilities/effects/spawn.js.map +1 -0
- package/dist/abilities/effects/timed.d.ts +2 -2
- package/dist/abilities/effects/timed.js +96 -0
- package/dist/abilities/effects/timed.js.map +1 -0
- package/dist/abilities/effects/trade.d.ts +1 -1
- package/dist/abilities/effects/trade.js +25 -0
- package/dist/abilities/effects/trade.js.map +1 -0
- package/dist/abilities/effects.d.ts +97 -23
- package/dist/abilities/effects.js +860 -0
- package/dist/abilities/effects.js.map +1 -0
- package/dist/abilities/land.d.ts +38 -4
- package/dist/abilities/land.js +189 -0
- package/dist/abilities/land.js.map +1 -0
- package/dist/abilities/recast.d.ts +45 -0
- package/dist/abilities/recast.js +118 -0
- package/dist/abilities/recast.js.map +1 -0
- package/dist/abilities/scaled.js +40 -0
- package/dist/abilities/scaled.js.map +1 -0
- package/dist/abilities/screen.d.ts +6 -0
- package/dist/abilities/screen.js +83 -0
- package/dist/abilities/screen.js.map +1 -0
- package/dist/abilities/shapes.d.ts +66 -0
- package/dist/abilities/shapes.js +122 -0
- package/dist/abilities/shapes.js.map +1 -0
- package/dist/abilities/text.d.ts +14 -2
- package/dist/abilities/text.js +204 -0
- package/dist/abilities/text.js.map +1 -0
- package/dist/abilities/triggers.d.ts +98 -0
- package/dist/abilities/triggers.js +351 -0
- package/dist/abilities/triggers.js.map +1 -0
- package/dist/abilityChanges.d.ts +131 -0
- package/dist/abilityChanges.js +345 -0
- package/dist/abilityChanges.js.map +1 -0
- package/dist/ai/area.d.ts +4 -1
- package/dist/ai/brain.d.ts +4 -1
- package/dist/ai/brain.js +844 -0
- package/dist/ai/brain.js.map +1 -0
- package/dist/ai/budget.js +74 -0
- package/dist/ai/budget.js.map +1 -0
- package/dist/ai/checks.d.ts +9 -1
- package/dist/ai/checks.js +242 -0
- package/dist/ai/checks.js.map +1 -0
- package/dist/ai/computer.d.ts +11 -4
- package/dist/ai/computer.js +251 -0
- package/dist/ai/computer.js.map +1 -0
- package/dist/ai/defence.d.ts +4 -0
- package/dist/ai/defence.js +430 -0
- package/dist/ai/defence.js.map +1 -0
- package/dist/ai/define.d.ts +3 -2
- package/dist/ai/define.js +31 -0
- package/dist/ai/define.js.map +1 -0
- package/dist/ai/economy.d.ts +10 -7
- package/dist/ai/economy.js +780 -0
- package/dist/ai/economy.js.map +1 -0
- package/dist/ai/geometry.js +38 -0
- package/dist/ai/geometry.js.map +1 -0
- package/dist/ai/goals.d.ts +1 -0
- package/dist/ai/goals.js +560 -0
- package/dist/ai/goals.js.map +1 -0
- package/dist/ai/knowledge.d.ts +72 -7
- package/dist/ai/knowledge.js +804 -0
- package/dist/ai/knowledge.js.map +1 -0
- package/dist/ai/lanes.d.ts +10 -2
- package/dist/ai/lanes.js +715 -0
- package/dist/ai/lanes.js.map +1 -0
- package/dist/ai/melee/build.js +264 -0
- package/dist/ai/melee/build.js.map +1 -0
- package/dist/ai/melee/goals.d.ts +7 -0
- package/dist/ai/melee/goals.js +720 -0
- package/dist/ai/melee/goals.js.map +1 -0
- package/dist/ai/melee/heroes.js +68 -0
- package/dist/ai/melee/heroes.js.map +1 -0
- package/dist/ai/melee/index.d.ts +1 -1
- package/dist/ai/melee/index.js +51 -0
- package/dist/ai/melee/index.js.map +1 -0
- package/dist/ai/melee/production.js +29 -0
- package/dist/ai/melee/production.js.map +1 -0
- package/dist/ai/melee/surrender.js +64 -0
- package/dist/ai/melee/surrender.js.map +1 -0
- package/dist/ai/micro.d.ts +9 -0
- package/dist/ai/micro.js +1316 -0
- package/dist/ai/micro.js.map +1 -0
- package/dist/ai/mission.d.ts +9 -2
- package/dist/ai/mission.js +538 -0
- package/dist/ai/mission.js.map +1 -0
- package/dist/ai/missionRules.d.ts +1 -1
- package/dist/ai/missionRules.js +26 -0
- package/dist/ai/missionRules.js.map +1 -0
- package/dist/ai/module.d.ts +6 -2
- package/dist/ai/module.js +37 -0
- package/dist/ai/module.js.map +1 -0
- package/dist/ai/options.d.ts +3 -3
- package/dist/ai/plans/build.d.ts +20 -1
- package/dist/ai/plans/build.js +608 -0
- package/dist/ai/plans/build.js.map +1 -0
- package/dist/ai/plans/placement.d.ts +4 -1
- package/dist/ai/plans/placement.js +295 -0
- package/dist/ai/plans/placement.js.map +1 -0
- package/dist/ai/plans/plans.d.ts +9 -0
- package/dist/ai/plans/plans.js +110 -0
- package/dist/ai/plans/plans.js.map +1 -0
- package/dist/ai/plans/production.d.ts +14 -2
- package/dist/ai/plans/production.js +434 -0
- package/dist/ai/plans/production.js.map +1 -0
- package/dist/ai/plans/purse.d.ts +6 -3
- package/dist/ai/plans/purse.js +139 -0
- package/dist/ai/plans/purse.js.map +1 -0
- package/dist/ai/plans/tech.d.ts +6 -0
- package/dist/ai/plans/tech.js +122 -0
- package/dist/ai/plans/tech.js.map +1 -0
- package/dist/ai/profiles.d.ts +4 -4
- package/dist/{profiles-B3NS9jwk.js → ai/profiles.js} +3 -98
- package/dist/ai/profiles.js.map +1 -0
- package/dist/ai/reach.js +54 -0
- package/dist/ai/reach.js.map +1 -0
- package/dist/ai/report.d.ts +8 -0
- package/dist/ai/report.js +87 -0
- package/dist/ai/report.js.map +1 -0
- package/dist/ai/roles.d.ts +4 -0
- package/dist/ai/roles.js +207 -0
- package/dist/ai/roles.js.map +1 -0
- package/dist/ai/rules.d.ts +8 -2
- package/dist/ai/rules.js +416 -0
- package/dist/ai/rules.js.map +1 -0
- package/dist/ai/scouting.d.ts +6 -0
- package/dist/ai/scouting.js +324 -0
- package/dist/ai/scouting.js.map +1 -0
- package/dist/ai/settings.js +99 -0
- package/dist/ai/settings.js.map +1 -0
- package/dist/ai/squads.d.ts +21 -2
- package/dist/ai/squads.js +916 -0
- package/dist/ai/squads.js.map +1 -0
- package/dist/ai/strength.js +320 -0
- package/dist/ai/strength.js.map +1 -0
- package/dist/ai/task.d.ts +3 -1
- package/dist/ai/task.js +17 -0
- package/dist/ai/task.js.map +1 -0
- package/dist/ai/tasks/attack.js +24 -0
- package/dist/ai/tasks/attack.js.map +1 -0
- package/dist/ai/tasks/capture.d.ts +3 -3
- package/dist/ai/tasks/capture.js +37 -0
- package/dist/ai/tasks/capture.js.map +1 -0
- package/dist/ai/tasks/creep.js +29 -0
- package/dist/ai/tasks/creep.js.map +1 -0
- package/dist/ai/tasks/defend.js +61 -0
- package/dist/ai/tasks/defend.js.map +1 -0
- package/dist/ai/tasks/drop.js +81 -0
- package/dist/ai/tasks/drop.js.map +1 -0
- package/dist/ai/tasks/escort.js +59 -0
- package/dist/ai/tasks/escort.js.map +1 -0
- package/dist/ai/tasks/gather.js +48 -0
- package/dist/ai/tasks/gather.js.map +1 -0
- package/dist/ai/tasks/harass.js +39 -0
- package/dist/ai/tasks/harass.js.map +1 -0
- package/dist/ai/tasks/hold.js +32 -0
- package/dist/ai/tasks/hold.js.map +1 -0
- package/dist/ai/tasks/index.js +34 -0
- package/dist/ai/tasks/index.js.map +1 -0
- package/dist/ai/tasks/move.js +26 -0
- package/dist/ai/tasks/move.js.map +1 -0
- package/dist/ai/tasks/patrol.js +59 -0
- package/dist/ai/tasks/patrol.js.map +1 -0
- package/dist/ai/tasks/retreat.js +28 -0
- package/dist/ai/tasks/retreat.js.map +1 -0
- package/dist/ai/tasks/scout.js +73 -0
- package/dist/ai/tasks/scout.js.map +1 -0
- package/dist/ai/tasks/shared.d.ts +1 -1
- package/dist/ai/tasks/shared.js +137 -0
- package/dist/ai/tasks/shared.js.map +1 -0
- package/dist/ai/team.d.ts +18 -1
- package/dist/ai/team.js +492 -0
- package/dist/ai/team.js.map +1 -0
- package/dist/ai/threat.d.ts +6 -0
- package/dist/ai/threat.js +206 -0
- package/dist/ai/threat.js.map +1 -0
- package/dist/ai/view.d.ts +21 -7
- package/dist/ai/view.js +677 -0
- package/dist/ai/view.js.map +1 -0
- package/dist/ai/waves.d.ts +6 -0
- package/dist/ai/waves.js +410 -0
- package/dist/ai/waves.js.map +1 -0
- package/dist/ai.js +54 -6239
- package/dist/aiTesting.d.ts +6 -3
- package/dist/aiTesting.js +229 -0
- package/dist/aiTesting.js.map +1 -0
- package/dist/areas.d.ts +4 -1
- package/dist/areas.js +295 -0
- package/dist/areas.js.map +1 -0
- package/dist/attacks.d.ts +3 -3
- package/dist/attacks.js +127 -0
- package/dist/attacks.js.map +1 -0
- package/dist/burning.d.ts +267 -0
- package/dist/burning.js +795 -0
- package/dist/burning.js.map +1 -0
- package/dist/bytes.js +21 -0
- package/dist/bytes.js.map +1 -0
- package/dist/callings.d.ts +71 -0
- package/dist/callings.js +157 -0
- package/dist/callings.js.map +1 -0
- package/dist/cameraOrders.d.ts +78 -0
- package/dist/cameraOrders.js +114 -0
- package/dist/cameraOrders.js.map +1 -0
- package/dist/camps.d.ts +70 -4
- package/dist/camps.js +501 -0
- package/dist/camps.js.map +1 -0
- package/dist/capture.d.ts +15 -3
- package/dist/capture.js +304 -0
- package/dist/capture.js.map +1 -0
- package/dist/cellLayers.d.ts +78 -13
- package/dist/cellLayers.js +275 -0
- package/dist/cellLayers.js.map +1 -0
- package/dist/cellPatches.d.ts +24 -0
- package/dist/cellPatches.js +73 -0
- package/dist/cellPatches.js.map +1 -0
- package/dist/cinematics.d.ts +10 -5
- package/dist/cinematics.js +161 -0
- package/dist/cinematics.js.map +1 -0
- package/dist/clock.d.ts +2 -2
- package/dist/clock.js +78 -0
- package/dist/clock.js.map +1 -0
- package/dist/commands.d.ts +36 -4
- package/dist/commands.js +636 -0
- package/dist/commands.js.map +1 -0
- package/dist/components.d.ts +31 -10
- package/dist/components.js +74 -0
- package/dist/components.js.map +1 -0
- package/dist/computers.d.ts +4 -4
- package/dist/computers.js +194 -0
- package/dist/computers.js.map +1 -0
- package/dist/concealment.d.ts +25 -2
- package/dist/concealment.js +409 -0
- package/dist/concealment.js.map +1 -0
- package/dist/coreComponents.js +130 -0
- package/dist/coreComponents.js.map +1 -0
- package/dist/createGame.d.ts +306 -0
- package/dist/createGame.js +405 -0
- package/dist/createGame.js.map +1 -0
- package/dist/dashing.d.ts +18 -2
- package/dist/dashing.js +41 -0
- package/dist/dashing.js.map +1 -0
- package/dist/debug.d.ts +8 -0
- package/dist/debug.js +5 -3
- package/dist/debug2.js +76 -0
- package/dist/debug2.js.map +1 -0
- package/dist/debugCommands.d.ts +6 -6
- package/dist/debugCommands.js +537 -0
- package/dist/debugCommands.js.map +1 -0
- package/dist/debugging.d.ts +1 -0
- package/dist/defaultSets.d.ts +183 -0
- package/dist/defaultSets.js +216 -0
- package/dist/defaultSets.js.map +1 -0
- package/dist/definitions.d.ts +6 -0
- package/dist/definitions.js +78 -0
- package/dist/definitions.js.map +1 -0
- package/dist/defs.d.ts +1895 -165
- package/dist/defs.js +380 -0
- package/dist/defs.js.map +1 -0
- package/dist/denying.d.ts +4 -4
- package/dist/denying.js +106 -0
- package/dist/denying.js.map +1 -0
- package/dist/destructibles.d.ts +2 -2
- package/dist/destructibles.js +36 -0
- package/dist/destructibles.js.map +1 -0
- package/dist/determinism.d.ts +4 -4
- package/dist/determinism.js +247 -0
- package/dist/determinism.js.map +1 -0
- package/dist/dialog.d.ts +17 -2
- package/dist/dialog.js +108 -0
- package/dist/dialog.js.map +1 -0
- package/dist/effectRefs.js +28 -0
- package/dist/effectRefs.js.map +1 -0
- package/dist/effects.d.ts +27 -11
- package/dist/effects.js +110 -0
- package/dist/effects.js.map +1 -0
- package/dist/endings.d.ts +1 -1
- package/dist/endings.js +78 -0
- package/dist/endings.js.map +1 -0
- package/dist/engagement.d.ts +40 -6
- package/dist/engagement.js +530 -0
- package/dist/engagement.js.map +1 -0
- package/dist/engineEvents.d.ts +72 -9
- package/dist/engineEvents.js +520 -0
- package/dist/engineEvents.js.map +1 -0
- package/dist/entity.d.ts +275 -26
- package/dist/entity.js +441 -0
- package/dist/entity.js.map +1 -0
- package/dist/entityIndex.d.ts +10 -3
- package/dist/entityIndex.js +149 -0
- package/dist/entityIndex.js.map +1 -0
- package/dist/errors.d.ts +6 -2
- package/dist/errors.js +59 -0
- package/dist/errors.js.map +1 -0
- package/dist/events.d.ts +11 -5
- package/dist/events.js +158 -0
- package/dist/events.js.map +1 -0
- package/dist/exactMath.js +273 -0
- package/dist/exactMath.js.map +1 -0
- package/dist/features.d.ts +1 -1
- package/dist/features.js +127 -0
- package/dist/features.js.map +1 -0
- package/dist/fields.d.ts +25 -5
- package/dist/fields.js +140 -0
- package/dist/fields.js.map +1 -0
- package/dist/fixture.d.ts +3 -3
- package/dist/fixture.js +512 -0
- package/dist/fixture.js.map +1 -0
- package/dist/fog.d.ts +26 -3
- package/dist/fog.js +333 -0
- package/dist/fog.js.map +1 -0
- package/dist/foliage.d.ts +476 -0
- package/dist/foliage.js +1478 -0
- package/dist/foliage.js.map +1 -0
- package/dist/foliageDebug.d.ts +57 -0
- package/dist/foliageDebug.js +172 -0
- package/dist/foliageDebug.js.map +1 -0
- package/dist/foliageRegrowth.d.ts +20 -0
- package/dist/foliageRegrowth.js +332 -0
- package/dist/foliageRegrowth.js.map +1 -0
- package/dist/formState.d.ts +67 -0
- package/dist/formState.js +65 -0
- package/dist/formState.js.map +1 -0
- package/dist/formation.d.ts +46 -8
- package/dist/formation.js +297 -0
- package/dist/formation.js.map +1 -0
- package/dist/forms.d.ts +58 -0
- package/dist/forms.js +146 -0
- package/dist/forms.js.map +1 -0
- package/dist/friendlyFire.d.ts +2 -2
- package/dist/friendlyFire.js +37 -0
- package/dist/friendlyFire.js.map +1 -0
- package/dist/game.d.ts +141 -48
- package/dist/game.js +834 -0
- package/dist/game.js.map +1 -0
- package/dist/gameData.d.ts +96 -22
- package/dist/gameData.js +1690 -0
- package/dist/gameData.js.map +1 -0
- package/dist/gameFiles.d.ts +3 -3
- package/dist/gameFiles.js +14 -0
- package/dist/gameFiles.js.map +1 -0
- package/dist/gates.js +92 -0
- package/dist/gates.js.map +1 -0
- package/dist/generate.d.ts +28 -1
- package/dist/generate.js +1062 -0
- package/dist/generate.js.map +1 -0
- package/dist/generateWorker.d.ts +7 -3
- package/dist/generateWorker.js +86 -0
- package/dist/generateWorker.js.map +1 -0
- package/dist/grid.d.ts +9 -0
- package/dist/grid.js +102 -0
- package/dist/grid.js.map +1 -0
- package/dist/ground.d.ts +17 -1
- package/dist/ground.js +375 -0
- package/dist/ground.js.map +1 -0
- package/dist/groundObjects.d.ts +70 -0
- package/dist/groundObjects.js +371 -0
- package/dist/groundObjects.js.map +1 -0
- package/dist/groundSpeed.d.ts +20 -3
- package/dist/groundSpeed.js +117 -0
- package/dist/groundSpeed.js.map +1 -0
- package/dist/hero.d.ts +126 -10
- package/dist/hero.js +432 -0
- package/dist/hero.js.map +1 -0
- package/dist/holds.d.ts +94 -0
- package/dist/holds.js +305 -0
- package/dist/holds.js.map +1 -0
- package/dist/home.d.ts +1 -1
- package/dist/home.js +30 -0
- package/dist/home.js.map +1 -0
- package/dist/hooks.d.ts +339 -57
- package/dist/hooks.js +105 -0
- package/dist/hooks.js.map +1 -0
- package/dist/hotReload.d.ts +6 -5
- package/dist/hotReload.js +145 -0
- package/dist/hotReload.js.map +1 -0
- package/dist/ids.d.ts +3 -3
- package/dist/ids.js +30 -0
- package/dist/ids.js.map +1 -0
- package/dist/idsFile.d.ts +36 -0
- package/dist/idsFile.js +134 -0
- package/dist/idsFile.js.map +1 -0
- package/dist/index.d.ts +105 -68
- package/dist/index.js +194 -4701
- package/dist/inspect.d.ts +29 -2
- package/dist/{inspect-D9dWHmZ0.js → inspect.js} +21 -12
- package/dist/inspect.js.map +1 -0
- package/dist/inventory.d.ts +14 -1
- package/dist/inventory.js +84 -0
- package/dist/inventory.js.map +1 -0
- package/dist/items.d.ts +136 -8
- package/dist/items.js +585 -0
- package/dist/items.js.map +1 -0
- package/dist/lanes.d.ts +12 -3
- package/dist/lanes.js +496 -0
- package/dist/lanes.js.map +1 -0
- package/dist/life.d.ts +6 -2
- package/dist/life.js +287 -0
- package/dist/life.js.map +1 -0
- package/dist/log.d.ts +26 -3
- package/dist/log.js +192 -0
- package/dist/log.js.map +1 -0
- package/dist/manaBurn.d.ts +2 -2
- package/dist/manaBurn.js +75 -0
- package/dist/manaBurn.js.map +1 -0
- package/dist/map/file.d.ts +56 -3
- package/dist/map/file.js +264 -0
- package/dist/map/file.js.map +1 -0
- package/dist/map/images.js +61 -0
- package/dist/map/images.js.map +1 -0
- package/dist/map/look.d.ts +1 -1
- package/dist/map/look.js +30 -0
- package/dist/map/look.js.map +1 -0
- package/dist/map/pathProfile.js +183 -0
- package/dist/map/pathProfile.js.map +1 -0
- package/dist/map/resize.d.ts +4 -0
- package/dist/map/resize.js +136 -0
- package/dist/map/resize.js.map +1 -0
- package/dist/map/schema.js +257 -0
- package/dist/map/schema.js.map +1 -0
- package/dist/map/terrain.js +214 -0
- package/dist/map/terrain.js.map +1 -0
- package/dist/map/types.d.ts +92 -13
- package/dist/map/types.js +251 -0
- package/dist/map/types.js.map +1 -0
- package/dist/mapCheck/cells.js +94 -0
- package/dist/mapCheck/cells.js.map +1 -0
- package/dist/mapCheck/rules/foliage.d.ts +9 -0
- package/dist/mapCheck/rules/foliage.js +83 -0
- package/dist/mapCheck/rules/foliage.js.map +1 -0
- package/dist/mapCheck/rules/names.js +39 -0
- package/dist/mapCheck/rules/names.js.map +1 -0
- package/dist/mapCheck/rules/objects.d.ts +1 -1
- package/dist/mapCheck/rules/objects.js +56 -0
- package/dist/mapCheck/rules/objects.js.map +1 -0
- package/dist/mapCheck/rules/paths.js +32 -0
- package/dist/mapCheck/rules/paths.js.map +1 -0
- package/dist/mapCheck/rules/players.js +20 -0
- package/dist/mapCheck/rules/players.js.map +1 -0
- package/dist/mapCheck/rules/races.js +56 -0
- package/dist/mapCheck/rules/races.js.map +1 -0
- package/dist/mapCheck/rules/random.js +47 -0
- package/dist/mapCheck/rules/random.js.map +1 -0
- package/dist/mapCheck/rules/regions.js +30 -0
- package/dist/mapCheck/rules/regions.js.map +1 -0
- package/dist/mapCheck/rules/targets.js +31 -0
- package/dist/mapCheck/rules/targets.js.map +1 -0
- package/dist/mapCheck/rules/walking.js +45 -0
- package/dist/mapCheck/rules/walking.js.map +1 -0
- package/dist/mapCheck.d.ts +2 -2
- package/dist/mapCheck.js +63 -0
- package/dist/mapCheck.js.map +1 -0
- package/dist/mapFields.d.ts +25 -2
- package/dist/mapFields.js +134 -0
- package/dist/mapFields.js.map +1 -0
- package/dist/mapFile.js +176 -0
- package/dist/mapFile.js.map +1 -0
- package/dist/mapMeasure.d.ts +8 -0
- package/dist/mapMeasure.js +283 -0
- package/dist/mapMeasure.js.map +1 -0
- package/dist/mapMerge.d.ts +1 -0
- package/dist/mapMerge.js +172 -0
- package/dist/mapMerge.js.map +1 -0
- package/dist/mapObjectives.js +138 -0
- package/dist/mapObjectives.js.map +1 -0
- package/dist/mapObjects.js +80 -0
- package/dist/mapObjects.js.map +1 -0
- package/dist/math.d.ts +37 -7
- package/dist/math.js +155 -0
- package/dist/math.js.map +1 -0
- package/dist/messages.d.ts +71 -4
- package/dist/messages.js +29 -0
- package/dist/messages.js.map +1 -0
- package/dist/missionRules.d.ts +10 -2
- package/dist/{missionRules-C-bGxm0Q.js → missionRules.js} +30 -150
- package/dist/missionRules.js.map +1 -0
- package/dist/mods.d.ts +39 -20
- package/dist/mods.js +271 -0
- package/dist/mods.js.map +1 -0
- package/dist/moves.d.ts +87 -0
- package/dist/moves.js +539 -0
- package/dist/moves.js.map +1 -0
- package/dist/names.d.ts +7 -0
- package/dist/names.js +122 -0
- package/dist/names.js.map +1 -0
- package/dist/navigation/agentParams.js +14 -0
- package/dist/navigation/agentParams.js.map +1 -0
- package/dist/navigation/air.d.ts +7 -3
- package/dist/navigation/air.js +401 -0
- package/dist/navigation/air.js.map +1 -0
- package/dist/navigation/builds.d.ts +34 -2
- package/dist/navigation/builds.js +287 -0
- package/dist/navigation/builds.js.map +1 -0
- package/dist/navigation/groundAreas.d.ts +59 -1
- package/dist/navigation/groundAreas.js +407 -0
- package/dist/navigation/groundAreas.js.map +1 -0
- package/dist/navigation/navigation.d.ts +98 -9
- package/dist/navigation/recast.d.ts +194 -18
- package/dist/navigation/recast.js +1379 -0
- package/dist/navigation/recast.js.map +1 -0
- package/dist/navigation/sidePaths.d.ts +8 -3
- package/dist/navigation/sidePaths.js +241 -0
- package/dist/navigation/sidePaths.js.map +1 -0
- package/dist/navigation/sized.js +243 -0
- package/dist/navigation/sized.js.map +1 -0
- package/dist/nearest.js +32 -0
- package/dist/nearest.js.map +1 -0
- package/dist/noise.js +59 -0
- package/dist/noise.js.map +1 -0
- package/dist/objectives.d.ts +12 -3
- package/dist/objectives.js +144 -0
- package/dist/objectives.js.map +1 -0
- package/dist/orders/basic.d.ts +5 -5
- package/dist/orders/basic.js +417 -0
- package/dist/orders/basic.js.map +1 -0
- package/dist/orders/build.js +278 -0
- package/dist/orders/build.js.map +1 -0
- package/dist/orders/cast.d.ts +13 -3
- package/dist/orders/cast.js +558 -0
- package/dist/orders/cast.js.map +1 -0
- package/dist/orders/facts.js +16 -0
- package/dist/orders/facts.js.map +1 -0
- package/dist/orders/harvest.d.ts +21 -5
- package/dist/orders/harvest.js +540 -0
- package/dist/orders/harvest.js.map +1 -0
- package/dist/orders/idle.d.ts +3 -1
- package/dist/orders/idle.js +234 -0
- package/dist/orders/idle.js.map +1 -0
- package/dist/orders/items.js +92 -0
- package/dist/orders/items.js.map +1 -0
- package/dist/orders/queue.js +108 -0
- package/dist/orders/queue.js.map +1 -0
- package/dist/orders/waiting.d.ts +39 -0
- package/dist/orders/waiting.js +149 -0
- package/dist/orders/waiting.js.map +1 -0
- package/dist/pack.schema.js +13 -0
- package/dist/pack.schema.js.map +1 -0
- package/dist/pack.schema.json +7622 -841
- package/dist/packs/director/index.d.ts +13 -5
- package/dist/packs/director/index.js +204 -0
- package/dist/packs/director/index.js.map +1 -0
- package/dist/packs/heroes/campaign.d.ts +3 -2
- package/dist/packs/heroes/campaign.js +241 -0
- package/dist/packs/heroes/campaign.js.map +1 -0
- package/dist/packs/heroes/carry.d.ts +6 -0
- package/dist/packs/heroes/carry.js +112 -0
- package/dist/packs/heroes/carry.js.map +1 -0
- package/dist/packs/heroes/commands.js +115 -0
- package/dist/packs/heroes/commands.js.map +1 -0
- package/dist/packs/heroes/fallen.d.ts +43 -0
- package/dist/packs/heroes/fallen.js +61 -0
- package/dist/packs/heroes/fallen.js.map +1 -0
- package/dist/packs/heroes/hire.js +60 -0
- package/dist/packs/heroes/hire.js.map +1 -0
- package/dist/packs/heroes/index.d.ts +7 -6
- package/dist/packs/heroes/index.js +130 -0
- package/dist/packs/heroes/index.js.map +1 -0
- package/dist/packs/heroes/loop.d.ts +95 -0
- package/dist/packs/heroes/loop.js +250 -0
- package/dist/packs/heroes/loop.js.map +1 -0
- package/dist/packs/heroes/making.d.ts +6 -3
- package/dist/packs/heroes/making.js +55 -0
- package/dist/packs/heroes/making.js.map +1 -0
- package/dist/packs/heroes/respawn.d.ts +3 -3
- package/dist/packs/heroes/respawn.js +87 -0
- package/dist/packs/heroes/respawn.js.map +1 -0
- package/dist/packs/heroes/sets.d.ts +32 -0
- package/dist/packs/heroes/sets.js +51 -0
- package/dist/packs/heroes/sets.js.map +1 -0
- package/dist/packs/heroes/spells.d.ts +16 -0
- package/dist/packs/heroes/spells.js +269 -0
- package/dist/packs/heroes/spells.js.map +1 -0
- package/dist/packs/items/defaults.d.ts +43 -0
- package/dist/packs/items/defaults.js +1504 -0
- package/dist/packs/items/defaults.js.map +1 -0
- package/dist/packs/items/index.d.ts +27 -0
- package/dist/packs/items/index.js +214 -0
- package/dist/packs/items/index.js.map +1 -0
- package/dist/packs/moba/index.d.ts +3 -3
- package/dist/packs/moba/index.js +174 -0
- package/dist/packs/moba/index.js.map +1 -0
- package/dist/packs/pack.d.ts +15 -15
- package/dist/packs/pack.js +14 -0
- package/dist/packs/pack.js.map +1 -0
- package/dist/packs.d.ts +15 -7
- package/dist/packs.js +222 -0
- package/dist/packs.js.map +1 -0
- package/dist/paths.d.ts +2 -0
- package/dist/paths.js +109 -0
- package/dist/paths.js.map +1 -0
- package/dist/plain.js +57 -0
- package/dist/plain.js.map +1 -0
- package/dist/player.d.ts +33 -10
- package/dist/player.js +159 -0
- package/dist/player.js.map +1 -0
- package/dist/portals.d.ts +1 -1
- package/dist/portals.js +194 -0
- package/dist/portals.js.map +1 -0
- package/dist/prefabs.d.ts +25 -2
- package/dist/prefabs.js +239 -0
- package/dist/prefabs.js.map +1 -0
- package/dist/presetBuildings.js +58 -0
- package/dist/presetBuildings.js.map +1 -0
- package/dist/presetFoliage.d.ts +27 -0
- package/dist/presetFoliage.js +98 -0
- package/dist/presetFoliage.js.map +1 -0
- package/dist/presetGround.js +65 -0
- package/dist/presetGround.js.map +1 -0
- package/dist/proxies.d.ts +12 -0
- package/dist/proxies.js +79 -0
- package/dist/proxies.js.map +1 -0
- package/dist/query.d.ts +56 -0
- package/dist/query.js +88 -0
- package/dist/query.js.map +1 -0
- package/dist/races.d.ts +15 -14
- package/dist/races.js +172 -0
- package/dist/races.js.map +1 -0
- package/dist/randomGroups.js +91 -0
- package/dist/randomGroups.js.map +1 -0
- package/dist/registry.d.ts +117 -53
- package/dist/registry.js +323 -0
- package/dist/registry.js.map +1 -0
- package/dist/remains.d.ts +11 -9
- package/dist/remains.js +188 -0
- package/dist/remains.js.map +1 -0
- package/dist/replication.d.ts +12 -7
- package/dist/replication.js +100 -0
- package/dist/replication.js.map +1 -0
- package/dist/rng.d.ts +2 -0
- package/dist/rng.js +40 -0
- package/dist/rng.js.map +1 -0
- package/dist/rules.d.ts +186 -99
- package/dist/rules.js +179 -0
- package/dist/rules.js.map +1 -0
- package/dist/rulesCheck.d.ts +5 -4
- package/dist/rulesCheck.js +693 -0
- package/dist/rulesCheck.js.map +1 -0
- package/dist/runes.d.ts +2 -2
- package/dist/runes.js +80 -0
- package/dist/runes.js.map +1 -0
- package/dist/save.d.ts +37 -12
- package/dist/save.js +532 -0
- package/dist/save.js.map +1 -0
- package/dist/scenario.d.ts +2 -2
- package/dist/scenario.js +99 -0
- package/dist/scenario.js.map +1 -0
- package/dist/scheduler.d.ts +3 -0
- package/dist/scheduler.js +156 -0
- package/dist/scheduler.js.map +1 -0
- package/dist/score.d.ts +19 -19
- package/dist/score.js +709 -0
- package/dist/score.js.map +1 -0
- package/dist/sequences.d.ts +10 -6
- package/dist/sequences.js +206 -0
- package/dist/sequences.js.map +1 -0
- package/dist/server/doorman.js +154 -0
- package/dist/server/doorman.js.map +1 -0
- package/dist/server/gameServer.d.ts +16 -1
- package/dist/server/gameServer.js +643 -0
- package/dist/server/gameServer.js.map +1 -0
- package/dist/server/index.d.ts +1 -1
- package/dist/server/lobby.js +199 -0
- package/dist/server/lobby.js.map +1 -0
- package/dist/server/log.js +18 -0
- package/dist/server/log.js.map +1 -0
- package/dist/server/match.js +267 -0
- package/dist/server/match.js.map +1 -0
- package/dist/server/mode.d.ts +18 -9
- package/dist/server/mode.js +220 -0
- package/dist/server/mode.js.map +1 -0
- package/dist/{navigation-worker.js → server/navigation-worker.js} +1 -1
- package/dist/server/navigation-worker.js.map +1 -0
- package/dist/server/navigation.js +39 -0
- package/dist/server/navigation.js.map +1 -0
- package/dist/server/ops.d.ts +4 -0
- package/dist/server/ops.js +137 -0
- package/dist/server/ops.js.map +1 -0
- package/dist/server/packs.d.ts +3 -3
- package/dist/server/packs.js +32 -0
- package/dist/server/packs.js.map +1 -0
- package/dist/server/ratings.d.ts +5 -0
- package/dist/server/ratings.js +104 -0
- package/dist/server/ratings.js.map +1 -0
- package/dist/server/relay.d.ts +12 -2
- package/dist/server/relay.js +144 -0
- package/dist/server/relay.js.map +1 -0
- package/dist/server/rooms.d.ts +9 -2
- package/dist/server/rooms.js +442 -0
- package/dist/server/rooms.js.map +1 -0
- package/dist/server/seat.js +116 -0
- package/dist/server/seat.js.map +1 -0
- package/dist/server/seatSettings.d.ts +3 -3
- package/dist/server/seatSettings.js +63 -0
- package/dist/server/seatSettings.js.map +1 -0
- package/dist/server/secret.js +13 -0
- package/dist/server/secret.js.map +1 -0
- package/dist/server/start.d.ts +13 -6
- package/dist/server/start.js +76 -0
- package/dist/server/start.js.map +1 -0
- package/dist/server/websocket.d.ts +9 -1
- package/dist/server/websocket.js +306 -0
- package/dist/server/websocket.js.map +1 -0
- package/dist/server.js +15 -2861
- package/dist/session/can.js +26 -0
- package/dist/session/can.js.map +1 -0
- package/dist/session/commandReplay.d.ts +8 -2
- package/dist/session/commandReplay.js +293 -0
- package/dist/session/commandReplay.js.map +1 -0
- package/dist/session/debug.js +151 -0
- package/dist/session/debug.js.map +1 -0
- package/dist/session/delay.js +62 -0
- package/dist/session/delay.js.map +1 -0
- package/dist/session/delta.d.ts +14 -1
- package/dist/session/delta.js +407 -0
- package/dist/session/delta.js.map +1 -0
- package/dist/session/entityState.js +415 -0
- package/dist/session/entityState.js.map +1 -0
- package/dist/session/local.d.ts +47 -5
- package/dist/session/local.js +670 -0
- package/dist/session/local.js.map +1 -0
- package/dist/session/memory.d.ts +20 -2
- package/dist/session/memory.js +131 -0
- package/dist/session/memory.js.map +1 -0
- package/dist/session/protocol.d.ts +325 -31
- package/dist/session/protocol.js +55 -0
- package/dist/session/protocol.js.map +1 -0
- package/dist/session/remote.d.ts +74 -12
- package/dist/session/remote.js +1394 -0
- package/dist/session/remote.js.map +1 -0
- package/dist/session/replay.d.ts +11 -2
- package/dist/session/replay.js +160 -0
- package/dist/session/replay.js.map +1 -0
- package/dist/session/seed.js +12 -0
- package/dist/session/seed.js.map +1 -0
- package/dist/session/share.d.ts +5 -1
- package/dist/session/share.js +94 -0
- package/dist/session/share.js.map +1 -0
- package/dist/session/socket.d.ts +1 -1
- package/dist/session/socket.js +29 -0
- package/dist/session/socket.js.map +1 -0
- package/dist/session/wire.d.ts +5 -0
- package/dist/session/wire.js +84 -0
- package/dist/session/wire.js.map +1 -0
- package/dist/session/worker.d.ts +77 -12
- package/dist/session/worker.js +499 -0
- package/dist/session/worker.js.map +1 -0
- package/dist/shared.d.ts +31 -5
- package/dist/shared.js +166 -0
- package/dist/shared.js.map +1 -0
- package/dist/sides.d.ts +9 -3
- package/dist/sides.js +149 -0
- package/dist/sides.js.map +1 -0
- package/dist/sight.js +85 -0
- package/dist/sight.js.map +1 -0
- package/dist/simulate-worker.js +1 -1
- package/dist/simulate.d.ts +12 -8
- package/dist/{simulate-oXBiw1Ff.js → simulate.js} +10 -11
- package/dist/simulate.js.map +1 -0
- package/dist/smart.js +77 -0
- package/dist/smart.js.map +1 -0
- package/dist/spatial.d.ts +32 -16
- package/dist/spatial.js +234 -0
- package/dist/spatial.js.map +1 -0
- package/dist/spawning.d.ts +1 -0
- package/dist/spawning.js +224 -0
- package/dist/spawning.js.map +1 -0
- package/dist/stances.d.ts +6 -3
- package/dist/stances.js +169 -0
- package/dist/stances.js.map +1 -0
- package/dist/start.d.ts +10 -10
- package/dist/start.js +75 -0
- package/dist/start.js.map +1 -0
- package/dist/stats.d.ts +42 -16
- package/dist/stats.js +290 -0
- package/dist/stats.js.map +1 -0
- package/dist/summoned.d.ts +52 -0
- package/dist/summoned.js +38 -0
- package/dist/summoned.js.map +1 -0
- package/dist/summons.d.ts +10 -13
- package/dist/summons.js +271 -0
- package/dist/summons.js.map +1 -0
- package/dist/systems/abilities.js +224 -0
- package/dist/systems/abilities.js.map +1 -0
- package/dist/systems/combat.d.ts +35 -1
- package/dist/systems/combat.js +677 -0
- package/dist/systems/combat.js.map +1 -0
- package/dist/systems/combatTold.d.ts +3 -1
- package/dist/systems/combatTold.js +85 -0
- package/dist/systems/combatTold.js.map +1 -0
- package/dist/systems/construction.js +80 -0
- package/dist/systems/construction.js.map +1 -0
- package/dist/systems/economy.d.ts +0 -6
- package/dist/systems/economy.js +128 -0
- package/dist/systems/economy.js.map +1 -0
- package/dist/systems/fog.d.ts +1 -1
- package/dist/systems/fog.js +120 -0
- package/dist/systems/fog.js.map +1 -0
- package/dist/systems/life.js +32 -0
- package/dist/systems/life.js.map +1 -0
- package/dist/systems/movement.d.ts +24 -12
- package/dist/systems/movement.js +1247 -0
- package/dist/systems/movement.js.map +1 -0
- package/dist/systems/orders.js +64 -0
- package/dist/systems/orders.js.map +1 -0
- package/dist/systems/production.js +322 -0
- package/dist/systems/production.js.map +1 -0
- package/dist/systems/productionQueue.js +120 -0
- package/dist/systems/productionQueue.js.map +1 -0
- package/dist/systems/victory.d.ts +1 -1
- package/dist/systems/victory.js +56 -0
- package/dist/systems/victory.js.map +1 -0
- package/dist/talk.d.ts +6 -6
- package/dist/talk.js +153 -0
- package/dist/talk.js.map +1 -0
- package/dist/targeting.d.ts +142 -0
- package/dist/targeting.js +49 -0
- package/dist/targeting.js.map +1 -0
- package/dist/tech.d.ts +20 -3
- package/dist/tech.js +239 -0
- package/dist/tech.js.map +1 -0
- package/dist/techTree.d.ts +7 -0
- package/dist/techTree.js +90 -0
- package/dist/techTree.js.map +1 -0
- package/dist/terrain.d.ts +59 -7
- package/dist/terrain.js +389 -0
- package/dist/terrain.js.map +1 -0
- package/dist/terrainSave.d.ts +6 -0
- package/dist/terrainSave.js +74 -0
- package/dist/terrainSave.js.map +1 -0
- package/dist/testing.d.ts +8 -7
- package/dist/testing.js +13 -739
- package/dist/testing.js.map +1 -1
- package/dist/tiles.d.ts +1 -1
- package/dist/tiles.js +43 -0
- package/dist/tiles.js.map +1 -0
- package/dist/timers.d.ts +29 -4
- package/dist/timers.js +242 -0
- package/dist/timers.js.map +1 -0
- package/dist/tomes.d.ts +4 -4
- package/dist/tomes.js +94 -0
- package/dist/tomes.js.map +1 -0
- package/dist/trade.js +103 -0
- package/dist/trade.js.map +1 -0
- package/dist/transport.d.ts +6 -1
- package/dist/transport.js +281 -0
- package/dist/transport.js.map +1 -0
- package/dist/tunables.d.ts +10 -3
- package/dist/tunables.js +56 -0
- package/dist/tunables.js.map +1 -0
- package/dist/unitResources.d.ts +67 -0
- package/dist/unitResources.js +266 -0
- package/dist/unitResources.js.map +1 -0
- package/dist/upkeep.d.ts +6 -1
- package/dist/upkeep.js +26 -0
- package/dist/upkeep.js.map +1 -0
- package/dist/veterancy.d.ts +8 -3
- package/dist/veterancy.js +131 -0
- package/dist/veterancy.js.map +1 -0
- package/dist/vision.d.ts +36 -0
- package/dist/vision.js +133 -0
- package/dist/vision.js.map +1 -0
- package/dist/walls.d.ts +1 -1
- package/dist/walls.js +278 -0
- package/dist/walls.js.map +1 -0
- package/dist/world.d.ts +606 -88
- package/dist/world.js +1263 -0
- package/dist/world.js.map +1 -0
- package/package.json +2 -2
- package/dist/ai.js.map +0 -1
- package/dist/attributes.d.ts +0 -66
- package/dist/brain-BvVdUhX8.js +0 -7659
- package/dist/brain-BvVdUhX8.js.map +0 -1
- package/dist/builds-C6LfgvEU.js +0 -460
- package/dist/builds-C6LfgvEU.js.map +0 -1
- package/dist/coreComponents-syuh2fPG.js +0 -5149
- package/dist/coreComponents-syuh2fPG.js.map +0 -1
- package/dist/debugCommands-CzjrSm66.js +0 -14739
- package/dist/debugCommands-CzjrSm66.js.map +0 -1
- package/dist/determinism-BCymQwiE.js +0 -518
- package/dist/determinism-BCymQwiE.js.map +0 -1
- package/dist/game-DiJEN-Ks.js +0 -5800
- package/dist/game-DiJEN-Ks.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/inspect-D9dWHmZ0.js.map +0 -1
- package/dist/local-Dkovq42k.js +0 -1379
- package/dist/local-Dkovq42k.js.map +0 -1
- package/dist/missionRules-C-bGxm0Q.js.map +0 -1
- package/dist/navigation-worker.js.map +0 -1
- package/dist/packs-g5thvmGn.js +0 -3199
- package/dist/packs-g5thvmGn.js.map +0 -1
- package/dist/profiles-B3NS9jwk.js.map +0 -1
- package/dist/server.js.map +0 -1
- package/dist/simulate-oXBiw1Ff.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lanes.js","names":[],"sources":["../../src/ai/lanes.ts"],"sourcesContent":["import { exp } from '#engine/exactMath'\nimport { farthestReach } from '#engine/attacks'\nimport { Team } from './team'\nimport type { Lane } from '#engine/lanes'\nimport { distSq, type Vec2 } from '#engine/math'\nimport type { EntityState } from '#engine/session/protocol'\nimport { type Brain, type BrainDef, type BrainExtension } from './brain'\nimport { type AiModule, type AiModuleDef, defineModule, moduleKey } from './module'\nimport { defineBrain } from './define'\nimport { consider, curve, defineGoal, type GoalDef, goals } from './goals'\nimport { micro, type TargetPicker } from './micro'\nimport { rules, words } from './rules'\nimport { type Squad, squads } from './squads'\nimport { defineTask, type TaskState } from './task'\nimport { team } from './team'\nimport type { UnitSet } from './view'\nimport { heroOfState } from '#engine/hero'\nimport { point, where } from './geometry'\nimport { LANE_ENGAGED, RESEND } from './reach'\n\n/*\n * The lanes brain (AI plan, D5): a computer player for a game of lanes, as in a MOBA (`lanesPack`, `docs/use-cases/\n * lanes.md`). No economy, no building, no army of its own to train: each player is a hero or two, and the waves of\n * minions walk the lanes by themselves (the lanes' rules send them). What a player does is where its hero goes: along\n * a lane behind its own wave, back home when hurt, to an ally's hero in a fight, to a camp of creeps when there is no\n * wave to walk with. It is the proof that the kit is not a melee's alone: the same goals, squads, micro and team\n * play, without the economy, the plans or the waves of D2.\n *\n * Its modules: its rules and the words every brain may be told (B2), `lanes` (this file: the lanes read, the heroes'\n * rest, and the goals below put on the picker), `team` (C5: the team's board, people's pings), the picker (B1), squads\n * (C1) and micro (C2: whom a hero hits, its spells, its potions, the shop, its skills). The minions are the lanes', not\n * the computer's: no goal claims them (only what it `commands`, its heroes), so they walk on as the lanes sent them.\n *\n * **Its goals**, one picker, each holding the heroes it runs with (B1's \"who may move a unit\"):\n *\n * - `lanes.push:<lane>` (one a lane, 1): the hero walks the lane a little behind its side's wave (the minion of its side\n * furthest along it, its **front**), fighting what comes; with no wave there, it waits by its side's furthest tower on\n * the lane. It never steps into reach of one of their towers with no minion of its side there to take the shots, and\n * falls back along the lane once outmatched where it stands (`backOdds`). Scored by the wave of its side on the lane,\n * the odds at its front, the allies' heroes there already (two heroes of a side on one lane leave another lane alone)\n * and how far the hero is from it: the lane with the most of its side's strength, and no ally on it, comes first.\n * - `lanes.back` (urgent, 10): a hero under `backAt` of its health goes home (by an ability that takes it home, where\n * it has one and nothing is near, else on foot) and rests there until it is back at `returnAt`, or `restFor` seconds\n * have passed: at home, micro's shopping buys it a potion and drinks it.\n * - `lanes.help` (1.3): an ally's hero in a fight with one of theirs, near enough, where the odds with it are good: the\n * hero goes with it (the `escort` task), and back to its lane once the fight is over. A person's ping for help (the\n * team's board) is one too.\n * - `lanes.camp` (0.6): with no wave of its side on any lane (before the first, between two), the hero takes the nearest\n * camp of creeps it can beat.\n *\n * **Whom a hero hits** (`lanesTargets`, micro's picker): a minion its next hit kills (a last hit: what gives the\n * bounty), else one of their heroes not under one of their towers (a hero hit there turns the towers on the one who hit\n * it: `lanesPack`), else a building (a tower its side's minions are taking the shots of, their core), else the weakest\n * of the rest. Never a hero or anything else under their tower with no minion of its side in that tower's reach.\n *\n * Every number has a data form (`LanesPlayOptions`, the seat's `AiOptions.lanes` over the module's); which units it\n * commands and where home is have a function form.\n */\n\n/**\n * How a lanes brain plays (`lanesPlay(options)`, the seat's `AiOptions.lanes` over it): its heroes' rest, how far it\n * goes for an ally or a camp, how near its wave it walks. Data, but for `units` and `home` as functions\n *\n * @beta\n */\nexport interface LanesPlayOptions {\n\t/**\n\t * Which of its units it commands: its heroes when left out. The rest (the minions) are the lanes', and walk as they\n\t * were sent\n\t */\n\tunits?: (ai: Brain, unit: EntityState) => boolean\n\t/** Where its heroes go to rest: a point, or a function. Its side's building by its side's ends of the lanes when left out (a core) */\n\thome?: Vec2 | ((ai: Brain) => Vec2 | undefined)\n\t/** Only these lanes, by their path's name: every lane of the map when left out */\n\tlanes?: string[]\n\t/** The share of its health under which a hero goes home to rest: 0.35 */\n\tbackAt?: number\n\t/** The share at which a resting hero goes back out: 0.85 */\n\treturnAt?: number\n\t/** Seconds a hero rests at home at most, healed or not: 40 */\n\trestFor?: number\n\t/** Whether a hero going home uses an ability that takes it there (a recall), where nothing hostile is near: yes when left out */\n\trecall?: boolean\n\t/** The odds where a hero stands on its lane under which it falls back along it: 0.3 */\n\tbackOdds?: number\n\t/** How many cells behind its side's wave a hero walks: 3 */\n\tbehind?: number\n\t/** An ally's hero in a fight it goes to: within `reach` cells of it (30), where the odds with it are at least `odds` (0.4). `false` never */\n\thelp?: false | { reach?: number; odds?: number }\n\t/** A camp it takes with no wave to walk with: within `reach` cells (50), where the odds against it are at least `odds` (0.6). `false` never */\n\tcamps?: false | { reach?: number; odds?: number }\n\t/** Whether a hero hits the minion its next hit kills before anything else (a last hit): yes when left out */\n\tlastHits?: boolean\n}\n\n/**\n * What the lanes module remembers between thinks, as a save keeps it: the heroes resting, since when; when each last\n * used an ability that takes it home\n *\n * @beta\n */\nexport interface LanesPlayMemory {\n\t/** The version of the memory's format: 1 so far */\n\tv: 1\n\t/** The heroes resting, by id: the tick they turned for home */\n\tresting: Record<string, number>\n\t/** When each hero last set off home by its recall, by id */\n\trecalled: Record<string, number>\n\t/** When each resting hero was last sent home on foot, by id */\n\tsent: Record<string, number>\n}\n\n/**\n * A lane as one side reads it (`LanesPlay.lanes`): the path, measured from that side's end (`from`: the end its own\n * spawner stands at), its length\n *\n * @beta\n */\nexport interface LaneSide {\n\t/** The name of its path: what the goal and squad of the lane are named by (`lanes.push:mid`) */\n\tpath: string\n\t/** The path's points in order, in cells */\n\tpoints: readonly Vec2[]\n\t/** The end of the lane that is its side's: 0 the first point's, 1 the last's */\n\tfrom: 0 | 1\n\t/** Cells from end to end, along it */\n\tlength: number\n}\n\n/**\n * A lane as it stands this think, for one side: its waves' fronts (in cells along it from its side's end), who is on\n * it, the towers by it\n *\n * @beta\n */\nexport interface LaneState {\n\t/** The lane, as its side reads it */\n\tlane: LaneSide\n\t/** How far along its side's furthest minion is: none with no minion of its side on the lane */\n\tfront?: number\n\t/** How far along their nearest minion is: none with none of theirs on it */\n\ttheirFront?: number\n\t/** Its side's minions on it (the player's own and its allies'), and theirs */\n\tours: EntityState[]\n\t/** Their minions on the lane */\n\ttheirs: EntityState[]\n\t/** The heroes on it: its allies' (the player's own left out), and theirs */\n\tallies: EntityState[]\n\t/** Their heroes on the lane */\n\tenemies: EntityState[]\n\t/** The towers by it, its side's and theirs (theirs as remembered), with how far along each stands */\n\tourTowers: { tower: EntityState; at: number }[]\n\t/** Their towers by the lane, each with how far along it stands in cells */\n\ttheirTowers: { tower: EntityState; at: number }[]\n}\n\n/** How far from a lane's line a unit is on it */\nconst ON_LANE = 7\n/** How far from a lane's line a tower is by it */\nconst BY_LANE = 9\n/** How near a hero is to where it was sent to be there */\nconst THERE = 4\n/** How far a hero's place on its lane moves before it is sent there again */\nconst MOVED = 4\n/** How near home a hero is home */\nconst HOME = 8\n/** How near an ally's hero one of theirs is for the two to be in a fight */\nconst FIGHTING = 10\n/** How far behind where it stands a hero falls back to, where none of its side's towers is nearer */\nconst FALL_BACK = 14\n/** Seconds between two recalls of a hero: one that was hurt in the channel walks */\nconst RECALL_AGAIN = 10\n\n/**\n * Where a place is along a line of points, and how far off it: `along` in cells from the first point, `off` from the\n * line's nearest point. What every question of a lane comes to\n */\nfunction measure(points: readonly Vec2[], at: Vec2): { along: number; off: number } {\n\tlet best = Infinity\n\tlet along = 0\n\tlet walked = 0\n\tfor (let i = 1; i < points.length; i++) {\n\t\tconst a = points[i - 1]\n\t\tconst dx = points[i].x - a.x\n\t\tconst dz = points[i].z - a.z\n\t\tconst lengthSq = dx * dx + dz * dz\n\t\tconst length = Math.sqrt(lengthSq)\n\t\tconst t = lengthSq > 0 ? Math.min(Math.max(((at.x - a.x) * dx + (at.z - a.z) * dz) / lengthSq, 0), 1) : 0\n\t\tconst ox = at.x - (a.x + dx * t)\n\t\tconst oz = at.z - (a.z + dz * t)\n\t\tconst off = ox * ox + oz * oz\n\t\tif (off < best) {\n\t\t\tbest = off\n\t\t\talong = walked + length * t\n\t\t}\n\t\twalked += length\n\t}\n\treturn { along, off: Math.sqrt(best) }\n}\n\n/** The length of a line of points */\nfunction lengthOf(points: readonly Vec2[]): number {\n\tlet length = 0\n\tfor (let i = 1; i < points.length; i++) length += Math.sqrt(distSq(points[i - 1], points[i]))\n\treturn length\n}\n\n/** The point so far along a line of points from its first */\nfunction pointAlong(points: readonly Vec2[], along: number): Vec2 {\n\tlet left = Math.max(0, along)\n\tfor (let i = 1; i < points.length; i++) {\n\t\tconst a = points[i - 1]\n\t\tconst length = Math.sqrt(distSq(a, points[i]))\n\t\tif (left <= length && length > 0) {\n\t\t\tconst t = left / length\n\t\t\treturn { x: a.x + (points[i].x - a.x) * t, z: a.z + (points[i].z - a.z) * t }\n\t\t}\n\t\tleft -= length\n\t}\n\treturn point(points[points.length - 1])\n}\n\n/**\n * Where a place is on a side's lane: how far along from the side's end, how far off the line\n *\n * @beta\n */\nexport function onLane(lane: LaneSide, at: Vec2): { along: number; off: number } {\n\tconst measured = measure(lane.points, at)\n\treturn { along: lane.from === 0 ? measured.along : lane.length - measured.along, off: measured.off }\n}\n\n/**\n * The point so far along a side's lane from its end\n *\n * @beta\n */\nexport function laneAt(lane: LaneSide, along: number): Vec2 {\n\tconst clamped = Math.min(Math.max(along, 0), lane.length)\n\treturn pointAlong(lane.points, lane.from === 0 ? clamped : lane.length - clamped)\n}\n\n/** A unit's share of its health */\nfunction health(ai: Brain, unit: EntityState): number {\n\tconst max = unit.maxHealth ?? ai.view.strength.statsOf(unit).health\n\treturn max > 0 ? unit.health / max : 1\n}\n\n/** How far a tower reaches: its attack's range and its size, a cell more */\nfunction reachOf(ai: Brain, tower: EntityState): number {\n\treturn farthestReach(ai.view.def(tower), ai.view.strength.statsOf(tower)) + ai.view.def(tower).radius + 1\n}\n\n/** Their towers, as remembered: buildings of theirs that attack */\nconst theirTowers = (ai: Brain): UnitSet =>\n\tai.cache('lanes.theirTowers', () =>\n\t\tai.view.enemies\n\t\t\t.known()\n\t\t\t.buildings()\n\t\t\t.alive()\n\t\t\t.where((_entity, def) => !!def.attacks?.length)\n\t)\n\n/** Whether a place is in reach of one of their towers with no minion of its side in that tower's reach to take the shots */\nfunction exposed(ai: Brain, at: Vec2, pad = 0): boolean {\n\tfor (const tower of theirTowers(ai)) {\n\t\tconst reach = reachOf(ai, tower) + pad\n\t\tif (distSq(tower, at) > reach * reach) continue\n\t\tconst covered = ai.view.all\n\t\t\t.units()\n\t\t\t.alive()\n\t\t\t.near(tower, reachOf(ai, tower))\n\t\t\t.where((unit) => ai.view.isFriendly(unit) && !heroOfState(unit) && !ai.view.def(unit).hero)\n\t\tif (!covered.length) return true\n\t}\n\treturn false\n}\n\n/**\n * Whom a hero of a lanes brain hits (micro's `targets`, the file's comment): the minion its next hit kills, one of their\n * heroes not under their tower, a building (a tower its side's minions take the shots of), the weakest of the rest; never\n * what stands where their tower would turn on it\n *\n * @beta\n */\nexport const lanesTargets =\n\t(options: Pick<LanesPlayOptions, 'lastHits'> = {}): TargetPicker =>\n\t(ai, squad, foes) => {\n\t\tconst { view } = ai\n\t\tconst hitters = squad.units()\n\t\tconst middle = hitters.centre()\n\t\tif (!middle) return undefined\n\t\t// what it may hit at all: not where their tower would turn on it (a hero hit under it), not a tower with nothing to tank it\n\t\tconst safe = foes.where((foe, def) => {\n\t\t\t// a tower with its side's minions in its reach to take its shots; any other building out of their towers' reach\n\t\t\tif (def.kind === 'building') return def.attacks?.length ? !exposed(ai, foe, -reachOf(ai, foe)) : !exposed(ai, foe)\n\t\t\tif (def.hero || heroOfState(foe))\n\t\t\t\treturn !theirTowers(ai).some((tower) => {\n\t\t\t\t\tconst reach = reachOf(ai, tower) + 2\n\t\t\t\t\treturn distSq(tower, foe) <= reach * reach\n\t\t\t\t})\n\t\t\treturn !exposed(ai, foe)\n\t\t})\n\t\tif (!safe.length) return undefined\n\t\tconst nearest = (set: readonly EntityState[]) =>\n\t\t\tset.reduce<EntityState | undefined>((best, each) => (!best || distSq(each, middle) < distSq(best, middle) ? each : best), undefined)\n\t\t// a last hit: a minion the hardest hitter's next blow kills\n\t\tif (options.lastHits !== false) {\n\t\t\tconst blow = Math.max(0, ...hitters.map((unit) => view.strength.statsOf(unit).attackDamage))\n\t\t\tconst dying = safe.where((foe, def) => def.kind === 'unit' && !def.hero && !heroOfState(foe) && foe.health <= blow)\n\t\t\tconst last = nearest(dying.items)\n\t\t\tif (last) return last\n\t\t}\n\t\tconst heroes = safe.where((foe, def) => !!def.hero || !!heroOfState(foe))\n\t\tif (heroes.length) return heroes.items.reduce((best, each) => (health(ai, each) < health(ai, best) ? each : best))\n\t\tconst buildings = safe.buildings()\n\t\tif (buildings.length) return nearest(buildings.items)\n\t\treturn safe.items.reduce((best, each) =>\n\t\t\teach.health < best.health || (each.health === best.health && distSq(each, middle) < distSq(best, middle)) ? each : best\n\t\t)\n\t}\n\n/**\n * The lanes of a lanes brain, read as its side sees them, and what its heroes do on them (`ai.module('lanes')`'s\n * `play`): the module's goals read it\n *\n * @beta\n */\nexport class LanesPlay {\n\t/** What the play keeps between thinks, as `LanesPlayMemory`: the heroes resting and when each was sent home */\n\treadonly memory: LanesPlayMemory = { v: 1, resting: {}, recalled: {}, sent: {} }\n\tprivate sides: LaneSide[] | undefined\n\n\tconstructor(\n\t\t/** The brain it plays for */\n\t\treadonly ai: Brain,\n\t\t/** How it plays: the module's, the seat's over it */\n\t\treadonly options: LanesPlayOptions\n\t) {}\n\n\t/** The lanes as its side reads them: each measured from the end its side's spawner stands at. None it has no end of */\n\tlanes(): readonly LaneSide[] {\n\t\tif (this.sides) return this.sides\n\t\tconst { view } = this.ai\n\t\tconst only = this.options.lanes\n\t\tconst ours = (end: Lane['ends'][number]) => !!end && (end.player === view.playerId || view.player(end.player)?.relation === 'ally')\n\t\tconst found: LaneSide[] = []\n\t\tfor (const lane of view.lanes()) {\n\t\t\tif (only && !only.includes(lane.path)) continue\n\t\t\tconst from = ours(lane.ends[0]) ? 0 : ours(lane.ends[1]) ? 1 : undefined\n\t\t\tif (from === undefined) continue\n\t\t\tfound.push({ path: lane.path, points: lane.points, from, length: lengthOf(lane.points) })\n\t\t}\n\t\t// found once the players are known: a view with no players yet (before the first snapshot) is asked again\n\t\tif (view.players.length) this.sides = found\n\t\treturn found\n\t}\n\n\t/** A lane of its side's, by its path's name */\n\tlane(path: string): LaneSide | undefined {\n\t\treturn this.lanes().find((lane) => lane.path === path)\n\t}\n\n\t/** The units it commands: its heroes, or what `units` says. Alive */\n\tcommanded(units: UnitSet = this.ai.view.mine): UnitSet {\n\t\tconst { units: commands } = this.options\n\t\tconst alive = units.units().alive()\n\t\treturn commands ? alive.where((unit) => commands(this.ai, unit)) : alive.heroes()\n\t}\n\n\t/**\n\t * Where its heroes rest: `home`, else its side's building nearest the middle of its side's ends of the lanes (a core),\n\t * else that middle, else its first building\n\t */\n\thome(): Vec2 | undefined {\n\t\tconst { home } = this.options\n\t\tif (home) return typeof home === 'function' ? home(this.ai) : point(home)\n\t\tconst ends = this.lanes().map((lane) => laneAt(lane, 0))\n\t\tif (ends.length) {\n\t\t\tconst middle = { x: ends.reduce((sum, end) => sum + end.x, 0) / ends.length, z: ends.reduce((sum, end) => sum + end.z, 0) / ends.length }\n\t\t\t// the building of its side there (a core, a fountain), where there is one: what heals and guards it\n\t\t\tconst { view } = this.ai\n\t\t\tconst building = view.all\n\t\t\t\t.buildings()\n\t\t\t\t.alive()\n\t\t\t\t.where((entity) => view.isFriendly(entity))\n\t\t\t\t.near(middle, HOME * 2)\n\t\t\t\t.nearest(middle)\n\t\t\treturn building ? point(building) : middle\n\t\t}\n\t\tconst first = this.ai.view.home()\n\t\treturn first && point(first)\n\t}\n\n\t/** Each lane as it stands this think: fronts, minions, heroes, towers. Once a think */\n\tstates(): readonly LaneState[] {\n\t\treturn this.ai.cache('lanes.states', () => this.lanes().map((lane) => this.stateOf(lane)))\n\t}\n\n\t/** One lane as it stands this think */\n\tstate(path: string): LaneState | undefined {\n\t\treturn this.states().find((state) => state.lane.path === path)\n\t}\n\n\tprivate stateOf(lane: LaneSide): LaneState {\n\t\tconst { ai } = this\n\t\tconst { view } = ai\n\t\tconst state: LaneState = { lane, ours: [], theirs: [], allies: [], enemies: [], ourTowers: [], theirTowers: [] }\n\t\tfor (const unit of view.all.units().alive()) {\n\t\t\tconst friendly = view.isFriendly(unit)\n\t\t\tif (!friendly && !(view.isHostile(unit) && !view.isCreep(unit))) continue\n\t\t\tconst { along, off } = onLane(lane, unit)\n\t\t\tif (off > ON_LANE) continue\n\t\t\tconst hero = !!view.def(unit).hero || !!heroOfState(unit)\n\t\t\tif (hero) {\n\t\t\t\tif (!friendly) state.enemies.push(unit)\n\t\t\t\telse if (unit.owner !== view.playerId) state.allies.push(unit)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (friendly) {\n\t\t\t\tstate.ours.push(unit)\n\t\t\t\tif (state.front === undefined || along > state.front) state.front = along\n\t\t\t} else {\n\t\t\t\tstate.theirs.push(unit)\n\t\t\t\tif (state.theirFront === undefined || along < state.theirFront) state.theirFront = along\n\t\t\t}\n\t\t}\n\t\tconst towers = view.all\n\t\t\t.known()\n\t\t\t.buildings()\n\t\t\t.alive()\n\t\t\t.where((_entity, def) => !!def.attacks?.length)\n\t\tfor (const tower of towers) {\n\t\t\tconst { along, off } = onLane(lane, tower)\n\t\t\tif (off > BY_LANE) continue\n\t\t\tif (view.isFriendly(tower)) state.ourTowers.push({ tower, at: along })\n\t\t\telse if (view.isHostile(tower) && !view.isCreep(tower)) state.theirTowers.push({ tower, at: along })\n\t\t}\n\t\treturn state\n\t}\n\n\t/**\n\t * Where a hero walks on a lane now: a little behind its side's front; with no wave there, by its side's furthest tower\n\t * on it (or a little out of its end); never into reach of a tower of theirs that no minion of its side is in reach of\n\t */\n\tspot(path: string): Vec2 | undefined {\n\t\tconst state = this.state(path)\n\t\tif (!state) return undefined\n\t\tconst { lane } = state\n\t\tconst behind = this.options.behind ?? 3\n\t\tlet along: number\n\t\tif (state.front !== undefined) along = state.front - behind\n\t\telse along = Math.max(6, ...state.ourTowers.map((each) => each.at - 2))\n\t\t// not into a tower's reach that its side's minions are not taking the shots of\n\t\tfor (const { tower, at } of state.theirTowers) {\n\t\t\tconst reach = reachOf(this.ai, tower)\n\t\t\tconst covered = state.ours.some((unit) => distSq(unit, tower) <= reach * reach)\n\t\t\tif (!covered && along > at - reach - 1) along = at - reach - 1\n\t\t}\n\t\treturn laneAt(lane, Math.max(0, along))\n\t}\n\n\t/**\n\t * What is at stake on a lane, 0..1: how far along its side's wave is (a tower of theirs to take, their core), or how\n\t * near its side's end theirs is (its own towers under attack), whichever is more\n\t */\n\tstake(path: string): number {\n\t\tconst state = this.state(path)\n\t\tif (!state) return 0\n\t\tconst { length } = state.lane\n\t\tconst ours = state.front === undefined ? 0 : state.front / length\n\t\tconst theirs = state.theirFront === undefined ? 0 : 1 - state.theirFront / length\n\t\treturn Math.min(1, Math.max(ours, theirs))\n\t}\n\n\t/** Where a hero outmatched on a lane falls back to: its side's nearest tower behind it, or so far back along it */\n\tfallBack(path: string, from: Vec2): Vec2 | undefined {\n\t\tconst state = this.state(path)\n\t\tif (!state) return undefined\n\t\tconst { along } = onLane(state.lane, from)\n\t\tconst behind = state.ourTowers.filter((each) => each.at < along - 2).sort((a, b) => b.at - a.at)[0]\n\t\treturn behind ? laneAt(state.lane, behind.at - 2) : laneAt(state.lane, along - FALL_BACK)\n\t}\n\n\t/** The odds of its side against theirs where a unit stands (`Strength.odds`): their towers that reach there count */\n\toddsAt(at: Vec2, reach = LANE_ENGAGED): number {\n\t\tconst { view } = this.ai\n\t\tconst near = view.all.units().alive().near(at, reach)\n\t\tconst ours = near.where((unit) => view.isFriendly(unit))\n\t\tconst theirs = [...near.where((unit) => view.isHostile(unit)).items]\n\t\tfor (const tower of theirTowers(this.ai)) {\n\t\t\tconst towerReach = reachOf(this.ai, tower)\n\t\t\tif (distSq(tower, at) <= towerReach * towerReach) theirs.push(tower)\n\t\t}\n\t\treturn theirs.length ? view.strength.odds(ours, theirs) : 1\n\t}\n\n\t/** The heroes resting, alive */\n\tresting(): readonly EntityState[] {\n\t\treturn this.commanded().where((hero) => this.memory.resting[hero.id] !== undefined).items\n\t}\n\n\t/** Heroes turned for home, those back out: what the `lanes.back` goal reads. Each think, before the goals */\n\tthink(): void {\n\t\tconst { ai } = this\n\t\tconst { memory } = this\n\t\tconst backAt = this.options.backAt ?? 0.35\n\t\tconst returnAt = this.options.returnAt ?? 0.85\n\t\tconst restFor = (this.options.restFor ?? 40) * ai.session.tickRate\n\t\tconst heroes = this.commanded()\n\t\tfor (const id in memory.resting) if (!heroes.has(Number(id))) delete memory.resting[id]\n\t\tfor (const id in memory.recalled) if (!heroes.has(Number(id))) delete memory.recalled[id]\n\t\tfor (const id in memory.sent) if (memory.resting[id] === undefined) delete memory.sent[id]\n\t\tfor (const hero of heroes) {\n\t\t\tconst share = health(ai, hero)\n\t\t\tconst since = memory.resting[hero.id]\n\t\t\tif (since === undefined) {\n\t\t\t\tif (share < backAt) {\n\t\t\t\t\tmemory.resting[hero.id] = ai.tick\n\t\t\t\t\tai.decide(`${hero.type} ${hero.id} goes home to rest at ${Math.round(share * 100)}%`, { kind: 'lanes' })\n\t\t\t\t}\n\t\t\t} else if (share >= returnAt || ai.tick - since >= restFor) {\n\t\t\t\tdelete memory.resting[hero.id]\n\t\t\t\tai.decide(`${hero.type} ${hero.id} rested, back out at ${Math.round(share * 100)}%`, { kind: 'lanes' })\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Sends a resting hero home: by an ability that takes it there (one whose effects, at its end, teleport home), where\n\t * it has one ready and nothing hostile is near; else on foot. Nothing while it channels, or once home\n\t */\n\tsendHome(hero: EntityState): void {\n\t\tconst { ai } = this\n\t\tconst home = this.home()\n\t\tif (!home || !hero.own || hero.own.hidden) return\n\t\tif (distSq(hero, home) <= HOME * HOME || hero.own.order === 'cast') return\n\t\tconst recalled = this.memory.recalled[hero.id]\n\t\tconst safe = !ai.view.hostile.alive().near(hero, 12).length\n\t\tif (this.options.recall !== false && safe && (recalled === undefined || ai.tick - recalled >= RECALL_AGAIN * ai.session.tickRate)) {\n\t\t\tconst ability = hero.own.abilities?.find((state) => {\n\t\t\t\tif (state.level < 1 || state.cooldown > 0 || state.charges === 0) return false\n\t\t\t\tconst def = ai.registry.ability(state.id)\n\t\t\t\treturn [...def.effects, ...(def.channel?.finished ?? [])].some((effect) => effect.type === 'teleport' && effect.to === 'home')\n\t\t\t})\n\t\t\tif (ability) {\n\t\t\t\tthis.memory.recalled[hero.id] = ai.tick\n\t\t\t\tai.send({ type: 'cast', entities: [hero.id], ability: ability.id })\n\t\t\t\tai.decide(`${hero.type} ${hero.id} recalls home`, { kind: 'lanes' })\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\tif (hero.own.order === 'move') return\n\t\tconst sent = this.memory.sent[hero.id]\n\t\tif (sent !== undefined && ai.tick - sent < RESEND * ai.session.tickRate) return\n\t\tthis.memory.sent[hero.id] = ai.tick\n\t\tai.send({ type: 'order', entities: [hero.id], order: { type: 'move', point: home } })\n\t}\n\n\t/** An ally's hero in a fight one of its heroes could go to: the most hurt, near enough; or a person's call for help */\n\tcall(from: Vec2): Vec2 | undefined {\n\t\tconst help = this.options.help\n\t\tif (help === false) return undefined\n\t\tconst { ai } = this\n\t\tconst { view } = ai\n\t\tconst reach = help?.reach ?? 30\n\t\tconst theirHeroes = view.enemies\n\t\t\t.units()\n\t\t\t.alive()\n\t\t\t.where((unit, def) => !!def.hero || !!heroOfState(unit))\n\t\tlet best: EntityState | undefined\n\t\tfor (const ally of view.allies.units().alive().heroes()) {\n\t\t\tif (distSq(ally, from) > reach * reach || !theirHeroes.near(ally, FIGHTING).length) continue\n\t\t\tif (!best || health(ai, ally) < health(ai, best)) best = ally\n\t\t}\n\t\tif (best) return point(best)\n\t\tconst ping = ai.area(Team).enabled\n\t\t\t? ai\n\t\t\t\t\t.area(Team)\n\t\t\t\t\t.requests('help')\n\t\t\t\t\t.find((request) => request.by === 'ping' && distSq(request.at, from) <= reach * reach)\n\t\t\t: undefined\n\t\treturn ping && point(ping.at)\n\t}\n\n\t/** The ally's hero nearest a place: what a hero helping goes with */\n\tallyAt(at: Vec2): EntityState | undefined {\n\t\treturn this.ai.view.allies.units().alive().heroes().near(at, 2).first()\n\t}\n\n\t/** The nearest camp it may take from a place: not cleared, in reach, its creeps (as seen) beatable */\n\tcamp(hero: EntityState): Vec2 | undefined {\n\t\tconst camps = this.options.camps\n\t\tif (camps === false) return undefined\n\t\tconst { ai } = this\n\t\tconst { view } = ai\n\t\tconst reach = camps?.reach ?? 50\n\t\tconst odds = camps?.odds ?? 0.6\n\t\tlet best: { at: Vec2; d: number } | undefined\n\t\tfor (const camp of view.camps()) {\n\t\t\tif (camp.cleared) continue\n\t\t\tconst d = distSq(camp, hero)\n\t\t\tif (d > reach * reach || (best && d >= best.d)) continue\n\t\t\t// as seen; a camp out of sight by its levels against the hero's\n\t\t\tconst creeps = view.creeps.alive().near(camp, 8)\n\t\t\tconst beatable = creeps.length ? view.strength.odds([hero], creeps) >= odds : camp.level <= 2 + 2 * (heroOfState(hero)?.level ?? 1)\n\t\t\tif (beatable) best = { at: { x: camp.x, z: camp.z }, d }\n\t\t}\n\t\treturn best?.at\n\t}\n}\n\n/** The kit's lane task: a hero walks a lane behind its side's wave (`LanesPlay.spot`), falling back once outmatched */\nconst PUSH = defineTask({ id: 'lanes.push', start(ai, squad, state) {\n\t\tstate.phase = 'going'\n\t\tstate.phaseSince = ai.tick\n\t\tpushOn(ai, squad, state, true)\n\t},\n\tthink(ai, squad, state) {\n\t\tpushOn(ai, squad, state, false)\n\t},\n\twhere: (ai, _squad, state) => playOf(ai)?.spot(state.data.lane as string),\n\thandles: ['retreat', 'regroup', 'reinforce'],\n\tstanding: true })\n\n/** The lanes module's play, where the brain has one */\nconst playOf = (ai: Brain): LanesPlay | undefined => ai.module(LANES)?.play\n\n/** A hero on its lane: to its spot, fighting on the way; back along it when outmatched */\nfunction pushOn(ai: Brain, squad: Squad, state: TaskState, first: boolean): void {\n\tconst play = playOf(ai)\n\tconst path = state.data.lane as string\n\tconst lane = play?.state(path)\n\tconst middle = squad.centre()\n\tif (!play || !lane || !middle) {\n\t\tsquad.finish('lost')\n\t\treturn\n\t}\n\tconst fighting = ai.view.hostile.alive().near(middle, LANE_ENGAGED).length > 0\n\t// outmatched where it stands: back along the lane (a retreat, which micro leaves alone), then on again\n\tif (fighting && play.oddsAt(middle) < (play.options.backOdds ?? 0.3)) {\n\t\tconst to = play.fallBack(path, middle)\n\t\tif (to) {\n\t\t\tai.decide(`squad ${squad.name} falls back along ${path} to ${where(to)}: outmatched (odds ${play.oddsAt(middle).toFixed(2)})`, {\n\t\t\t\tkind: 'lanes'\n\t\t\t})\n\t\t\tsquad.retreat(to, 'outmatched on its lane')\n\t\t\treturn\n\t\t}\n\t}\n\tconst spot = play.spot(path)!\n\tconst phase = lane.front !== undefined ? 'pushing' : 'waiting'\n\tif (state.phase !== phase) {\n\t\tstate.phase = phase\n\t\tstate.phaseSince = ai.tick\n\t}\n\t// in a fight, micro has it: sent on only once the fight is over, or standing idle\n\tconst idle = squad.idleUnits()\n\tif (fighting && !idle.length) return\n\tconst sentTo = state.memory.at as Vec2 | undefined\n\tconst moved = !sentTo || distSq(sentTo, spot) > MOVED * MOVED\n\tconst away = squad.units().some((unit) => distSq(unit, spot) > THERE * THERE)\n\tif (!first && !(away && (moved || (idle.length && squad.mayResend())))) return\n\tstate.memory.at = point(spot)\n\tsquad.fight(spot)\n}\n\n/**\n * The lanes module, with the play it runs (`LanesPlay`): what the tests reach\n *\n * @beta\n */\nexport interface LanesModule extends AiModule {\n\t/** The lanes play the module runs */\n\tplay: LanesPlay\n}\n\n/**\n * What finds a lanes brain's module with its shape (`ai.module(LANES)`)\n *\n * @beta\n */\nexport const LANES = moduleKey<LanesModule>('lanes')\n\n/** The goals of a lanes brain over its play (the file's comment) */\nfunction laneGoals(ai: Brain, play: LanesPlay): GoalDef[] {\n\t/** Its heroes free to go: alive, not resting */\n\tconst free = (available: UnitSet) => play.commanded(available).where((hero) => play.memory.resting[hero.id] === undefined)\n\tconst nearestTo = (set: UnitSet, at: Vec2 | undefined) => (at ? set.nearest(at) : set.first())\n\tconst lanes = (ai.session.can.computer?.lanes() ?? [])\n\t\t.map((lane) => lane.path)\n\t\t.filter((path) => !play.options.lanes || play.options.lanes.includes(path))\n\tconst push = lanes.map((path) => {\n\t\tconst id = `lanes.push:${path}`\n\t\treturn defineGoal({\n\t\t\tid,\n\t\t\tweight: 1,\n\t\t\tcommitment: 30,\n\t\t\tconsiderations: [\n\t\t\t\tconsider('a lane of its side', () => (play.lane(path) ? 1 : 0), curve.step(1)),\n\t\t\t\tconsider('a hero free', () => free(ai.view.mine).length, curve.step(1)),\n\t\t\t\t// the lane with the most of its side's strength first; one with none still worth a hero waiting by its tower\n\t\t\t\tconsider(\n\t\t\t\t\t'its wave on it',\n\t\t\t\t\t() => ai.view.strength.sum(play.state(path)?.ours ?? []),\n\t\t\t\t\tcurve.custom((x) => 0.3 + 0.7 * (1 - exp(-x / 60)))\n\t\t\t\t),\n\t\t\t\t// where its side is winning (its wave far along: a tower to take, their core) or losing (theirs at its towers)\n\t\t\t\tconsider(\n\t\t\t\t\t'what is at stake',\n\t\t\t\t\t() => play.stake(path),\n\t\t\t\t\tcurve.custom((x) => 0.4 + 0.6 * x)\n\t\t\t\t),\n\t\t\t\tconsider(\n\t\t\t\t\t'the odds at its front',\n\t\t\t\t\t() => {\n\t\t\t\t\t\tconst spot = play.spot(path)\n\t\t\t\t\t\treturn spot ? play.oddsAt(spot, 14) : 0\n\t\t\t\t\t},\n\t\t\t\t\tcurve.custom((odds) => 0.2 + odds)\n\t\t\t\t),\n\t\t\t\t// two heroes of a side on a lane leave another to their heroes; a third, more so\n\t\t\t\tconsider('allies already on it', () => play.state(path)?.allies.length ?? 0, curve.inverse(2)),\n\t\t\t\tconsider(\n\t\t\t\t\t'how far its hero is',\n\t\t\t\t\t() => {\n\t\t\t\t\t\tconst spot = play.spot(path)\n\t\t\t\t\t\tconst hero = nearestTo(free(ai.view.mine), spot)\n\t\t\t\t\t\treturn hero && spot ? Math.sqrt(distSq(hero, spot)) : 0\n\t\t\t\t\t},\n\t\t\t\t\tcurve.inverse(60)\n\t\t\t\t)\n\t\t\t],\n\t\t\tclaims: {\n\t\t\t\t// one hero a lane: the nearest of those free to it, so that two heroes of a player take two lanes\n\t\t\t\tunits: (_ai, available) => {\n\t\t\t\t\tconst hero = nearestTo(free(available), play.spot(path))\n\t\t\t\t\treturn hero ? [hero] : []\n\t\t\t\t}\n\t\t\t},\n\t\t\trun: (_ai, claimed) => {\n\t\t\t\tconst squad = claimed.squad(id, claimed.units, { retreatAt: false })\n\t\t\t\t// given as made, and again once a fall back along it is over\n\t\t\t\tif (squad.idle) squad.task(PUSH, { lane: path })\n\t\t\t}\n\t\t})\n\t})\n\tconst back = defineGoal({\n\t\tid: 'lanes.back',\n\t\tweight: 10,\n\t\turgent: true,\n\t\tcommitment: 0,\n\t\tconsiderations: [consider('a hero to rest', () => play.resting().length, curve.step(1))],\n\t\tclaims: { units: () => play.resting() },\n\t\trun: (ai, claimed) => {\n\t\t\t// one that turned for home while another goal had it: taken from that goal; one rested: let go of\n\t\t\tconst hold = ai.goals.held('lanes.back')\n\t\t\tconst resting = play.resting()\n\t\t\tconst fresh = resting.filter((hero) => !hold?.units.includes(hero.id)).map((hero) => hero.id)\n\t\t\tif (fresh.length) {\n\t\t\t\tai.goals.take(fresh, 'urgent')\n\t\t\t\tai.goals.give('lanes.back', fresh)\n\t\t\t}\n\t\t\tconst rested = claimed.units.where((hero) => play.memory.resting[hero.id] === undefined).ids()\n\t\t\tif (rested.size) ai.goals.drop('lanes.back', rested)\n\t\t\t// on its own: no squad, so micro's shopping finds it with nothing to do at home\n\t\t\tfor (const hero of resting) play.sendHome(hero)\n\t\t}\n\t})\n\tconst help = defineGoal({\n\t\tid: 'lanes.help',\n\t\tweight: 1.3,\n\t\tcommitment: 6,\n\t\tconsiderations: [\n\t\t\tconsider(\n\t\t\t\t'an ally in a fight near',\n\t\t\t\t() => {\n\t\t\t\t\tconst hero = free(ai.view.mine).first()\n\t\t\t\t\treturn hero && play.call(hero) ? 1 : 0\n\t\t\t\t},\n\t\t\t\tcurve.step(1)\n\t\t\t),\n\t\t\tconsider(\n\t\t\t\t'the odds there with it',\n\t\t\t\t() => {\n\t\t\t\t\tconst hero = free(ai.view.mine).first()\n\t\t\t\t\tconst at = hero && play.call(hero)\n\t\t\t\t\tif (!hero || !at) return 0\n\t\t\t\t\tconst near = ai.view.all.units().alive().near(at, 12)\n\t\t\t\t\tconst theirs = near.where((unit) => ai.view.isHostile(unit))\n\t\t\t\t\treturn theirs.length ? ai.view.strength.odds([...near.where((unit) => ai.view.isFriendly(unit)).items, hero], theirs) : 1\n\t\t\t\t},\n\t\t\t\tcurve.custom((odds) => (odds >= ((play.options.help || {}).odds ?? 0.4) ? odds : 0))\n\t\t\t)\n\t\t],\n\t\tclaims: {\n\t\t\tunits: (_ai, available) => {\n\t\t\t\tconst heroes = free(available)\n\t\t\t\tconst hero = heroes.first()\n\t\t\t\tconst at = hero && play.call(hero)\n\t\t\t\tconst chosen = at && heroes.nearest(at)\n\t\t\t\treturn chosen ? [chosen] : []\n\t\t\t}\n\t\t},\n\t\trun: (ai, claimed) => {\n\t\t\tconst hero = claimed.units.first()\n\t\t\tconst at = hero && play.call(hero)\n\t\t\tif (!hero || !at) return\n\t\t\tconst ally = play.allyAt(at)\n\t\t\tconst squad = claimed.squad('lanes.help', claimed.units, { retreatAt: false })\n\t\t\tif (claimed.first) ai.decide(`${hero.type} ${hero.id} goes to help at ${where(at)}`, { kind: 'lanes' })\n\t\t\tif (squad.idle || (ally && squad.current?.kind !== 'escort')) {\n\t\t\t\tif (ally) squad.escort(ally.id)\n\t\t\t\telse squad.attack(at)\n\t\t\t}\n\t\t}\n\t})\n\tconst camp = defineGoal({\n\t\tid: 'lanes.camp',\n\t\tweight: 0.6,\n\t\tcommitment: 15,\n\t\tconsiderations: [\n\t\t\tconsider('no wave to walk with', () => play.states().filter((state) => state.ours.length > 0).length, curve.inverse(0.01)),\n\t\t\tconsider(\n\t\t\t\t'a camp it can take',\n\t\t\t\t() => {\n\t\t\t\t\tconst hero = free(ai.view.mine).first()\n\t\t\t\t\treturn hero && play.camp(hero) ? 1 : 0\n\t\t\t\t},\n\t\t\t\tcurve.step(1)\n\t\t\t)\n\t\t],\n\t\tclaims: {\n\t\t\tunits: (_ai, available) => {\n\t\t\t\tconst hero = free(available).first()\n\t\t\t\treturn hero && play.camp(hero) ? [hero] : []\n\t\t\t}\n\t\t},\n\t\trun: (_ai, claimed) => {\n\t\t\tconst hero = claimed.units.first()\n\t\t\tconst at = hero && play.camp(hero)\n\t\t\tconst squad = claimed.squad('lanes.camp', claimed.units, { retreatAt: false })\n\t\t\tif (squad.idle && at) squad.creep(at)\n\t\t}\n\t})\n\treturn [...push, back, ...(play.options.help === false ? [] : [help]), ...(play.options.camps === false ? [] : [camp])]\n}\n\n/**\n * The module of a lanes brain: the lanes read for its side, its heroes' rest, and its goals put on the picker (the\n * file's comment). Its options under the brain's settings (`AiSettings.lanes`)\n *\n * @beta\n */\nexport const lanesPlay = (options: LanesPlayOptions = {}): AiModuleDef =>\n\tdefineModule({ id: 'lanes', make: (ai: Brain): LanesModule => {\n\t\tconst play = new LanesPlay(ai, { ...options, ...ai.settings.lanes })\n\t\tai.squads.define(PUSH)\n\t\tai.goals.add(...laneGoals(ai, play))\n\t\treturn {\n\t\t\tid: 'lanes',\n\t\t\tversion: 1,\n\t\t\tphase: 'decide',\n\t\t\tplay,\n\t\t\tthink: () => play.think(),\n\t\t\tsave: () => structuredClone(play.memory),\n\t\t\t// written into the same object: the goals' closures read it\n\t\t\trestore: (data) => {\n\t\t\t\tconst kept = data && typeof data === 'object' ? (data as Partial<LanesPlayMemory>) : {}\n\t\t\t\tplay.memory.resting = { ...kept.resting }\n\t\t\t\tplay.memory.recalled = { ...kept.recalled }\n\t\t\t\tplay.memory.sent = { ...kept.sent }\n\t\t\t},\n\t\t\tinspect: () => ({\n\t\t\t\tlanes: play.states().map((state) => ({\n\t\t\t\t\tlane: state.lane.path,\n\t\t\t\t\tfront: state.front === undefined ? undefined : Math.round(state.front),\n\t\t\t\t\ttheirFront: state.theirFront === undefined ? undefined : Math.round(state.theirFront),\n\t\t\t\t\tours: state.ours.length,\n\t\t\t\t\ttheirs: state.theirs.length\n\t\t\t\t})),\n\t\t\t\tresting: Object.keys(play.memory.resting).map(Number)\n\t\t\t})\n\t\t}\n\t} })\n\n/**\n * The engine's computer player for a game of lanes (`lanesPack`): a brain of its rules, the words, `lanesPlay`, the\n * team, the picker, squads and micro (the file's comment). Heroes walk the lanes with their waves, rest at home when\n * hurt, help an ally's hero, take a camp with no wave to walk with. A variant is `lanesBrain.with({ ... })`; a game's\n * own lanes brain is `lanesBrainOf({ id, lanes, ... })`\n *\n * @beta\n */\nexport function lanesBrainOf(def: BrainExtension & { id: string; lanes?: LanesPlayOptions }): BrainDef {\n\tconst { lanes, modules = [], settings, ...rest } = def\n\treturn defineBrain({\n\t\t...rest,\n\t\tsettings: {\n\t\t\t...settings,\n\t\t\t// heroes are its to bring home (`lanes.back`), not micro's to send off alone; whom they hit, the lanes' way\n\t\t\tmicro: { heroesFlee: false, unitsFlee: false, focusEvery: 2, targets: lanesTargets(lanes), ...settings?.micro },\n\t\t\t// the minions are the lanes', so a call for help is the lanes' goal's to answer (`lanes.help`), and it asks for none\n\t\t\tteam: { defendUsers: false, askForHelp: false, ...settings?.team }\n\t\t},\n\t\tmodules: [\n\t\t\t// its own rules first, as every brain's: what a rule takes is not given orders by the rest\n\t\t\tdefineModule({ id: 'rules', make: (ai: Brain) => (rules(ai.def.rules ?? []) as (ai: Brain) => AiModule)(ai) }),\n\t\t\twords(),\n\t\t\tteam(),\n\t\t\tlanesPlay(lanes),\n\t\t\t...modules,\n\t\t\tgoals(),\n\t\t\tsquads(),\n\t\t\tmicro()\n\t\t]\n\t})\n}\n\n/**\n * The engine's computer player for a game of lanes, as it is: `lanesBrainOf({ id: 'core.lanes' })`. List it in the\n * game's `Rules.brains` and seat it (`world.computers.seat(player, { brain: lanesBrain })`)\n *\n * @beta\n */\nexport const lanesBrain: BrainDef = lanesBrainOf({ id: 'core.lanes' })\n"],"mappings":"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"}
|
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import { upgradesOf } from "../../defs.js";
|
|
2
|
+
import { availableToPlayer } from "../../shared.js";
|
|
3
|
+
import { queueOf, upgradeOf } from "../../systems/productionQueue.js";
|
|
4
|
+
import { defineModule } from "../module.js";
|
|
5
|
+
import "../reach.js";
|
|
6
|
+
import { evaluate } from "../rules.js";
|
|
7
|
+
import { flagOf } from "../profiles.js";
|
|
8
|
+
import { Economy } from "../economy.js";
|
|
9
|
+
//#region src/ai/melee/build.ts
|
|
10
|
+
/**
|
|
11
|
+
* The melee player's ladder as it stands: a hall, a barracks, another hall once the mine at home runs low, an altar,
|
|
12
|
+
* the building its best answer needs, the next tier of its hall once a barracks stands (FJ1: before the workshop, so
|
|
13
|
+
* that what the tier opens is trained while it matters), a workshop, a second barracks with money to spare
|
|
14
|
+
*
|
|
15
|
+
* @beta
|
|
16
|
+
*/
|
|
17
|
+
var MELEE_LADDER = [
|
|
18
|
+
{
|
|
19
|
+
id: "melee.hall",
|
|
20
|
+
role: "hall",
|
|
21
|
+
count: 1,
|
|
22
|
+
priority: 100
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
id: "melee.barracks",
|
|
26
|
+
role: "barracks",
|
|
27
|
+
count: 1,
|
|
28
|
+
priority: 80
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
id: "melee.expand",
|
|
32
|
+
role: "expand",
|
|
33
|
+
priority: 70
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
id: "melee.altar",
|
|
37
|
+
role: "altar",
|
|
38
|
+
count: 1,
|
|
39
|
+
priority: 60
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
id: "melee.counter",
|
|
43
|
+
role: "counter",
|
|
44
|
+
priority: 50,
|
|
45
|
+
spare: 100
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
id: "melee.tier",
|
|
49
|
+
role: "tier",
|
|
50
|
+
priority: 45,
|
|
51
|
+
spare: 100,
|
|
52
|
+
when: { units: { role: "barracks" } }
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
id: "melee.workshop",
|
|
56
|
+
role: "workshop",
|
|
57
|
+
count: 1,
|
|
58
|
+
priority: 30,
|
|
59
|
+
spare: 150
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
id: "melee.barracks2",
|
|
63
|
+
role: "barracks",
|
|
64
|
+
count: 2,
|
|
65
|
+
priority: 10,
|
|
66
|
+
spare: 400
|
|
67
|
+
}
|
|
68
|
+
];
|
|
69
|
+
/** What fights: a worker that builds does not, one that only gathers (a ghoul) does */
|
|
70
|
+
var isSoldier = (def) => def.kind === "unit" && !!def.attacks?.length && !(def.harvester && def.builds?.length) && !def.hero;
|
|
71
|
+
/**
|
|
72
|
+
* The melee brain's build module: the ladder of wants set on the build plan each think, the counter and the tier
|
|
73
|
+
* worked out, the plan thought. After the heroes, before the production and the picker, as the old turn had it;
|
|
74
|
+
* `steps.construction` honoured
|
|
75
|
+
*
|
|
76
|
+
* @beta
|
|
77
|
+
*/
|
|
78
|
+
var build = (options = {}) => defineModule({
|
|
79
|
+
id: "melee.build",
|
|
80
|
+
make: (ai) => {
|
|
81
|
+
const ladder = options.ladder ?? MELEE_LADDER;
|
|
82
|
+
const margin = options.counterMargin ?? 1.2;
|
|
83
|
+
const expandAt = options.expandAt ?? .35;
|
|
84
|
+
const module = {
|
|
85
|
+
id: "melee.build",
|
|
86
|
+
phase: "plan",
|
|
87
|
+
after: ["economy", "melee.heroes"],
|
|
88
|
+
before: ["melee.production"],
|
|
89
|
+
/** Where its home first stood: where its hall is built again when lost, where it may not move home */
|
|
90
|
+
homeAt: void 0,
|
|
91
|
+
think: () => {
|
|
92
|
+
if (ai.area(Economy).waiting) return;
|
|
93
|
+
wants(ai, ladder, margin, expandAt, module);
|
|
94
|
+
ai.plans.build.think();
|
|
95
|
+
},
|
|
96
|
+
save: () => ({
|
|
97
|
+
v: 1,
|
|
98
|
+
...module.homeAt && { homeAt: {
|
|
99
|
+
x: module.homeAt.x,
|
|
100
|
+
z: module.homeAt.z
|
|
101
|
+
} }
|
|
102
|
+
}),
|
|
103
|
+
restore: (data) => {
|
|
104
|
+
const given = data;
|
|
105
|
+
if (given?.homeAt) module.homeAt = {
|
|
106
|
+
x: given.homeAt.x,
|
|
107
|
+
z: given.homeAt.z
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
return module;
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
/** The ladder as wants on the plan, with what it has now in mind */
|
|
115
|
+
function wants(ai, ladder, margin, expandAt, module) {
|
|
116
|
+
const { view } = ai;
|
|
117
|
+
const plan = ai.plans.build;
|
|
118
|
+
const by = "melee";
|
|
119
|
+
const home = view.home();
|
|
120
|
+
if (home && !module.homeAt) module.homeAt = {
|
|
121
|
+
x: home.x,
|
|
122
|
+
z: home.z
|
|
123
|
+
};
|
|
124
|
+
const stays = flagOf(ai, "allowHomeChanges") === false ? module.homeAt : void 0;
|
|
125
|
+
for (const rung of ladder) {
|
|
126
|
+
const base = {
|
|
127
|
+
id: rung.id,
|
|
128
|
+
priority: rung.priority,
|
|
129
|
+
keep: true,
|
|
130
|
+
by,
|
|
131
|
+
...rung.spare !== void 0 && { spare: rung.spare }
|
|
132
|
+
};
|
|
133
|
+
switch (rung.role) {
|
|
134
|
+
case "counter": {
|
|
135
|
+
const wanted = counterNeeds(ai, margin);
|
|
136
|
+
if (wanted) plan.want({
|
|
137
|
+
...base,
|
|
138
|
+
type: wanted.id,
|
|
139
|
+
count: rung.count ?? 1,
|
|
140
|
+
by: "counters",
|
|
141
|
+
...rung.when && { when: rung.when }
|
|
142
|
+
});
|
|
143
|
+
else plan.drop(rung.id);
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
case "expand": {
|
|
147
|
+
const hall = view.typesOf("hall")[0];
|
|
148
|
+
if (!hall || !mineLow(ai, expandAt)) {
|
|
149
|
+
plan.drop(rung.id);
|
|
150
|
+
break;
|
|
151
|
+
}
|
|
152
|
+
plan.want({
|
|
153
|
+
...base,
|
|
154
|
+
type: hall.id,
|
|
155
|
+
count: (brain) => brain.view.mine.buildings().withRole("hall").length + (rung.count ?? 1),
|
|
156
|
+
by: "expand",
|
|
157
|
+
within: 15,
|
|
158
|
+
near: () => ai.area(Economy).freeMine(),
|
|
159
|
+
when: (brain) => !!brain.area(Economy).freeMine() && (!rung.when || evaluate(rung.when, brain))
|
|
160
|
+
});
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
case "tier": {
|
|
164
|
+
const hall = view.typesOf("hall")[0];
|
|
165
|
+
const tier = hall && view.mine.ofType(hall.id).finished().find((each) => upgradesOf(view.def(each)).length && !queueOf(each).length && !upgradeOf(each)?.to);
|
|
166
|
+
const next = tier && upgradesOf(view.def(tier))[0];
|
|
167
|
+
if (next) plan.want({
|
|
168
|
+
...base,
|
|
169
|
+
type: next,
|
|
170
|
+
count: view.mine.ofType(next).length + (rung.count ?? 1),
|
|
171
|
+
by: "tier",
|
|
172
|
+
...rung.when && { when: rung.when }
|
|
173
|
+
});
|
|
174
|
+
else plan.drop(rung.id);
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
default: {
|
|
178
|
+
const type = view.typesOf(rung.role)[0];
|
|
179
|
+
if (!type) {
|
|
180
|
+
plan.drop(rung.id);
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
plan.want({
|
|
184
|
+
...base,
|
|
185
|
+
type: type.id,
|
|
186
|
+
count: rung.count ?? 1,
|
|
187
|
+
...rung.when && { when: rung.when },
|
|
188
|
+
...rung.role === "hall" && stays && { near: stays }
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Whether the mine at home is running low: of the money's deposits by its home base in sight, what is left together
|
|
196
|
+
* under `ratio` of what they held (the type's `resource.amount`). No while none is in sight
|
|
197
|
+
*/
|
|
198
|
+
function mineLow(ai, ratio) {
|
|
199
|
+
if (ratio <= 0) return false;
|
|
200
|
+
const { view } = ai;
|
|
201
|
+
const home = view.bases()[0];
|
|
202
|
+
if (!home) return false;
|
|
203
|
+
const money = view.registry.currency ?? view.registry.resources[0]?.id;
|
|
204
|
+
if (!money) return false;
|
|
205
|
+
let held = 0;
|
|
206
|
+
let left = 0;
|
|
207
|
+
for (const deposit of view.resourcesNear(home)) {
|
|
208
|
+
if (!deposit.visible || deposit.resource === void 0) continue;
|
|
209
|
+
const def = view.def(deposit);
|
|
210
|
+
if (def.resource?.id !== money) continue;
|
|
211
|
+
held += def.resource.amount;
|
|
212
|
+
left += deposit.resource;
|
|
213
|
+
}
|
|
214
|
+
return held > 0 && left < held * ratio;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* A building it would put up for a better answer to its rivals' armies: what the best of the soldiers its barracks
|
|
218
|
+
* train needs, where it answers them better than any it can train now, and its workers can build it. None otherwise
|
|
219
|
+
*/
|
|
220
|
+
function counterNeeds(ai, margin) {
|
|
221
|
+
const { registry, view } = ai;
|
|
222
|
+
const { me } = view;
|
|
223
|
+
const builds = new Set(view.typesOf("worker")[0]?.builds ?? []);
|
|
224
|
+
let best;
|
|
225
|
+
let ready = 0;
|
|
226
|
+
for (const barracks of view.typesOf("barracks")) {
|
|
227
|
+
if (!view.mine.ofType(barracks.id).length) continue;
|
|
228
|
+
for (const id of barracks.trains ?? []) {
|
|
229
|
+
const def = registry.unit(id);
|
|
230
|
+
if (!isSoldier(def) || !availableToPlayer(def, {
|
|
231
|
+
race: me.race,
|
|
232
|
+
availability: me.availability
|
|
233
|
+
}, id)) continue;
|
|
234
|
+
const score = counters(ai, def);
|
|
235
|
+
if (view.has(def.requires)) ready = Math.max(ready, score);
|
|
236
|
+
else if (score > (best?.score ?? 0)) best = {
|
|
237
|
+
def,
|
|
238
|
+
score
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
if (!best || best.score <= ready * margin) return void 0;
|
|
243
|
+
for (const need of best.def.requires ?? []) {
|
|
244
|
+
if (view.has([need])) continue;
|
|
245
|
+
const maker = registry.units.all().find((def) => builds.has(def.id) && (def.id === need || def.provides?.includes(need)));
|
|
246
|
+
if (maker) return maker;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* How well a type it can train answers what it has seen of its rivals (`Strength.counterFor`: its strength against
|
|
251
|
+
* them over its plain strength; one that hits the air against flyers, one whose damage gets through their armour).
|
|
252
|
+
* 0 where it has seen nothing to answer
|
|
253
|
+
*/
|
|
254
|
+
function counters(ai, def) {
|
|
255
|
+
const { registry } = ai;
|
|
256
|
+
const seen = {};
|
|
257
|
+
for (const [type, { most }] of Object.entries(ai.knowledge.enemy.typesSeen())) if (registry.units.has(type) && registry.unit(type).kind === "unit") seen[type] = most;
|
|
258
|
+
if (!Object.keys(seen).length) return 0;
|
|
259
|
+
return ai.view.strength.counterFor(seen, [def])[0].score;
|
|
260
|
+
}
|
|
261
|
+
//#endregion
|
|
262
|
+
export { MELEE_LADDER, build };
|
|
263
|
+
|
|
264
|
+
//# sourceMappingURL=build.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.js","names":[],"sources":["../../../src/ai/melee/build.ts"],"sourcesContent":["import { type UnitTypeDef, upgradesOf } from '#engine/defs'\nimport { Economy } from '../economy'\nimport { queueOf, upgradeOf } from '#engine/systems/productionQueue'\nimport type { Vec2 } from '#engine/math'\nimport { availableToPlayer } from '#engine/shared'\nimport { type Brain } from '#engine/ai/brain'\nimport { type AiModuleDef, defineModule } from '#engine/ai/module'\nimport type { Want } from '#engine/ai/plans/build'\nimport { flagOf } from '#engine/ai/profiles'\nimport type { AiRole } from '#engine/ai/roles'\nimport { type AiConditionData, evaluate } from '#engine/ai/rules'\nimport { HALL_REACH } from '../reach'\n\n/*\n * What the melee player builds (AI plan, D3; the part of its turn that was `runConstruction`): a ladder of wants on\n * the brain's build plan (B3), most important first, as data (`MELEE_LADDER`) rather than code. Each rung names a\n * role (what the kit found the game's types are for, `roles.ts`) and how many of it, how important it is to the purse\n * (`priority`: a hall before a barracks before a workshop), what to keep spare for it, and when it holds. Two rungs\n * are worked out rather than looked up: `counter`, the building the best answer to their army needs (a blacksmith for\n * riflemen against flyers), and `tier`, the next tier of the hall. Supply is the production plan's (kept ahead of what\n * it trains), another hall by a free mine the economy's (`economy.expand`, 40), towers at a base raided often the\n * defence's. The plan works out the steps to each want (a blacksmith needs a barracks), the spots, the builders and\n * the purse, and builds anew what is lost. The wants stand (`keep`): they are set again each think with what it has\n * now in mind, and a game gives a ladder of its own (`build({ ladder })`) or leaves a rung out\n */\n\n/**\n * One rung of the melee player's ladder of wants: what to have, by role, how many, how important, money to spare,\n * when. `counter` and `tier` are worked out each think (the file's comment); any other role is the first type of it\n * the player can make\n *\n * @beta\n */\nexport interface MeleeWant {\n\t/** The want's id on the build plan (`melee.barracks`): what the report shows, what `without` leaves out */\n\tid: string\n\t/**\n\t * A role of the kit's (`hall`, `barracks`, `altar`, `workshop`, `tower`), or one worked out: `counter` (the\n\t * building its best answer to their army needs), `tier` (the next tier of its hall), `expand` (another hall by a\n\t * free mine once the mine at home runs low, FJ1)\n\t */\n\trole: AiRole | 'counter' | 'tier' | 'expand'\n\t/** How many of it to have: 1 when left out */\n\tcount?: number\n\t/** How important it is to the purse: a want of more goes first and may spend what is held for one of less */\n\tpriority: number\n\t/** Money to keep spare before it is paid for (a luxury waits until there is this much over its price) */\n\tspare?: number\n\t/** Only while this holds (`AiConditionData`): `{ units: { role: 'barracks' } }` for the next tier */\n\twhen?: AiConditionData\n}\n\n/**\n * The melee player's ladder as it stands: a hall, a barracks, another hall once the mine at home runs low, an altar,\n * the building its best answer needs, the next tier of its hall once a barracks stands (FJ1: before the workshop, so\n * that what the tier opens is trained while it matters), a workshop, a second barracks with money to spare\n *\n * @beta\n */\nexport const MELEE_LADDER: readonly MeleeWant[] = [\n\t{ id: 'melee.hall', role: 'hall', count: 1, priority: 100 },\n\t{ id: 'melee.barracks', role: 'barracks', count: 1, priority: 80 },\n\t// another hall by a free mine when the mine at home is running out (`expandAt`): past the economy's own expansion\n\t{ id: 'melee.expand', role: 'expand', priority: 70 },\n\t{ id: 'melee.altar', role: 'altar', count: 1, priority: 60 },\n\t{ id: 'melee.counter', role: 'counter', priority: 50, spare: 100 },\n\t{ id: 'melee.tier', role: 'tier', priority: 45, spare: 100, when: { units: { role: 'barracks' } } },\n\t// another hall by a free mine is the economy's want (`economy.expand`, priority 40)\n\t{ id: 'melee.workshop', role: 'workshop', count: 1, priority: 30, spare: 150 },\n\t{ id: 'melee.barracks2', role: 'barracks', count: 2, priority: 10, spare: 400 }\n]\n\n/**\n * How the melee brain builds (`build()` of the melee brain): its ladder of wants, and how much better an answer to\n * their army must be for its building to be put up\n *\n * @beta\n */\nexport interface MeleeBuildOptions {\n\t/** The ladder of wants, most important first: `MELEE_LADDER` when left out */\n\tladder?: readonly MeleeWant[]\n\t/** How much better a type must answer their armies than what it can train now, for the building it needs to be put up: 1.2 when left out */\n\tcounterMargin?: number\n\t/**\n\t * The part of what it held left in the mine at home under which another hall by a free mine is wanted (the `expand`\n\t * rung): 0.35 when left out. 0 for never\n\t */\n\texpandAt?: number\n}\n\n/** What the module remembers: where home first stood (Allow Home Changes off) */\ninterface MeleeBuildMemory {\n\tv: 1\n\thomeAt?: Vec2\n}\n\n/** What fights: a worker that builds does not, one that only gathers (a ghoul) does */\nconst isSoldier = (def: UnitTypeDef) => def.kind === 'unit' && !!def.attacks?.length && !(def.harvester && def.builds?.length) && !def.hero\n\n/**\n * The melee brain's build module: the ladder of wants set on the build plan each think, the counter and the tier\n * worked out, the plan thought. After the heroes, before the production and the picker, as the old turn had it;\n * `steps.construction` honoured\n *\n * @beta\n */\nexport const build = (options: MeleeBuildOptions = {}): AiModuleDef =>\n\tdefineModule({ id: 'melee.build', make: (ai: Brain) => {\n\t\tconst ladder = options.ladder ?? MELEE_LADDER\n\t\tconst margin = options.counterMargin ?? 1.2\n\t\tconst expandAt = options.expandAt ?? 0.35\n\t\tconst module = {\n\t\t\tid: 'melee.build',\n\t\t\tphase: 'plan' as const,\n\t\t\tafter: ['economy', 'melee.heroes'],\n\t\t\tbefore: ['melee.production'],\n\t\t\t/** Where its home first stood: where its hall is built again when lost, where it may not move home */\n\t\t\thomeAt: undefined as Vec2 | undefined,\n\t\t\tthink: () => {\n\t\t\t\tif (ai.area(Economy).waiting) return\n\t\t\t\twants(ai, ladder, margin, expandAt, module)\n\t\t\t\tai.plans.build.think()\n\t\t\t},\n\t\t\tsave: (): MeleeBuildMemory => ({ v: 1, ...(module.homeAt && { homeAt: { x: module.homeAt.x, z: module.homeAt.z } }) }),\n\t\t\trestore: (data: unknown) => {\n\t\t\t\tconst given = data as MeleeBuildMemory | undefined\n\t\t\t\tif (given?.homeAt) module.homeAt = { x: given.homeAt.x, z: given.homeAt.z }\n\t\t\t}\n\t\t}\n\t\treturn module\n\t} })\n\n/** The ladder as wants on the plan, with what it has now in mind */\nfunction wants(ai: Brain, ladder: readonly MeleeWant[], margin: number, expandAt: number, module: { homeAt: Vec2 | undefined }): void {\n\tconst { view } = ai\n\tconst plan = ai.plans.build\n\tconst by = 'melee'\n\t// where home first stood: a hall lost there is built again there, where it may not move home (Allow Home Changes off)\n\tconst home = view.home()\n\tif (home && !module.homeAt) module.homeAt = { x: home.x, z: home.z }\n\tconst stays = flagOf(ai, 'allowHomeChanges') === false ? module.homeAt : undefined\n\tfor (const rung of ladder) {\n\t\tconst base: Omit<Want, 'type'> = { id: rung.id, priority: rung.priority, keep: true, by, ...(rung.spare !== undefined && { spare: rung.spare }) }\n\t\tswitch (rung.role) {\n\t\t\tcase 'counter': {\n\t\t\t\t// what answers the rivals' armies best, where it cannot be trained yet: the building it needs (a blacksmith for\n\t\t\t\t// riflemen against flyers), with a little to spare\n\t\t\t\tconst wanted = counterNeeds(ai, margin)\n\t\t\t\tif (wanted) plan.want({ ...base, type: wanted.id, count: rung.count ?? 1, by: 'counters', ...(rung.when && { when: rung.when }) })\n\t\t\t\telse plan.drop(rung.id)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'expand': {\n\t\t\t\t// another hall by a free mine once the mine at home runs low: one more than it has, where there is a mine to take\n\t\t\t\tconst hall = view.typesOf('hall')[0]\n\t\t\t\tif (!hall || !mineLow(ai, expandAt)) {\n\t\t\t\t\tplan.drop(rung.id)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tplan.want({\n\t\t\t\t\t...base,\n\t\t\t\t\ttype: hall.id,\n\t\t\t\t\tcount: (brain) => brain.view.mine.buildings().withRole('hall').length + (rung.count ?? 1),\n\t\t\t\t\tby: 'expand',\n\t\t\t\t\twithin: HALL_REACH - 1,\n\t\t\t\t\tnear: () => ai.area(Economy).freeMine(),\n\t\t\t\t\twhen: (brain) => !!brain.area(Economy).freeMine() && (!rung.when || evaluate(rung.when, brain))\n\t\t\t\t})\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tcase 'tier': {\n\t\t\t\t// the next tier of a hall, once there is an army to speak of\n\t\t\t\tconst hall = view.typesOf('hall')[0]\n\t\t\t\tconst tier =\n\t\t\t\t\thall &&\n\t\t\t\t\tview.mine\n\t\t\t\t\t\t.ofType(hall.id)\n\t\t\t\t\t\t.finished()\n\t\t\t\t\t\t.find((each) => upgradesOf(view.def(each)).length && !queueOf(each).length && !upgradeOf(each)?.to)\n\t\t\t\t// the first of what it may turn into, where it may turn into several\n\t\t\t\tconst next = tier && upgradesOf(view.def(tier))[0]\n\t\t\t\tif (next)\n\t\t\t\t\tplan.want({\n\t\t\t\t\t\t...base,\n\t\t\t\t\t\ttype: next,\n\t\t\t\t\t\tcount: view.mine.ofType(next).length + (rung.count ?? 1),\n\t\t\t\t\t\tby: 'tier',\n\t\t\t\t\t\t...(rung.when && { when: rung.when })\n\t\t\t\t\t})\n\t\t\t\telse plan.drop(rung.id)\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tconst type = view.typesOf(rung.role)[0]\n\t\t\t\tif (!type) {\n\t\t\t\t\tplan.drop(rung.id)\n\t\t\t\t\tbreak\n\t\t\t\t}\n\t\t\t\tplan.want({\n\t\t\t\t\t...base,\n\t\t\t\t\ttype: type.id,\n\t\t\t\t\tcount: rung.count ?? 1,\n\t\t\t\t\t...(rung.when && { when: rung.when }),\n\t\t\t\t\t...(rung.role === 'hall' && stays && { near: stays })\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Whether the mine at home is running low: of the money's deposits by its home base in sight, what is left together\n * under `ratio` of what they held (the type's `resource.amount`). No while none is in sight\n */\nfunction mineLow(ai: Brain, ratio: number): boolean {\n\tif (ratio <= 0) return false\n\tconst { view } = ai\n\tconst home = view.bases()[0]\n\tif (!home) return false\n\tconst money = view.registry.currency ?? view.registry.resources[0]?.id\n\tif (!money) return false\n\tlet held = 0\n\tlet left = 0\n\tfor (const deposit of view.resourcesNear(home)) {\n\t\tif (!deposit.visible || deposit.resource === undefined) continue\n\t\tconst def = view.def(deposit)\n\t\tif (def.resource?.id !== money) continue\n\t\theld += def.resource.amount\n\t\tleft += deposit.resource\n\t}\n\treturn held > 0 && left < held * ratio\n}\n\n/**\n * A building it would put up for a better answer to its rivals' armies: what the best of the soldiers its barracks\n * train needs, where it answers them better than any it can train now, and its workers can build it. None otherwise\n */\nfunction counterNeeds(ai: Brain, margin: number): UnitTypeDef | undefined {\n\tconst { registry, view } = ai\n\tconst { me } = view\n\tconst builds = new Set(view.typesOf('worker')[0]?.builds ?? [])\n\tlet best: { def: UnitTypeDef; score: number } | undefined\n\tlet ready = 0\n\tfor (const barracks of view.typesOf('barracks')) {\n\t\tif (!view.mine.ofType(barracks.id).length) continue\n\t\tfor (const id of barracks.trains ?? []) {\n\t\t\tconst def = registry.unit(id)\n\t\t\tif (!isSoldier(def) || !availableToPlayer(def, { race: me.race, availability: me.availability }, id)) continue\n\t\t\tconst score = counters(ai, def)\n\t\t\tif (view.has(def.requires)) ready = Math.max(ready, score)\n\t\t\telse if (score > (best?.score ?? 0)) best = { def, score }\n\t\t}\n\t}\n\tif (!best || best.score <= ready * margin) return undefined\n\t// the first thing it lacks that its workers build: by its id, or what provides it\n\tfor (const need of best.def.requires ?? []) {\n\t\tif (view.has([need])) continue\n\t\tconst maker = registry.units.all().find((def) => builds.has(def.id) && (def.id === need || def.provides?.includes(need)))\n\t\tif (maker) return maker\n\t}\n\treturn undefined\n}\n\n/**\n * How well a type it can train answers what it has seen of its rivals (`Strength.counterFor`: its strength against\n * them over its plain strength; one that hits the air against flyers, one whose damage gets through their armour).\n * 0 where it has seen nothing to answer\n */\nfunction counters(ai: Brain, def: UnitTypeDef): number {\n\tconst { registry } = ai\n\t// the most of each of its rivals' unit types seen at once, as its knowledge keeps them (not creeps, not buildings)\n\tconst seen: Record<string, number> = {}\n\tfor (const [type, { most }] of Object.entries(ai.knowledge.enemy.typesSeen())) {\n\t\tif (registry.units.has(type) && registry.unit(type).kind === 'unit') seen[type] = most\n\t}\n\tif (!Object.keys(seen).length) return 0\n\treturn ai.view.strength.counterFor(seen, [def])[0].score\n}\n"],"mappings":"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"}
|
package/dist/ai/melee/goals.d.ts
CHANGED
|
@@ -41,6 +41,7 @@ export interface MeleeArmyOptions {
|
|
|
41
41
|
* near its bases in the last twenty seconds (3 when left out)
|
|
42
42
|
*/
|
|
43
43
|
counter?: boolean;
|
|
44
|
+
/** How many of their fighters must have fallen near its bases in the last twenty seconds for the counter: 3 when left out */
|
|
44
45
|
counterAfter?: number;
|
|
45
46
|
/** The odds against their army as last seen a wave needs to go on: 0.5 when left out */
|
|
46
47
|
pressOdds?: number;
|
|
@@ -116,6 +117,7 @@ export interface MeleeArmyOptions {
|
|
|
116
117
|
* @beta
|
|
117
118
|
*/
|
|
118
119
|
export interface MeleeArmyMemory {
|
|
120
|
+
/** The version of the memory's format: 1 so far */
|
|
119
121
|
v: 1;
|
|
120
122
|
/** Units the next wave of its own asks for */
|
|
121
123
|
waveSize: number;
|
|
@@ -140,6 +142,7 @@ export interface MeleeArmyMemory {
|
|
|
140
142
|
* @beta
|
|
141
143
|
*/
|
|
142
144
|
export interface MeleeArmyModule extends AiModule {
|
|
145
|
+
/** The army the module runs */
|
|
143
146
|
army: MeleeArmy;
|
|
144
147
|
}
|
|
145
148
|
/**
|
|
@@ -167,9 +170,13 @@ export declare class MeleeArmy {
|
|
|
167
170
|
readonly ai: Brain;
|
|
168
171
|
/** How it goes: the module's options, the brain's settings over them (`ai.settings.army`) */
|
|
169
172
|
readonly options: MeleeArmyOptions;
|
|
173
|
+
/** What the army remembers between thinks: wave size, next times and counts */
|
|
170
174
|
readonly memory: MeleeArmyMemory;
|
|
175
|
+
/** Seconds into the game the first wave is due */
|
|
171
176
|
readonly firstAttack: number;
|
|
177
|
+
/** Seconds between one wave's time and the next */
|
|
172
178
|
readonly attackEvery: number;
|
|
179
|
+
/** How far from a base, in cells, the army defends */
|
|
173
180
|
readonly defendRadius: number;
|
|
174
181
|
constructor(
|
|
175
182
|
/** The brain it is the army of */
|