@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":"score.js","names":["entityDiedEvent","bountyEvent"],"sources":["../src/score.ts"],"sourcesContent":["import {\n\tgameOver,\n\tabilityCast,\n\tbounty as bountyEvent,\n\tconstructionFinished,\n\tdamaged,\n\tentityDied as entityDiedEvent,\n\thealed,\n\theroLevelUp,\n\titemPicked,\n\tresourcesDeposited,\n\tresourcesSpent,\n\ttraded,\n\tunitHired,\n\tunitTrained,\n\txpGained\n} from '#engine/engineEvents'\nimport { defineComponent, type Component } from './components'\nimport type { Entity, PlayerId } from './entity'\nimport type { EventKey } from './events'\nimport type { Rules } from './game'\nimport type { System } from './registry'\nimport type { World } from './world'\nimport { boughtBack, heroAssisted, heroOf, heroState, killStreak } from './hero'\nimport { snapshotField } from './replication'\nimport type { SessionView } from './replication'\n\n/*\n * The score (a classic RTS score screen): numbers about each player that the rules count as the game goes, from the\n * world's events and from the game's own code. Counted where the rules run, so every machine has the same; kept in the\n * world's state (`core.score`), so a save and a replay have them; told to the players in their snapshots\n * (`Snapshot.score`), each the players the game lets them see (`ScoreSettings.live`, `end`). Nothing is counted for a\n * game that does not ask (`RuleSettings.score`); `presetScore()` is the engine's whole set, to take or pick from.\n */\n\n/**\n * How a stat takes what it is told: `sum` adds it up (the default), `count` adds one each time whatever the amount,\n * `max` keeps the most it was told, `min` the least, `last` what it was told last (a gauge: the army now)\n *\n * @beta\n */\nexport type ScoreKind = 'sum' | 'count' | 'max' | 'min' | 'last'\n\n/**\n * How a stat's number reads on a screen: a whole `number` (the default), a `decimal` one, a `percent` (0..1), or\n * `time` (seconds, as 3:05). A screen's own (`GameView.hud.score.format`) goes over it\n *\n * @beta\n */\nexport type ScoreFormat = 'number' | 'decimal' | 'percent' | 'time'\n\n/**\n * What a stat is told of an event, for a player: how much (`amount`, 1 when left out) and what of (`type`: a unit\n * type, an ability, anything the stat is split by, `ScoreStatDef.byType`)\n *\n * @beta\n */\nexport interface ScoreCount {\n\t/** Whose number it is */\n\tplayer: PlayerId\n\t/** How much: 1 when left out */\n\tamount?: number\n\t/** What it was counted of, for a stat kept `byType`: a unit type, an ability */\n\ttype?: string\n}\n\n/**\n * What a stat's source makes of an event: nothing to count (`undefined`), one player (one more for them), what one\n * player is counted, or several of those\n *\n * @beta\n */\nexport type ScoreCounted = PlayerId | ScoreCount | readonly ScoreCount[] | undefined | void\n\n/**\n * Where a stat's numbers come from: an event of the world's (`'entityDied'`) or of the game's own (`defineEvent`), and\n * what it counts of each (`scoreOn`)\n *\n * @beta\n */\nexport interface ScoreSource {\n\t/** The event: one of the engine's (`entityDied`) or of the game's own (`defineEvent`) */\n\tevent: EventKey<any>\n\t/** What it counts of each: nothing, a player, or what a player is counted */\n\tcount(payload: any, world: World): ScoreCounted\n}\n\n/**\n * A number the score keeps for each player (`RuleSettings.score`, `defineStat`): what it is called, how it adds up, where\n * it comes from, and how it is shown. One with no source is counted by the game's code alone (`world.score.add`)\n *\n * @beta\n */\nexport interface ScoreStatDef {\n\t/** Its own, among the game's stats: `world.score.add(player, id, …)` names it */\n\tid: string\n\t/** What it is called on a screen: its id when left out */\n\tlabel?: string\n\t/** What the screen says it is, in a tip */\n\tdescription?: string\n\t/** The tab of the score screen it is in: `units`, `heroes`, `resources`, `combat`, or the game's own. `other` when left out */\n\tcategory?: string\n\t/** How it adds up: `sum` when left out, `last` for one that only samples */\n\tkind?: ScoreKind\n\t/** The events it is counted from */\n\tfrom?: ScoreSource | readonly ScoreSource[]\n\t/**\n\t * A gauge: what it is for a player now (their supply used, their gold), read once a second and at each point of the\n\t * timeline, and taken as `kind` says (`last` when left out). Nothing taken for `undefined`\n\t */\n\tsample?(world: World, player: PlayerId): number | undefined\n\t/** Kept by what it was counted of too (`ScoreCount.type`): units killed by unit type, abilities cast by ability */\n\tbyType?: boolean\n\t/** On the timeline: sampled every `ScoreSettings.every` seconds, for a screen's graph */\n\ttimeline?: boolean\n\t/** How its number is written: `number` (when left out), `decimal`, `percent` (0 to 1), `time` (seconds) */\n\tformat?: ScoreFormat\n\t/** Counted, and not on the score screen: for the game's own use (an achievement, a mission's goal) */\n\thidden?: boolean\n}\n\n/**\n * Who of the players is told a player's numbers: that player alone (`own`), their side (`allies`), `everyone`, or\n * `none`; or a function of the world, who is told (`undefined` for an observer) and whose numbers they are\n *\n * @beta\n */\nexport type ScoreAudience = 'own' | 'allies' | 'everyone' | 'none' | ((world: World, viewer: PlayerId | undefined, player: PlayerId) => boolean)\n\n/**\n * What a game counts of its players (`RuleSettings.score`): the stats, how often the timeline is sampled, and who is told\n * what while the game goes on and after it ended. `presetScore()` makes one of the engine's stats\n *\n * @beta\n */\nexport interface ScoreSettings {\n\t/** The stats, or what makes them of the game (the engine's set makes one of each resource) */\n\tstats: readonly ScoreStatDef[] | ((game: Rules) => readonly ScoreStatDef[])\n\t/** Seconds between two points of the timeline: 10 when left out, 0 for no timeline */\n\tevery?: number\n\t/**\n\t * Points the timeline keeps at most: past it, every other point goes and they are twice as far apart, so a long\n\t * game keeps its whole story in as much room. 360 when left out\n\t */\n\tmaxPoints?: number\n\t/** Who is told a player's numbers while the game goes on: their side (`allies`) when left out. An observer is told everyone's */\n\tlive?: ScoreAudience\n\t/** Who is told them once the game is decided: `everyone` when left out */\n\tend?: ScoreAudience\n\t/** Seconds between two tellings of the numbers to the screens while the game goes on: 1 when left out */\n\trefresh?: number\n\t/** Whose numbers are kept: every player but the neutral ones and the creeps when left out */\n\tcounts?(world: World, player: PlayerId): boolean\n\t/** The tabs of the score screen, in order, with their names: those of the stats, in the order met, when left out */\n\tcategories?: readonly { id: string; label: string }[]\n}\n\n/**\n * The score's rules, its stats made: what the registry keeps (`registry.score`)\n *\n * @beta\n */\nexport interface ResolvedScore {\n\t/** The rules as the game gave them */\n\treadonly rules: ScoreSettings\n\t/** Every stat, made */\n\treadonly stats: readonly ScoreStatDef[]\n\t/** Every stat by its id */\n\treadonly byId: ReadonlyMap<string, ScoreStatDef>\n\t/** The tabs of the score screen, in order */\n\treadonly categories: readonly { id: string; label: string }[]\n}\n\n/**\n * What the score keeps in the world (`world.state(scoreData)`), plain data for a save: by stat, by player, the number;\n * by stat, player and type, the numbers of a stat kept `byType`; the ticks of the timeline's points, and by stat and\n * player, the number at each\n *\n * @beta\n */\nexport interface ScoreData {\n\t/** By stat, by player: the number */\n\tvalues: Record<string, Record<number, number>>\n\t/** By stat, player and type: the numbers of a stat kept `byType` */\n\ttypes: Record<string, Record<number, Record<string, number>>>\n\t/** Ticks between two points of the timeline, as it is now (doubled each time it was thinned) */\n\tevery: number\n\t/** The ticks of the timeline's points */\n\tticks: number[]\n\t/** By stat and player: the number at each point of the timeline */\n\tline: Record<string, Record<number, number[]>>\n}\n\n/**\n * The world's component the score is kept in (`core.score`, on the world's own entity): what a save keeps of it\n *\n * @beta\n */\nexport const scoreData: Component<ScoreData> = defineComponent<ScoreData>({ id: 'core.score', default: () => ({ values: {}, types: {}, every: 0, ticks: [], line: {} }) })\n\n/**\n * What a player is told of the score (`Snapshot.score`): the numbers of the players they may see, as they stood at\n * `tick`. Rounded to hundredths\n *\n * @beta\n */\nexport interface ScoreState {\n\t/** The tick the numbers stood at */\n\ttick: number\n\t/** The game is decided: these are the numbers it ended with, told as `ScoreSettings.end` says */\n\tfinal: boolean\n\t/** Whose numbers are in it */\n\tplayers: PlayerId[]\n\t/** By stat, by player */\n\tvalues: Record<string, Record<number, number>>\n\t/** By stat, by player, by type: of the stats kept `byType` */\n\ttypes?: Record<string, Record<number, Record<string, number>>>\n}\n\n/**\n * The timeline a player is told (`Snapshot.scoreLine`): the ticks of its points, and by stat and player the number at\n * each, for the players they may see\n *\n * @beta\n */\nexport interface ScoreLineState {\n\t/** Seconds between two points */\n\tevery: number\n\t/** The ticks of its points */\n\tticks: number[]\n\t/** By stat and player: the number at each point */\n\tvalues: Record<string, Record<number, number[]>>\n}\n\n/**\n * A source of a stat, typed by its event, the engine's or the game's own: `scoreOn(entityDied, ({ entity, killer }) =>\n * killer && { player: killer.owner })`\n *\n * @beta\n */\nexport function scoreOn<T>(event: EventKey<T>, count: (payload: T, world: World) => ScoreCounted): ScoreSource {\n\treturn { event, count }\n}\n\n/**\n * A stat of the game's own, for `RuleSettings.score`: `defineStat({ id: 'towersLost', label: 'Towers lost', category: 'units',\n * from: scoreOn(entityDied, ({ entity }) => entity.def.tags?.includes('tower') ? entity.owner : undefined) })`.\n * One with no source is counted in code (`world.score.add(player, 'towersLost')`)\n *\n * @public\n */\nexport function defineStat(def: ScoreStatDef): ScoreStatDef {\n\treturn def\n}\n\nconst CATEGORY_LABELS: Record<string, string> = { units: 'Units', heroes: 'Heroes', resources: 'Resources', combat: 'Combat', other: 'Other' }\n\n/** The score's rules with their stats made of the game, checked: an id twice, or a timeline of no length, throws */\nexport function resolveScore(rules: ScoreSettings | undefined | null, game: Rules): ResolvedScore | null {\n\tif (!rules) return null\n\tconst stats = typeof rules.stats === 'function' ? rules.stats(game) : rules.stats\n\tconst byId = new Map<string, ScoreStatDef>()\n\tfor (const stat of stats) {\n\t\tif (byId.has(stat.id)) throw new Error(`The score has the stat \"${stat.id}\" twice`)\n\t\tbyId.set(stat.id, stat)\n\t}\n\tif (rules.every !== undefined && !(rules.every >= 0)) throw new Error(`The score's timeline is sampled every ${rules.every} seconds: 0 or more`)\n\tconst categories = [...(rules.categories ?? [])]\n\tfor (const stat of stats) {\n\t\tconst id = stat.category ?? 'other'\n\t\tif (!stat.hidden && !categories.some((category) => category.id === id)) categories.push({ id, label: CATEGORY_LABELS[id] ?? id })\n\t}\n\treturn { rules, stats, byId, categories }\n}\n\n/** What a kind makes of a number and what is told */\nfunction combine(kind: ScoreKind | undefined, before: number | undefined, amount: number): number {\n\tswitch (kind) {\n\t\tcase 'count':\n\t\t\treturn (before ?? 0) + 1\n\t\tcase 'max':\n\t\t\treturn before === undefined ? amount : Math.max(before, amount)\n\t\tcase 'min':\n\t\t\treturn before === undefined ? amount : Math.min(before, amount)\n\t\tcase 'last':\n\t\t\treturn amount\n\t\tdefault:\n\t\t\treturn (before ?? 0) + amount\n\t}\n}\n\n/** Rounded to hundredths, for the wire */\nconst hundredths = (value: number) => Math.round(value * 100) / 100\n\n/**\n * The score of a world (`world.score`): counts what its stats are told of the world's events, takes the gauges and\n * the timeline's points, and is what the game's code counts with, and reads, in the rules. What it keeps is the\n * world's state (`scoreData`); nothing of it is kept here but what is made again from the game\n *\n * @beta\n */\nexport class Score {\n\t/** Goes up with every change of a number: what a session tells the screens again by */\n\tversion = 0\n\t/** Goes up with every point of the timeline */\n\tlineVersion = 0\n\tprivate offs: (() => void)[] = []\n\n\tconstructor(private readonly world: World) {\n\t\tthis.listen()\n\t}\n\n\t/** The game's score, as its rules say: none for a game that counts nothing */\n\tget rules(): ResolvedScore | null {\n\t\treturn this.world.registry.score\n\t}\n\n\t/** Whether the game counts anything */\n\tget on(): boolean {\n\t\treturn this.world.registry.score !== null\n\t}\n\n\t/** The stats, in order */\n\tstats(): readonly ScoreStatDef[] {\n\t\treturn this.rules?.stats ?? []\n\t}\n\n\t/** Hears the events the stats are counted from: again when the game takes a new version (`reloadGame`) */\n\tlisten(): void {\n\t\tfor (const off of this.offs) off()\n\t\tthis.offs = []\n\t\tconst score = this.rules\n\t\tif (!score) return\n\t\tconst byEvent = new Map<string, { key: EventKey<unknown>; list: { stat: ScoreStatDef; source: ScoreSource }[] }>()\n\t\tfor (const stat of score.stats) {\n\t\t\tconst sources = !stat.from ? [] : Array.isArray(stat.from) ? (stat.from as readonly ScoreSource[]) : [stat.from as ScoreSource]\n\t\t\tfor (const source of sources) {\n\t\t\t\tlet heard = byEvent.get(source.event.id)\n\t\t\t\tif (!heard) byEvent.set(source.event.id, (heard = { key: source.event, list: [] }))\n\t\t\t\theard.list.push({ stat, source })\n\t\t\t}\n\t\t}\n\t\tconst world = this.world\n\t\tfor (const { key, list } of byEvent.values()) {\n\t\t\tthis.offs.push(\n\t\t\t\tworld.events.on(key, (payload: unknown) => {\n\t\t\t\t\tfor (let i = 0; i < list.length; i++) {\n\t\t\t\t\t\tconst { stat, source } = list[i]\n\t\t\t\t\t\t// one switched off for having thrown counts nothing more\n\t\t\t\t\t\tif (world.disabled.size && world.disabled.has(`listener:score:${stat.id}`)) continue\n\t\t\t\t\t\tlet counted: ScoreCounted\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tcounted = source.count(payload, world)\n\t\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\t\tworld.caught(error, { kind: 'listener', id: `score:${stat.id}` })\n\t\t\t\t\t\t\tcontinue\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.take(stat, counted)\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t)\n\t\t}\n\t\t// the last of the gauges and a last point, as the game is decided\n\t\tthis.offs.push(world.events.on(gameOver, () => this.sample(true)))\n\t}\n\n\tprivate take(stat: ScoreStatDef, counted: ScoreCounted): void {\n\t\tif (counted === undefined || counted === null) return\n\t\tif (typeof counted === 'number') this.put(stat, counted, 1, undefined)\n\t\telse if (Array.isArray(counted)) for (const each of counted as readonly ScoreCount[]) this.put(stat, each.player, each.amount ?? 1, each.type)\n\t\telse {\n\t\t\tconst each = counted as ScoreCount\n\t\t\tthis.put(stat, each.player, each.amount ?? 1, each.type)\n\t\t}\n\t}\n\n\t/** Whether a player's numbers are kept: as the rules say, every player but the neutral ones and the creeps when they do not */\n\tcounts(player: PlayerId): boolean {\n\t\tconst own = this.rules?.rules.counts\n\t\tif (own) return own(this.world, player)\n\t\tconst found = this.world.players.get(player)\n\t\treturn !!found && !found.neutral && !found.creeps\n\t}\n\n\t/** Who `counts`, by player id, where the rules leave it to the engine (whether a player is neutral never changes) */\n\tprivate counted: boolean[] = []\n\n\t/** The players whose numbers are kept, by id */\n\tplayers(): PlayerId[] {\n\t\tconst players: PlayerId[] = []\n\t\tfor (const id of this.world.players.keys()) if (this.counts(id)) players.push(id)\n\t\treturn players.sort((a, b) => a - b)\n\t}\n\n\tprivate put(stat: ScoreStatDef, player: PlayerId, amount: number, type: string | undefined): void {\n\t\tif (!Number.isFinite(amount)) return\n\t\tif (this.rules!.rules.counts ? !this.counts(player) : !(this.counted[player] ??= this.counts(player))) return\n\t\tconst data = this.world.state(scoreData)\n\t\tconst values = (data.values[stat.id] ??= {})\n\t\tvalues[player] = combine(stat.kind, values[player], amount)\n\t\tif (stat.byType && type !== undefined) {\n\t\t\tconst types = ((data.types[stat.id] ??= {})[player] ??= {})\n\t\t\ttypes[type] = combine(stat.kind, types[type], amount)\n\t\t}\n\t\tthis.version++\n\t}\n\n\tprivate stat(id: string): ScoreStatDef {\n\t\tconst stat = this.rules?.byId.get(id)\n\t\tif (!stat) {\n\t\t\tthrow new Error(\n\t\t\t\tthis.rules\n\t\t\t\t\t? `The score has no stat \"${id}\": give it in RuleSettings.score (defineStat)`\n\t\t\t\t\t: `The game counts no score: give RuleSettings.score (presetScore(), or stats of its own) to count \"${id}\"`\n\t\t\t)\n\t\t}\n\t\treturn stat\n\t}\n\n\t/** Counts something for a player, as the stat's kind takes it (adds it up for a sum): one when no amount is given */\n\tadd(player: PlayerId, id: string, amount = 1, type?: string): void {\n\t\tthis.put(this.stat(id), player, amount, type)\n\t}\n\n\t/** Sets a player's number, whatever the stat's kind */\n\tset(player: PlayerId, id: string, value: number, type?: string): void {\n\t\tthis.put({ ...this.stat(id), kind: 'last' }, player, value, type)\n\t}\n\n\t/** A player's number of a stat: 0 for one never counted */\n\tget(player: PlayerId, id: string): number {\n\t\treturn this.world.state(scoreData).values[id]?.[player] ?? 0\n\t}\n\n\t/** A player's numbers of a stat kept by type, by type */\n\tbyType(player: PlayerId, id: string): Readonly<Record<string, number>> {\n\t\treturn this.world.state(scoreData).types[id]?.[player] ?? {}\n\t}\n\n\t/** A team's number of a stat: its players' added up, or the most or the least of them for `max` and `min` */\n\tteam(team: number, id: string): number {\n\t\tconst stat = this.stat(id)\n\t\tlet total: number | undefined\n\t\tfor (const player of this.players()) {\n\t\t\tif (this.world.player(player).team !== team) continue\n\t\t\tconst value = this.get(player, id)\n\t\t\ttotal = stat.kind === 'max' || stat.kind === 'min' ? (total === undefined ? value : combine(stat.kind, total, value)) : (total ?? 0) + value\n\t\t}\n\t\treturn total ?? 0\n\t}\n\n\t/** The timeline of a player's number of a stat on it: its points, at `ticks` */\n\ttimeline(player: PlayerId, id: string): { ticks: readonly number[]; values: readonly number[] } {\n\t\tconst data = this.world.state(scoreData)\n\t\treturn { ticks: data.ticks, values: data.line[id]?.[player] ?? [] }\n\t}\n\n\t/** Reads the gauges, and on a point of the timeline (or `point`) takes a point. Run once a second by the score's system */\n\tsample(point = false): void {\n\t\tconst score = this.rules\n\t\tif (!score) return\n\t\tconst { world } = this\n\t\tconst players = this.players()\n\t\tfor (const stat of score.stats) {\n\t\t\tif (!stat.sample || (world.disabled.size && world.disabled.has(`system:score:${stat.id}`))) continue\n\t\t\tconst kind = stat.kind ?? 'last'\n\t\t\tfor (const player of players) {\n\t\t\t\tlet value: number | undefined\n\t\t\t\ttry {\n\t\t\t\t\tvalue = stat.sample(world, player)\n\t\t\t\t} catch (error) {\n\t\t\t\t\tworld.caught(error, { kind: 'system', id: `score:${stat.id}` })\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif (value !== undefined) this.put(stat.kind ? stat : { ...stat, kind }, player, value, undefined)\n\t\t\t}\n\t\t}\n\t\tconst data = world.state(scoreData)\n\t\tconst every = Math.round((score.rules.every ?? 10) * world.tickRate)\n\t\tif (every <= 0) return\n\t\tif (!data.every) data.every = every\n\t\tconst due = data.ticks.length === 0 || world.tick - data.ticks[data.ticks.length - 1] >= data.every\n\t\tif (!due && !(point && data.ticks[data.ticks.length - 1] !== world.tick)) return\n\t\tdata.ticks.push(world.tick)\n\t\tfor (const stat of score.stats) {\n\t\t\tif (!stat.timeline) continue\n\t\t\tconst line = (data.line[stat.id] ??= {})\n\t\t\tfor (const player of players) {\n\t\t\t\tconst points = (line[player] ??= [])\n\t\t\t\t// a player whose numbers began to be kept late starts at nothing\n\t\t\t\twhile (points.length < data.ticks.length - 1) points.push(0)\n\t\t\t\tpoints.push(data.values[stat.id]?.[player] ?? 0)\n\t\t\t}\n\t\t}\n\t\t// a long game keeps its whole story: every other point goes, and they are twice as far apart\n\t\tconst max = Math.max(score.rules.maxPoints ?? 360, 8)\n\t\tif (data.ticks.length > max) {\n\t\t\tconst keep = (list: number[]) => list.filter((_, i) => i % 2 === 0 || i === list.length - 1)\n\t\t\tdata.ticks = keep(data.ticks)\n\t\t\tfor (const lines of Object.values(data.line)) for (const player in lines) lines[player] = keep(lines[player])\n\t\t\tdata.every *= 2\n\t\t}\n\t\tthis.lineVersion++\n\t\tthis.version++\n\t}\n\n\t/** Whether `viewer` (`undefined` for an observer) is told `player`'s numbers now */\n\ttells(viewer: PlayerId | undefined, player: PlayerId, final: boolean): boolean {\n\t\tconst rules = this.rules?.rules\n\t\tif (!rules) return false\n\t\tconst audience = final ? (rules.end ?? 'everyone') : (rules.live ?? 'allies')\n\t\tif (typeof audience === 'function') return audience(this.world, viewer, player)\n\t\tif (audience === 'none') return false\n\t\tif (viewer === undefined || audience === 'everyone') return true\n\t\tif (audience === 'own') return viewer === player\n\t\treturn viewer === player || this.world.player(viewer).team === this.world.player(player).team\n\t}\n\n\t/** What `viewer` is told of the numbers (`Snapshot.score`): nothing for a game that counts none, or a viewer told of no one */\n\tstateFor(viewer: PlayerId | undefined, final: boolean): ScoreState | undefined {\n\t\tconst score = this.rules\n\t\tif (!score) return undefined\n\t\tconst players = this.players().filter((player) => this.tells(viewer, player, final))\n\t\tif (!players.length) return undefined\n\t\tconst data = this.world.state(scoreData)\n\t\tconst values: ScoreState['values'] = {}\n\t\tlet types: ScoreState['types']\n\t\tfor (const stat of score.stats) {\n\t\t\tconst all = data.values[stat.id]\n\t\t\tif (all) {\n\t\t\t\tconst told: Record<number, number> = {}\n\t\t\t\tfor (const player of players) if (player in all) told[player] = hundredths(all[player])\n\t\t\t\tvalues[stat.id] = told\n\t\t\t}\n\t\t\tconst byType = stat.byType ? data.types[stat.id] : undefined\n\t\t\tif (byType) {\n\t\t\t\tconst told: Record<number, Record<string, number>> = {}\n\t\t\t\tfor (const player of players) {\n\t\t\t\t\tif (!byType[player]) continue\n\t\t\t\t\tconst each: Record<string, number> = {}\n\t\t\t\t\tfor (const type in byType[player]) each[type] = hundredths(byType[player][type])\n\t\t\t\t\ttold[player] = each\n\t\t\t\t}\n\t\t\t\t;(types ??= {})[stat.id] = told\n\t\t\t}\n\t\t}\n\t\treturn { tick: this.world.tick, final, players, values, ...(types && { types }) }\n\t}\n\n\t/** What `viewer` is told of the timeline (`Snapshot.scoreLine`): nothing without one */\n\tlineFor(viewer: PlayerId | undefined, final: boolean): ScoreLineState | undefined {\n\t\tconst score = this.rules\n\t\tif (!score) return undefined\n\t\tconst data = this.world.state(scoreData)\n\t\tif (!data.ticks.length) return undefined\n\t\tconst players = this.players().filter((player) => this.tells(viewer, player, final))\n\t\tif (!players.length) return undefined\n\t\tconst values: ScoreLineState['values'] = {}\n\t\tfor (const stat in data.line) {\n\t\t\tconst told: Record<number, number[]> = {}\n\t\t\tfor (const player of players) if (data.line[stat][player]) told[player] = data.line[stat][player].map(hundredths)\n\t\t\tvalues[stat] = told\n\t\t}\n\t\treturn { every: data.every / this.world.tickRate, ticks: [...data.ticks], values }\n\t}\n}\n\n/** The score's system: the gauges once a second, a point of the timeline when one is due. Only in a game that counts */\nexport function scoreSystem(world: World): System {\n\treturn {\n\t\tname: 'score',\n\t\tphase: 'cleanup',\n\t\tevery: Math.max(Math.round(world.tickRate), 1),\n\t\tupdate: (world) => world.score.sample()\n\t}\n}\n\n// ---- the engine's stats (`presetScore`)\n\nconst enemies = (world: World, a: PlayerId, b: PlayerId) => world.areEnemies(a, b)\n\n/** Whether a death is a loss: what was cancelled, ran out, was removed, a tree felled or a mine dry is not */\nconst lost = (reason: string) =>\n\treason !== 'cancelled' && reason !== 'expired' && reason !== 'removed' && reason !== 'depleted' && reason !== 'felled'\n\nconst killedBy = (world: World, entity: Entity, killer: Entity | undefined) =>\n\tkiller && enemies(world, killer.owner, entity.owner) ? killer.owner : undefined\n\n/**\n * The stats `presetScore` has, by id, those of each resource made of the game (`gathered.gold`, `spent.gold`...)\n *\n * @beta\n */\nexport function engineStats(game: Rules): ScoreStatDef[] {\n\tconst resources = game.resources ?? []\n\tconst currency = game.currency ?? resources[0]?.id\n\treturn [\n\t\t// units\n\t\tdefineStat({ id: 'unitsProduced', label: 'Units produced',\n\t\t\tcategory: 'units',\n\t\t\tbyType: true,\n\t\t\tfrom: [\n\t\t\t\tscoreOn(unitTrained, ({ unit }) => ({ player: unit.owner, type: unit.def.id })),\n\t\t\t\tscoreOn(unitHired, ({ unit, player }) => ({ player, type: unit.def.id }))\n\t\t\t] }),\n\t\tdefineStat({ id: 'unitsKilled', label: 'Units killed',\n\t\t\tcategory: 'units',\n\t\t\tbyType: true,\n\t\t\ttimeline: true,\n\t\t\tfrom: scoreOn(entityDiedEvent, ({ entity, killer }, world) => {\n\t\t\t\tif (!entity.isUnit) return undefined\n\t\t\t\tconst by = killedBy(world, entity, killer)\n\t\t\t\treturn by === undefined ? undefined : { player: by, type: entity.def.id }\n\t\t\t}) }),\n\t\tdefineStat({ id: 'unitsLost', label: 'Units lost',\n\t\t\tcategory: 'units',\n\t\t\tbyType: true,\n\t\t\tfrom: scoreOn(entityDiedEvent, ({ entity, reason }) =>\n\t\t\t\tentity.isUnit && lost(reason) ? { player: entity.owner, type: entity.def.id } : undefined\n\t\t\t) }),\n\t\tdefineStat({ id: 'buildingsBuilt', label: 'Buildings built',\n\t\t\tcategory: 'units',\n\t\t\tbyType: true,\n\t\t\tfrom: scoreOn(constructionFinished, (building) => ({ player: building.owner, type: building.def.id })) }),\n\t\tdefineStat({ id: 'buildingsRazed', label: 'Buildings razed',\n\t\t\tcategory: 'units',\n\t\t\tbyType: true,\n\t\t\tfrom: scoreOn(entityDiedEvent, ({ entity, killer }, world) => {\n\t\t\t\tif (!entity.isBuilding) return undefined\n\t\t\t\tconst by = killedBy(world, entity, killer)\n\t\t\t\treturn by === undefined ? undefined : { player: by, type: entity.def.id }\n\t\t\t}) }),\n\t\tdefineStat({ id: 'buildingsLost', label: 'Buildings lost',\n\t\t\tcategory: 'units',\n\t\t\tfrom: scoreOn(entityDiedEvent, ({ entity, reason }) => (entity.isBuilding && lost(reason) ? entity.owner : undefined)) }),\n\t\tdefineStat({ id: 'army', label: 'Army',\n\t\t\tdescription: 'The supply used now',\n\t\t\tcategory: 'units',\n\t\t\tkind: 'last',\n\t\t\ttimeline: true,\n\t\t\tsample: (world, player) => world.player(player).supplyUsed }),\n\t\tdefineStat({ id: 'largestArmy', label: 'Largest army',\n\t\t\tdescription: 'The most supply used at once',\n\t\t\tcategory: 'units',\n\t\t\tkind: 'max',\n\t\t\tsample: (world, player) => world.player(player).supplyUsed }),\n\t\t// heroes\n\t\tdefineStat({ id: 'heroesKilled', label: 'Heroes killed',\n\t\t\tcategory: 'heroes',\n\t\t\tbyType: true,\n\t\t\tfrom: scoreOn(entityDiedEvent, ({ entity, killer }, world) => {\n\t\t\t\tif (!entity.has(heroState)) return undefined\n\t\t\t\tconst by = killedBy(world, entity, killer)\n\t\t\t\treturn by === undefined ? undefined : { player: by, type: entity.def.id }\n\t\t\t}) }),\n\t\tdefineStat({ id: 'heroesLost', label: 'Heroes lost',\n\t\t\tcategory: 'heroes',\n\t\t\tfrom: scoreOn(entityDiedEvent, ({ entity, reason }) => (heroOf(entity) && lost(reason) ? entity.owner : undefined)) }),\n\t\tdefineStat({ id: 'heroAssists', label: 'Assists',\n\t\t\tdescription: 'Heroes killed with the help of its heroes: hurt by them, or their killer healed, shielded or buffed',\n\t\t\tcategory: 'heroes',\n\t\t\tbyType: true,\n\t\t\tfrom: scoreOn(heroAssisted, ({ player, type }) => ({ player, type })) }),\n\t\tdefineStat({ id: 'longestKillStreak', label: 'Longest kill streak',\n\t\t\tdescription: 'The most heroes one of its heroes killed without dying',\n\t\t\tcategory: 'heroes',\n\t\t\tkind: 'max',\n\t\t\tfrom: scoreOn(killStreak, ({ player, streak, type }) => ({ player, amount: streak, type })) }),\n\t\tdefineStat({ id: 'buybacks', label: 'Buybacks',\n\t\t\tcategory: 'heroes',\n\t\t\tfrom: scoreOn(boughtBack, ({ player, type }) => ({ player, type })) }),\n\t\tdefineStat({ id: 'highestHeroLevel', label: 'Highest hero level',\n\t\t\tcategory: 'heroes',\n\t\t\tkind: 'max',\n\t\t\tfrom: scoreOn(heroLevelUp, ({ hero, level }) => ({ player: hero.owner, amount: level, type: hero.def.id })) }),\n\t\tdefineStat({ id: 'experience', label: 'Experience gained',\n\t\t\tcategory: 'heroes',\n\t\t\tbyType: true,\n\t\t\tfrom: scoreOn(xpGained, ({ hero, amount }) => ({ player: hero.owner, amount, type: hero.def.id })) }),\n\t\tdefineStat({ id: 'creepsKilled', label: 'Creeps killed',\n\t\t\tcategory: 'heroes',\n\t\t\tfrom: scoreOn(entityDiedEvent, ({ entity, killer }, world) => (killer && world.player(entity.owner).creeps ? killer.owner : undefined)) }),\n\t\tdefineStat({ id: 'itemsObtained', label: 'Items obtained',\n\t\t\tcategory: 'heroes',\n\t\t\tbyType: true,\n\t\t\tfrom: scoreOn(itemPicked, ({ entity, item }) => ({ player: entity.owner, type: item.item })) }),\n\t\tdefineStat({ id: 'abilitiesCast', label: 'Abilities cast',\n\t\t\tcategory: 'heroes',\n\t\t\tbyType: true,\n\t\t\tfrom: scoreOn(abilityCast, ({ caster, ability }) => ({ player: caster.owner, type: ability.id })) }),\n\t\t// combat\n\t\tdefineStat({ id: 'damageDealt', label: 'Damage dealt',\n\t\t\tcategory: 'combat',\n\t\t\tbyType: true,\n\t\t\ttimeline: true,\n\t\t\tfrom: scoreOn(damaged, ({ target, source, amount }, world) =>\n\t\t\t\tsource && enemies(world, source.owner, target.owner) ? { player: source.owner, amount, type: source.def.id } : undefined\n\t\t\t) }),\n\t\tdefineStat({ id: 'damageTaken', label: 'Damage taken',\n\t\t\tcategory: 'combat',\n\t\t\tfrom: scoreOn(damaged, ({ target, amount }) => ({ player: target.owner, amount })) }),\n\t\tdefineStat({ id: 'healing', label: 'Healing done',\n\t\t\tcategory: 'combat',\n\t\t\tbyType: true,\n\t\t\tfrom: scoreOn(healed, ({ target, source, amount }) => ({ player: (source ?? target).owner, amount, type: (source ?? target).def.id })) }),\n\t\t// resources\n\t\t...resources.flatMap((resource) => [\n\t\t\tdefineStat({ id: `gathered.${resource.id}`, label: `${resource.name} gathered`,\n\t\t\t\tcategory: 'resources',\n\t\t\t\ttimeline: resource.id === currency,\n\t\t\t\tfrom: scoreOn(resourcesDeposited, ({ player, kind, amount }) => (kind === resource.id ? { player, amount } : undefined)) }),\n\t\t\tdefineStat({ id: `spent.${resource.id}`, label: `${resource.name} spent`,\n\t\t\t\tcategory: 'resources',\n\t\t\t\tbyType: true,\n\t\t\t\tfrom: scoreOn(resourcesSpent, ({ player, cost, on, refund }) =>\n\t\t\t\t\tcost[resource.id] ? { player, amount: refund ? -cost[resource.id] : cost[resource.id], type: on } : undefined\n\t\t\t\t) }),\n\t\t\t...(resource.upkeep\n\t\t\t\t? [\n\t\t\t\t\t\tdefineStat({ id: `upkeep.${resource.id}`, label: `${resource.name} lost to upkeep`,\n\t\t\t\t\t\t\tcategory: 'resources',\n\t\t\t\t\t\t\tfrom: scoreOn(resourcesDeposited, ({ player, kind, upkeep }) =>\n\t\t\t\t\t\t\t\tkind === resource.id && upkeep ? { player, amount: upkeep } : undefined\n\t\t\t\t\t\t\t) })\n\t\t\t\t\t]\n\t\t\t\t: [])\n\t\t]),\n\t\t...(currency\n\t\t\t? [\n\t\t\t\t\tdefineStat({ id: 'bounty', label: 'Bounty',\n\t\t\t\t\t\tdescription: `${resources.find((resource) => resource.id === currency)?.name ?? currency} for kills`,\n\t\t\t\t\t\tcategory: 'resources',\n\t\t\t\t\t\tfrom: scoreOn(bountyEvent, ({ player, amount }) => ({ player, amount })) })\n\t\t\t\t]\n\t\t\t: []),\n\t\t// what went between allies, in a game with something to give\n\t\t...(resources.length\n\t\t\t? [\n\t\t\t\t\tdefineStat({ id: 'tradedOut', label: 'Given to allies',\n\t\t\t\t\t\tcategory: 'resources',\n\t\t\t\t\t\tbyType: true,\n\t\t\t\t\t\tfrom: scoreOn(traded, ({ from, resource, sent }) => ({ player: from, amount: sent, type: resource })) }),\n\t\t\t\t\tdefineStat({ id: 'tradedIn', label: 'Given by allies',\n\t\t\t\t\t\tcategory: 'resources',\n\t\t\t\t\t\tbyType: true,\n\t\t\t\t\t\tfrom: scoreOn(traded, ({ to, resource, received }) => ({ player: to, amount: received, type: resource })) })\n\t\t\t\t]\n\t\t\t: [])\n\t]\n}\n\n/**\n * What `presetScore` is given: which of the engine's stats (`only`, or all but `without`), stats of the game's own\n * after them, and the score's other rules\n *\n * @beta\n */\nexport interface PresetScoreOptions extends Omit<ScoreSettings, 'stats'> {\n\t/** Only these of the engine's stats, by id (`gathered` for every `gathered.<resource>`) */\n\tonly?: readonly string[]\n\t/** The engine's stats but these, by id or as `only` */\n\twithout?: readonly string[]\n\t/** Stats of the game's own, after the engine's */\n\tstats?: readonly ScoreStatDef[]\n}\n\n/**\n * The engine's score, for `RuleSettings.score`: a classic RTS score screen. Units produced, killed and lost, buildings\n * built, razed and lost, the army and the largest, heroes killed and lost, the highest hero level, experience, creeps\n * killed, items obtained, abilities cast, damage dealt and taken, healing, and of each resource what was gathered,\n * spent and lost to upkeep, the bounty and what went between allies\n *\n * @public\n */\nexport function presetScore(options: PresetScoreOptions = {}): ScoreSettings {\n\tconst { only, without, stats: own = [], ...rules } = options\n\tconst named = (list: readonly string[] | undefined, id: string) => !!list?.some((name) => name === id || id.startsWith(`${name}.`))\n\treturn {\n\t\t...rules,\n\t\tstats: (game) => [...engineStats(game).filter((stat) => (!only || named(only, stat.id)) && !named(without, stat.id)), ...own]\n\t}\n}\n\n/** What a seat was last told of the score, and when: told again once `refresh` seconds passed and it changed, or as the game is decided */\ninterface ScoreTold {\n\tscore?: ScoreState\n\tline?: ScoreLineState\n\ttick: number\n\tversion: number\n\tlineVersion: number\n\tfinal: boolean\n}\n\nconst TOLD = {}\n\n/** What the seat is told of the score now: the same objects while nothing new is to be told */\nfunction scoreTold(view: SessionView): ScoreTold | undefined {\n\tconst { world } = view\n\tconst counted = world.score.rules\n\tif (!counted || view.forComputer) return undefined\n\tconst told = view.keep<ScoreTold>(TOLD, () => ({ tick: -Infinity, version: -1, lineVersion: -1, final: false }))\n\t// asked again within a tick (the score's part, then its line's), it tells the same: nothing new is due\n\tconst final = world.winner !== null || world.failure !== null\n\tconst viewer = view.observer ? undefined : view.player\n\tconst refresh = Math.max(Math.round((counted.rules.refresh ?? 1) * world.tickRate), 1)\n\tconst due = final !== told.final || (world.tick - told.tick >= refresh && world.score.version !== told.version)\n\tif (due) {\n\t\ttold.score = world.score.stateFor(viewer, final)\n\t\ttold.tick = world.tick\n\t\ttold.version = world.score.version\n\t}\n\tif (final !== told.final || world.score.lineVersion !== told.lineVersion) {\n\t\ttold.line = world.score.lineFor(viewer, final)\n\t\ttold.lineVersion = world.score.lineVersion\n\t}\n\ttold.final = final\n\treturn told\n}\n\n/** The score the player is told (`Snapshot.score`) */\nexport const scorePart = snapshotField('score', (view) => scoreTold(view)?.score)\n\n/** The score's line over time the player is told (`Snapshot.scoreLine`) */\nexport const scoreLinePart = snapshotField('scoreLine', (view) => scoreTold(view)?.line)\n"],"mappings":"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"}
|
package/dist/sequences.d.ts
CHANGED
|
@@ -36,14 +36,14 @@ export type Step<D> = Act<D> | Wait | WaitFor<D> | WaitUntil<D>;
|
|
|
36
36
|
/**
|
|
37
37
|
* Waits `seconds` before the next step
|
|
38
38
|
*
|
|
39
|
-
* @
|
|
39
|
+
* @public
|
|
40
40
|
*/
|
|
41
41
|
export declare const wait: (seconds: number) => Wait;
|
|
42
42
|
/**
|
|
43
43
|
* Waits for an event, the engine's (`'constructionFinished'`) or a game's own, and for `test` to pass on what it
|
|
44
44
|
* says when there is one. Heard at the end of the tick, like listeners hear events
|
|
45
45
|
*
|
|
46
|
-
* @
|
|
46
|
+
* @public
|
|
47
47
|
*/
|
|
48
48
|
export declare function waitFor<T, D = any>(event: EventKey<T>, test?: (world: World, payload: T, data: D, run: number) => boolean): WaitFor<D>;
|
|
49
49
|
/**
|
|
@@ -54,7 +54,7 @@ export declare function waitFor<T, D = any>(event: EventKey<T>, test?: (world: W
|
|
|
54
54
|
export declare const waitUntil: <D = any>(test: (world: World, data: D, run: number) => boolean) => WaitUntil<D>;
|
|
55
55
|
/**
|
|
56
56
|
* What a mission or a cutscene is mostly made of: do this, wait two seconds, then that, then wait until the gate
|
|
57
|
-
* holds five invaders. Made with `defineSequence` and given in `
|
|
57
|
+
* holds five invaders. Made with `defineSequence` and given in `Rules.sequences`, so that a save finds the steps
|
|
58
58
|
* by id: what is kept in the world of a running sequence is which one, which step, and its data, never a function.
|
|
59
59
|
* That is why it is not an `async` function: one of those cannot be saved halfway through
|
|
60
60
|
*
|
|
@@ -63,15 +63,19 @@ export declare const waitUntil: <D = any>(test: (world: World, data: D, run: num
|
|
|
63
63
|
export interface SequenceDef<D = any> {
|
|
64
64
|
/** Shared by every game, like other ids: give it a prefix of the game's (`'td.briefing'`) */
|
|
65
65
|
readonly id: string;
|
|
66
|
+
/** The steps in order: functions, waits and wait-fors, run one after the other */
|
|
66
67
|
readonly steps: readonly Step<D>[];
|
|
67
68
|
}
|
|
68
69
|
/**
|
|
69
|
-
* Typed help: `defineSequence<{ hero: number }>('td.briefing', [(world) => ..., wait(3), waitFor(constructionFinished)])`.
|
|
70
|
+
* Typed help: `defineSequence<{ hero: number }>({ id: 'td.briefing', steps: [(world) => ..., wait(3), waitFor(constructionFinished)] })`.
|
|
70
71
|
* A helper that is several steps (`talk`, `cinematic(id, { wait })`) may be given as its list, spread or not
|
|
71
72
|
*
|
|
72
|
-
* @
|
|
73
|
+
* @public
|
|
73
74
|
*/
|
|
74
|
-
export declare function defineSequence<D = undefined>(
|
|
75
|
+
export declare function defineSequence<D = undefined>(def: {
|
|
76
|
+
id: string;
|
|
77
|
+
steps: (Step<D> | readonly Step<D>[])[];
|
|
78
|
+
}): SequenceDef<D>;
|
|
75
79
|
/** A sequence as it runs in the world. Plain data: it goes into a save */
|
|
76
80
|
interface Running {
|
|
77
81
|
id: number;
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import { defineComponent } from "./components.js";
|
|
2
|
+
import { defineListener } from "./events.js";
|
|
3
|
+
import { assertPlainData } from "./debug2.js";
|
|
4
|
+
import { defineTimer } from "./timers.js";
|
|
5
|
+
//#region src/sequences.ts
|
|
6
|
+
/**
|
|
7
|
+
* Waits `seconds` before the next step
|
|
8
|
+
*
|
|
9
|
+
* @public
|
|
10
|
+
*/
|
|
11
|
+
var wait = (seconds) => ({
|
|
12
|
+
kind: "wait",
|
|
13
|
+
seconds
|
|
14
|
+
});
|
|
15
|
+
/**
|
|
16
|
+
* Waits for an event, the engine's (`'constructionFinished'`) or a game's own, and for `test` to pass on what it
|
|
17
|
+
* says when there is one. Heard at the end of the tick, like listeners hear events
|
|
18
|
+
*
|
|
19
|
+
* @public
|
|
20
|
+
*/
|
|
21
|
+
function waitFor(event, test) {
|
|
22
|
+
return {
|
|
23
|
+
kind: "waitFor",
|
|
24
|
+
event,
|
|
25
|
+
passes: test
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Waits until `test` holds: asked at the end of every tick
|
|
30
|
+
*
|
|
31
|
+
* @beta
|
|
32
|
+
*/
|
|
33
|
+
var waitUntil = (test) => ({
|
|
34
|
+
kind: "waitUntil",
|
|
35
|
+
test
|
|
36
|
+
});
|
|
37
|
+
/**
|
|
38
|
+
* Typed help: `defineSequence<{ hero: number }>({ id: 'td.briefing', steps: [(world) => ..., wait(3), waitFor(constructionFinished)] })`.
|
|
39
|
+
* A helper that is several steps (`talk`, `cinematic(id, { wait })`) may be given as its list, spread or not
|
|
40
|
+
*
|
|
41
|
+
* @public
|
|
42
|
+
*/
|
|
43
|
+
function defineSequence(def) {
|
|
44
|
+
return {
|
|
45
|
+
id: def.id,
|
|
46
|
+
steps: def.steps.flat()
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
var running = defineComponent({
|
|
50
|
+
id: "core.sequences",
|
|
51
|
+
default: () => ({
|
|
52
|
+
next: 1,
|
|
53
|
+
list: []
|
|
54
|
+
})
|
|
55
|
+
});
|
|
56
|
+
/** The sequences running in the state of a save, by the id of their definition: what a game must still have to load it */
|
|
57
|
+
var runningSequences = (state) => (state[running.id]?.list ?? []).map((run) => run.sequence);
|
|
58
|
+
/** Takes a sequence that waited out its seconds on to its next step */
|
|
59
|
+
var resume = defineTimer({
|
|
60
|
+
id: "core.sequenceResume",
|
|
61
|
+
run: (world, { run }) => world.sequences.resume(run)
|
|
62
|
+
});
|
|
63
|
+
/** The engine's timers, which every world has next to its game's */
|
|
64
|
+
var coreTimers = [resume];
|
|
65
|
+
/**
|
|
66
|
+
* The sequences of a world
|
|
67
|
+
*
|
|
68
|
+
* @beta
|
|
69
|
+
*/
|
|
70
|
+
var Sequences = class {
|
|
71
|
+
world;
|
|
72
|
+
defs = /* @__PURE__ */ new Map();
|
|
73
|
+
constructor(world, defs) {
|
|
74
|
+
this.world = world;
|
|
75
|
+
for (const def of defs) {
|
|
76
|
+
if (this.defs.has(def.id)) throw new Error(`Sequence "${def.id}" is there twice`);
|
|
77
|
+
this.defs.set(def.id, def);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Listeners for the events the sequences of a game wait for, one for each event: the world subscribes them with
|
|
82
|
+
* the game's own
|
|
83
|
+
*/
|
|
84
|
+
static listenersFor(defs) {
|
|
85
|
+
const events = /* @__PURE__ */ new Map();
|
|
86
|
+
for (const def of defs) for (const step of def.steps) {
|
|
87
|
+
if (typeof step === "function" || step.kind !== "waitFor") continue;
|
|
88
|
+
events.set(step.event.id, step.event);
|
|
89
|
+
}
|
|
90
|
+
return [...events].map(([id, event]) => defineListener({
|
|
91
|
+
id: `core.sequences:${id}`,
|
|
92
|
+
event,
|
|
93
|
+
run: (world, payload) => world.sequences.heard(id, payload)
|
|
94
|
+
}));
|
|
95
|
+
}
|
|
96
|
+
/** Starts a sequence: its first steps run at once, up to the first that waits. Returns its id, for `stop` */
|
|
97
|
+
start(sequence, ...data) {
|
|
98
|
+
if (!this.defs.has(sequence.id)) throw new Error(`Sequence "${sequence.id}" is not the game's: give it in Rules.sequences, so that a save can find it`);
|
|
99
|
+
if (this.world.checks.events) assertPlainData(data[0], `Sequence "${sequence.id}"`);
|
|
100
|
+
const state = this.state();
|
|
101
|
+
const run = {
|
|
102
|
+
id: state.next++,
|
|
103
|
+
sequence: sequence.id,
|
|
104
|
+
step: 0,
|
|
105
|
+
data: data[0]
|
|
106
|
+
};
|
|
107
|
+
state.list.push(run);
|
|
108
|
+
this.advance(run);
|
|
109
|
+
return run.id;
|
|
110
|
+
}
|
|
111
|
+
/** Stops a sequence where it is. Whether it was running */
|
|
112
|
+
stop(id) {
|
|
113
|
+
const { list } = this.state();
|
|
114
|
+
const index = list.findIndex((run) => run.id === id);
|
|
115
|
+
if (index < 0) return false;
|
|
116
|
+
const [run] = list.splice(index, 1);
|
|
117
|
+
if (run.timer !== void 0) this.world.timers.cancel(run.timer);
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
/** Whether a sequence is still running */
|
|
121
|
+
running(id) {
|
|
122
|
+
return this.state().list.some((run) => run.id === id);
|
|
123
|
+
}
|
|
124
|
+
/** Cuts the `wait` a sequence is on short, and takes it on at once: a line of dialog skipped. Whether it was waiting */
|
|
125
|
+
hurry(id) {
|
|
126
|
+
const run = this.state().list.find((candidate) => candidate.id === id);
|
|
127
|
+
if (run?.timer === void 0) return false;
|
|
128
|
+
this.world.timers.cancel(run.timer);
|
|
129
|
+
this.resume(id);
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
/** Takes a sequence whose `wait` is over on. For the engine's timer */
|
|
133
|
+
resume(id) {
|
|
134
|
+
const run = this.state().list.find((candidate) => candidate.id === id);
|
|
135
|
+
if (!run) return;
|
|
136
|
+
run.timer = void 0;
|
|
137
|
+
run.step++;
|
|
138
|
+
this.advance(run);
|
|
139
|
+
}
|
|
140
|
+
/** An event that sequences may wait for went off. For the engine's listeners */
|
|
141
|
+
heard(event, payload) {
|
|
142
|
+
for (const run of [...this.state().list]) {
|
|
143
|
+
const step = this.stepOf(run);
|
|
144
|
+
if (typeof step === "function" || step?.kind !== "waitFor") continue;
|
|
145
|
+
if (step.event.id !== event) continue;
|
|
146
|
+
if (step.passes && !step.passes(this.world, payload, run.data, run.id)) continue;
|
|
147
|
+
run.step++;
|
|
148
|
+
this.advance(run);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
/** Asks the sequences waiting until something holds whether it does. The `sequences` system does, every tick */
|
|
152
|
+
update() {
|
|
153
|
+
for (const run of [...this.state().list]) {
|
|
154
|
+
const step = this.stepOf(run);
|
|
155
|
+
if (typeof step === "function" || step?.kind !== "waitUntil" || !step.test(this.world, run.data, run.id)) continue;
|
|
156
|
+
run.step++;
|
|
157
|
+
this.advance(run);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
/** Runs the steps from where the sequence is, up to the next one that waits, or the end */
|
|
161
|
+
advance(run) {
|
|
162
|
+
const def = this.defOf(run);
|
|
163
|
+
while (run.step < def.steps.length) {
|
|
164
|
+
if (!this.running(run.id)) return;
|
|
165
|
+
const step = def.steps[run.step];
|
|
166
|
+
if (typeof step === "function") {
|
|
167
|
+
step(this.world, run.data, run.id);
|
|
168
|
+
run.step++;
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
if (step.kind === "wait") {
|
|
172
|
+
run.timer = this.world.timers.after(step.seconds, resume, { run: run.id });
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
if (step.kind === "waitUntil" && step.test(this.world, run.data, run.id)) {
|
|
176
|
+
run.step++;
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
this.stop(run.id);
|
|
182
|
+
}
|
|
183
|
+
stepOf(run) {
|
|
184
|
+
return this.defOf(run).steps[run.step];
|
|
185
|
+
}
|
|
186
|
+
defOf(run) {
|
|
187
|
+
const def = this.defs.get(run.sequence);
|
|
188
|
+
if (!def) throw new Error(`Sequence "${run.sequence}" is running, and the game has no such sequence: give it in Rules.sequences`);
|
|
189
|
+
return def;
|
|
190
|
+
}
|
|
191
|
+
state() {
|
|
192
|
+
return this.world.state(running);
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
/** Asks the sequences that wait until something holds, at the end of every tick */
|
|
196
|
+
var sequenceSystem = {
|
|
197
|
+
name: "sequences",
|
|
198
|
+
phase: "cleanup",
|
|
199
|
+
update(world) {
|
|
200
|
+
world.sequences.update();
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
//#endregion
|
|
204
|
+
export { Sequences, coreTimers, defineSequence, running, runningSequences, sequenceSystem, wait, waitFor, waitUntil };
|
|
205
|
+
|
|
206
|
+
//# sourceMappingURL=sequences.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sequences.js","names":[],"sources":["../src/sequences.ts"],"sourcesContent":["import { defineComponent } from './components'\nimport { assertPlainData } from './debug'\nimport { type EventKey, type ListenerDef, defineListener } from './events'\nimport type { System } from './registry'\nimport { defineTimer, type TimerDef } from './timers'\nimport type { World } from './world'\n\n/** An event a step can wait for: one of the engine's by name, or a game's own */\ntype AnyEvent = EventKey<any>\n\n/** Doing something: runs, and the sequence goes on to the next step at once. `run` is the id of the sequence running it */\ntype Act<D> = (world: World, data: D, run: number) => void\n\n/** Waiting a number of seconds */\ninterface Wait {\n\tkind: 'wait'\n\tseconds: number\n}\n\n/** Waiting for an event, and for what it says to pass a test when there is one */\ninterface WaitFor<D> {\n\tkind: 'waitFor'\n\tevent: AnyEvent\n\t/**\n\t * `run` is the id of the sequence waiting, as an `Act` has it. Not called `test`, as `WaitUntil`'s is: a step's type\n\t * would be inferred from the other's then (`waitFor` in a sequence of data had its data typed `never`)\n\t */\n\tpasses?: (world: World, payload: any, data: D, run: number) => boolean\n}\n\n/** Waiting until something holds. Asked every tick, so keep it cheap */\ninterface WaitUntil<D> {\n\tkind: 'waitUntil'\n\t/** `run` is the id of the sequence waiting, as an `Act` has it */\n\ttest: (world: World, data: D, run: number) => boolean\n}\n\n/**\n * One step of a sequence\n *\n * @beta\n */\nexport type Step<D> = Act<D> | Wait | WaitFor<D> | WaitUntil<D>\n\n/**\n * Waits `seconds` before the next step\n *\n * @public\n */\nexport const wait = (seconds: number): Wait => ({ kind: 'wait', seconds })\n\n/**\n * Waits for an event, the engine's (`'constructionFinished'`) or a game's own, and for `test` to pass on what it\n * says when there is one. Heard at the end of the tick, like listeners hear events\n *\n * @public\n */\nexport function waitFor<T, D = any>(event: EventKey<T>, test?: (world: World, payload: T, data: D, run: number) => boolean): WaitFor<D> {\n\treturn { kind: 'waitFor', event, passes: test }\n}\n\n/**\n * Waits until `test` holds: asked at the end of every tick\n *\n * @beta\n */\nexport const waitUntil = <D = any>(test: (world: World, data: D, run: number) => boolean): WaitUntil<D> => ({ kind: 'waitUntil', test })\n\n/**\n * What a mission or a cutscene is mostly made of: do this, wait two seconds, then that, then wait until the gate\n * holds five invaders. Made with `defineSequence` and given in `Rules.sequences`, so that a save finds the steps\n * by id: what is kept in the world of a running sequence is which one, which step, and its data, never a function.\n * That is why it is not an `async` function: one of those cannot be saved halfway through\n *\n * @beta\n */\nexport interface SequenceDef<D = any> {\n\t/** Shared by every game, like other ids: give it a prefix of the game's (`'td.briefing'`) */\n\treadonly id: string\n\t/** The steps in order: functions, waits and wait-fors, run one after the other */\n\treadonly steps: readonly Step<D>[]\n}\n\n/**\n * Typed help: `defineSequence<{ hero: number }>({ id: 'td.briefing', steps: [(world) => ..., wait(3), waitFor(constructionFinished)] })`.\n * A helper that is several steps (`talk`, `cinematic(id, { wait })`) may be given as its list, spread or not\n *\n * @public\n */\nexport function defineSequence<D = undefined>(def: { id: string; steps: (Step<D> | readonly Step<D>[])[] }): SequenceDef<D> {\n\treturn { id: def.id, steps: def.steps.flat() as Step<D>[] }\n}\n\n/** A sequence as it runs in the world. Plain data: it goes into a save */\ninterface Running {\n\tid: number\n\tsequence: string\n\t/** The step it is at: the one it waits on, while it waits */\n\tstep: number\n\tdata: unknown\n\t/** The timer it waits for, on a `wait` step */\n\ttimer?: number\n}\n\nexport const running = defineComponent<{ next: number; list: Running[] }>({ id: 'core.sequences', default: () => ({ next: 1, list: [] }) })\n\n/** The sequences running in the state of a save, by the id of their definition: what a game must still have to load it */\nexport const runningSequences = (state: Record<string, unknown>): string[] =>\n\t((state[running.id] as { list?: Running[] } | undefined)?.list ?? []).map((run) => run.sequence)\n\n/** Takes a sequence that waited out its seconds on to its next step */\nconst resume = defineTimer<{ run: number }>({ id: 'core.sequenceResume', run: (world, { run }) => world.sequences.resume(run) })\n\n/** The engine's timers, which every world has next to its game's */\nexport const coreTimers: TimerDef[] = [resume]\n\n/**\n * The sequences of a world\n *\n * @beta\n */\nexport class Sequences {\n\tprivate readonly defs = new Map<string, SequenceDef>()\n\n\tconstructor(\n\t\tprivate readonly world: World,\n\t\tdefs: readonly SequenceDef[]\n\t) {\n\t\tfor (const def of defs) {\n\t\t\tif (this.defs.has(def.id)) throw new Error(`Sequence \"${def.id}\" is there twice`)\n\t\t\tthis.defs.set(def.id, def)\n\t\t}\n\t}\n\n\t/**\n\t * Listeners for the events the sequences of a game wait for, one for each event: the world subscribes them with\n\t * the game's own\n\t */\n\tstatic listenersFor(defs: readonly SequenceDef[]): ListenerDef[] {\n\t\tconst events = new Map<string, AnyEvent>()\n\t\tfor (const def of defs) {\n\t\t\tfor (const step of def.steps) {\n\t\t\t\tif (typeof step === 'function' || step.kind !== 'waitFor') continue\n\t\t\t\tevents.set(step.event.id, step.event)\n\t\t\t}\n\t\t}\n\t\treturn [...events].map(([id, event]) =>\n\t\t\tdefineListener({ id: `core.sequences:${id}`, event, run: (world, payload) => world.sequences.heard(id, payload) })\n\t\t)\n\t}\n\n\t/** Starts a sequence: its first steps run at once, up to the first that waits. Returns its id, for `stop` */\n\tstart<D>(sequence: SequenceDef<D>, ...data: D extends undefined ? [] : [D]): number {\n\t\tif (!this.defs.has(sequence.id))\n\t\t\tthrow new Error(`Sequence \"${sequence.id}\" is not the game's: give it in Rules.sequences, so that a save can find it`)\n\t\tif (this.world.checks.events) assertPlainData(data[0], `Sequence \"${sequence.id}\"`)\n\t\tconst state = this.state()\n\t\tconst run: Running = { id: state.next++, sequence: sequence.id, step: 0, data: data[0] }\n\t\tstate.list.push(run)\n\t\tthis.advance(run)\n\t\treturn run.id\n\t}\n\n\t/** Stops a sequence where it is. Whether it was running */\n\tstop(id: number): boolean {\n\t\tconst { list } = this.state()\n\t\tconst index = list.findIndex((run) => run.id === id)\n\t\tif (index < 0) return false\n\t\tconst [run] = list.splice(index, 1)\n\t\tif (run.timer !== undefined) this.world.timers.cancel(run.timer)\n\t\treturn true\n\t}\n\n\t/** Whether a sequence is still running */\n\trunning(id: number): boolean {\n\t\treturn this.state().list.some((run) => run.id === id)\n\t}\n\n\t/** Cuts the `wait` a sequence is on short, and takes it on at once: a line of dialog skipped. Whether it was waiting */\n\thurry(id: number): boolean {\n\t\tconst run = this.state().list.find((candidate) => candidate.id === id)\n\t\tif (run?.timer === undefined) return false\n\t\tthis.world.timers.cancel(run.timer)\n\t\tthis.resume(id)\n\t\treturn true\n\t}\n\n\t/** Takes a sequence whose `wait` is over on. For the engine's timer */\n\tresume(id: number): void {\n\t\tconst run = this.state().list.find((candidate) => candidate.id === id)\n\t\tif (!run) return\n\t\trun.timer = undefined\n\t\trun.step++\n\t\tthis.advance(run)\n\t}\n\n\t/** An event that sequences may wait for went off. For the engine's listeners */\n\theard(event: string, payload: unknown): void {\n\t\tfor (const run of [...this.state().list]) {\n\t\t\tconst step = this.stepOf(run)\n\t\t\tif (typeof step === 'function' || step?.kind !== 'waitFor') continue\n\t\t\tif (step.event.id !== event) continue\n\t\t\tif (step.passes && !step.passes(this.world, payload, run.data, run.id)) continue\n\t\t\trun.step++\n\t\t\tthis.advance(run)\n\t\t}\n\t}\n\n\t/** Asks the sequences waiting until something holds whether it does. The `sequences` system does, every tick */\n\tupdate(): void {\n\t\tfor (const run of [...this.state().list]) {\n\t\t\tconst step = this.stepOf(run)\n\t\t\tif (typeof step === 'function' || step?.kind !== 'waitUntil' || !step.test(this.world, run.data, run.id)) continue\n\t\t\trun.step++\n\t\t\tthis.advance(run)\n\t\t}\n\t}\n\n\t/** Runs the steps from where the sequence is, up to the next one that waits, or the end */\n\tprivate advance(run: Running): void {\n\t\tconst def = this.defOf(run)\n\t\twhile (run.step < def.steps.length) {\n\t\t\tif (!this.running(run.id)) return\n\t\t\tconst step = def.steps[run.step]\n\t\t\tif (typeof step === 'function') {\n\t\t\t\tstep(this.world, run.data, run.id)\n\t\t\t\trun.step++\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (step.kind === 'wait') {\n\t\t\t\trun.timer = this.world.timers.after(step.seconds, resume, { run: run.id })\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (step.kind === 'waitUntil' && step.test(this.world, run.data, run.id)) {\n\t\t\t\trun.step++\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t// waiting: for an event, or until something holds\n\t\t\treturn\n\t\t}\n\t\tthis.stop(run.id)\n\t}\n\n\tprivate stepOf(run: Running): Step<unknown> | undefined {\n\t\treturn this.defOf(run).steps[run.step]\n\t}\n\n\tprivate defOf(run: Running): SequenceDef {\n\t\tconst def = this.defs.get(run.sequence)\n\t\tif (!def) throw new Error(`Sequence \"${run.sequence}\" is running, and the game has no such sequence: give it in Rules.sequences`)\n\t\treturn def\n\t}\n\n\tprivate state() {\n\t\treturn this.world.state(running)\n\t}\n}\n\n/** Asks the sequences that wait until something holds, at the end of every tick */\nexport const sequenceSystem: System = {\n\tname: 'sequences',\n\tphase: 'cleanup',\n\tupdate(world) {\n\t\tworld.sequences.update()\n\t}\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { errorFields } from "../log.js";
|
|
2
|
+
import "../session/protocol.js";
|
|
3
|
+
import { ratedId } from "./ratings.js";
|
|
4
|
+
import { sameSecret } from "./secret.js";
|
|
5
|
+
//#region src/server/doorman.ts
|
|
6
|
+
/**
|
|
7
|
+
* Where one who joins a server's game goes (`Doorman`): their seat again, a free seat, a seat the game decides
|
|
8
|
+
* (`GameServerOptions.seat`), watching, or away with why (design review E12). It decides and says so; the server seats,
|
|
9
|
+
* tells and closes
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Decides where each who joins a server goes
|
|
13
|
+
*
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
16
|
+
var Doorman = class {
|
|
17
|
+
server;
|
|
18
|
+
constructor(server) {
|
|
19
|
+
this.server = server;
|
|
20
|
+
}
|
|
21
|
+
/** Why one who joins speaks another version of the wire, or nothing: told before any seat is taken or welcome sent that it would misread */
|
|
22
|
+
wrongWire(join) {
|
|
23
|
+
if (join.protocol === void 0 || join.protocol === 13) return void 0;
|
|
24
|
+
return `this server runs another version of the engine (protocol 13, yours is ${join.protocol}): update the game`;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Where one who joins from `address` goes: decided now, or once the game said (`GameServerOptions.seat`), a promise
|
|
28
|
+
* then. Their wire is the server's (`wrongWire`)
|
|
29
|
+
*/
|
|
30
|
+
place(join, address) {
|
|
31
|
+
const { server } = this;
|
|
32
|
+
const theirs = join.token ? server.seats.find((each) => each.token === join.token) : void 0;
|
|
33
|
+
if (theirs) return {
|
|
34
|
+
to: "seat",
|
|
35
|
+
seat: theirs,
|
|
36
|
+
name: join.name
|
|
37
|
+
};
|
|
38
|
+
if (server.draining) return {
|
|
39
|
+
to: "refuse",
|
|
40
|
+
reason: "the server is stopping"
|
|
41
|
+
};
|
|
42
|
+
if (join.back) return {
|
|
43
|
+
to: "refuse",
|
|
44
|
+
reason: "the game you were in is over"
|
|
45
|
+
};
|
|
46
|
+
if (server.options.seat && !join.watch) return this.asked(join, address);
|
|
47
|
+
const free = !join.watch && server.phase === "lobby" ? server.seats.find((each) => !each.ai && !each.connected) : void 0;
|
|
48
|
+
if (!free) return this.noSeat(join, address);
|
|
49
|
+
return {
|
|
50
|
+
to: "seat",
|
|
51
|
+
seat: free,
|
|
52
|
+
name: join.name,
|
|
53
|
+
rated: join.who ? ratedId(join.who) : void 0
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/** Where the game says one who joins sits (`seat`), checked as it answered: a seat may have been taken meanwhile */
|
|
57
|
+
async asked(join, address) {
|
|
58
|
+
const { server } = this;
|
|
59
|
+
let answer;
|
|
60
|
+
try {
|
|
61
|
+
answer = await server.options.seat({
|
|
62
|
+
address,
|
|
63
|
+
name: join.name,
|
|
64
|
+
ticket: join.ticket,
|
|
65
|
+
free: server.seats.filter((seat) => seat.isFree).map((seat) => server.publicSeat(seat)),
|
|
66
|
+
phase: server.phase
|
|
67
|
+
});
|
|
68
|
+
} catch (error) {
|
|
69
|
+
server.logger.error("server", "deciding a seat threw: they are refused", {
|
|
70
|
+
error: errorFields(error),
|
|
71
|
+
name: join.name
|
|
72
|
+
});
|
|
73
|
+
return {
|
|
74
|
+
to: "refuse",
|
|
75
|
+
reason: "the server could not seat you"
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
if (!answer || typeof answer !== "object") return {
|
|
79
|
+
to: "refuse",
|
|
80
|
+
reason: "the server could not seat you"
|
|
81
|
+
};
|
|
82
|
+
if ("refuse" in answer) return {
|
|
83
|
+
to: "refuse",
|
|
84
|
+
reason: String(answer.refuse)
|
|
85
|
+
};
|
|
86
|
+
return this.answered(join, answer, address);
|
|
87
|
+
}
|
|
88
|
+
/** The game's answer, checked against the seats as they are now */
|
|
89
|
+
answered(join, answer, address) {
|
|
90
|
+
const { server } = this;
|
|
91
|
+
const { player, id } = answer;
|
|
92
|
+
let seat;
|
|
93
|
+
if (player === void 0) seat = server.phase === "lobby" ? server.seats.find((each) => each.isFree) : void 0;
|
|
94
|
+
else {
|
|
95
|
+
seat = server.seats.find((each) => each.player === player);
|
|
96
|
+
if (!seat) return {
|
|
97
|
+
to: "refuse",
|
|
98
|
+
reason: `there is no seat ${player}`
|
|
99
|
+
};
|
|
100
|
+
if (seat.ai) return {
|
|
101
|
+
to: "refuse",
|
|
102
|
+
reason: "that seat is the computer's"
|
|
103
|
+
};
|
|
104
|
+
if (!seat.isFree && (id === void 0 || seat.id !== id)) return {
|
|
105
|
+
to: "refuse",
|
|
106
|
+
reason: "that seat is taken"
|
|
107
|
+
};
|
|
108
|
+
if (seat.isFree && server.phase !== "lobby") return {
|
|
109
|
+
to: "refuse",
|
|
110
|
+
reason: "the game has started"
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
if (!seat) return this.noSeat(join, address);
|
|
114
|
+
const rate = answer.rate || join.who || id;
|
|
115
|
+
return {
|
|
116
|
+
to: "seat",
|
|
117
|
+
seat,
|
|
118
|
+
name: answer.name ?? join.name,
|
|
119
|
+
named: answer.name !== void 0,
|
|
120
|
+
id,
|
|
121
|
+
rated: rate !== void 0 ? ratedId(rate) : void 0
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
/** No seat for who joined: they watch, if they may, or are told so */
|
|
125
|
+
noSeat(join, address) {
|
|
126
|
+
const { phase } = this.server;
|
|
127
|
+
if (phase === "lobby" && !join.watch) return { to: "full" };
|
|
128
|
+
if (this.mayWatch(join, address)) return { to: "watch" };
|
|
129
|
+
if (phase === "lobby") return { to: "full" };
|
|
130
|
+
return {
|
|
131
|
+
to: "refuse",
|
|
132
|
+
reason: "watching is not open"
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
/** Whether who asks may watch, as the server was told (`watch`) */
|
|
136
|
+
mayWatch(join, address) {
|
|
137
|
+
const { watch } = this.server.options;
|
|
138
|
+
if (!watch) return false;
|
|
139
|
+
if (watch === true) return true;
|
|
140
|
+
if (typeof watch === "object") return join.key !== void 0 && sameSecret(join.key, watch.key);
|
|
141
|
+
const seated = this.server.seats.some((seat) => seat.connected && seat.connection?.address === address);
|
|
142
|
+
return watch({
|
|
143
|
+
address,
|
|
144
|
+
name: join.name,
|
|
145
|
+
key: join.key,
|
|
146
|
+
seated,
|
|
147
|
+
phase: this.server.phase
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
//#endregion
|
|
152
|
+
export { Doorman };
|
|
153
|
+
|
|
154
|
+
//# sourceMappingURL=doorman.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doorman.js","names":[],"sources":["../../src/server/doorman.ts"],"sourcesContent":["/**\n * Where one who joins a server's game goes (`Doorman`): their seat again, a free seat, a seat the game decides\n * (`GameServerOptions.seat`), watching, or away with why (design review E12). It decides and says so; the server seats,\n * tells and closes\n */\nimport { errorFields, type Logger } from '#engine/log'\nimport type { ServerSeat } from '#engine/game'\nimport { PROTOCOL_VERSION } from '#engine/session/protocol'\nimport type { LobbyPlayerMessage } from '../session/wire'\nimport type { GameServerOptions, SeatAnswer } from './gameServer'\nimport { ratedId } from './ratings'\nimport type { Seat } from './seat'\nimport { sameSecret } from './secret'\n\n/** A join, its fields checked */\nexport type Join = Extract<LobbyPlayerMessage, { type: 'join' }>\n\n/**\n * Where one who joins goes\n *\n * @internal\n */\nexport type Door =\n\t/**\n\t * A seat: theirs again, a free one, or the game's choice. `id` and `rated`, where there (even as nothing), are who\n\t * holds it and what they are rated as, set as they sit; left out, the seat keeps its own (theirs again)\n\t */\n\t| { to: 'seat'; seat: Seat; name?: string; named?: boolean; id?: string; rated?: string }\n\t/** Watching: every seat is taken, and they may */\n\t| { to: 'watch' }\n\t/** Every seat is taken in the lobby, and they may not watch: they stay connected, and are told */\n\t| { to: 'full' }\n\t/** Away, told why: their connection closed */\n\t| { to: 'refuse'; reason: string }\n\n/** What the doorman reads of the server it keeps the door of */\nexport interface DoorContext {\n\treadonly phase: 'lobby' | 'game' | 'ended'\n\treadonly seats: readonly Seat[]\n\treadonly draining: boolean\n\treadonly options: Pick<GameServerOptions, 'seat' | 'watch'>\n\treadonly logger: Logger\n\tpublicSeat(seat: Seat): ServerSeat\n}\n\n/**\n * Decides where each who joins a server goes\n *\n * @internal\n */\nexport class Doorman {\n\tconstructor(private readonly server: DoorContext) {}\n\n\t/** Why one who joins speaks another version of the wire, or nothing: told before any seat is taken or welcome sent that it would misread */\n\twrongWire(join: Join): string | undefined {\n\t\tif (join.protocol === undefined || join.protocol === PROTOCOL_VERSION) return undefined\n\t\treturn `this server runs another version of the engine (protocol ${PROTOCOL_VERSION}, yours is ${join.protocol}): update the game`\n\t}\n\n\t/**\n\t * Where one who joins from `address` goes: decided now, or once the game said (`GameServerOptions.seat`), a promise\n\t * then. Their wire is the server's (`wrongWire`)\n\t */\n\tplace(join: Join, address: string): Door | Promise<Door> {\n\t\tconst { server } = this\n\t\t// back to the seat one had\n\t\tconst theirs = join.token ? server.seats.find((each) => each.token === join.token) : undefined\n\t\tif (theirs) return { to: 'seat', seat: theirs, name: join.name }\n\t\t// stopping: those of the game may come back to it, nobody new comes\n\t\tif (server.draining) return { to: 'refuse', reason: 'the server is stopping' }\n\t\t// coming back to a game that is no more (it ended and everyone left, or they were let go): not a new seat\n\t\tif (join.back) return { to: 'refuse', reason: 'the game you were in is over' }\n\t\tif (server.options.seat && !join.watch) return this.asked(join, address)\n\t\tconst free = !join.watch && server.phase === 'lobby' ? server.seats.find((each) => !each.ai && !each.connected) : undefined\n\t\tif (!free) return this.noSeat(join, address)\n\t\treturn { to: 'seat', seat: free, name: join.name, rated: join.who ? ratedId(join.who) : undefined }\n\t}\n\n\t/** Where the game says one who joins sits (`seat`), checked as it answered: a seat may have been taken meanwhile */\n\tprivate async asked(join: Join, address: string): Promise<Door> {\n\t\tconst { server } = this\n\t\tlet answer: SeatAnswer\n\t\ttry {\n\t\t\tanswer = await server.options.seat!({\n\t\t\t\taddress,\n\t\t\t\tname: join.name,\n\t\t\t\tticket: join.ticket,\n\t\t\t\tfree: server.seats.filter((seat) => seat.isFree).map((seat) => server.publicSeat(seat)),\n\t\t\t\tphase: server.phase\n\t\t\t})\n\t\t} catch (error) {\n\t\t\tserver.logger.error('server', 'deciding a seat threw: they are refused', { error: errorFields(error), name: join.name })\n\t\t\treturn { to: 'refuse', reason: 'the server could not seat you' }\n\t\t}\n\t\tif (!answer || typeof answer !== 'object') return { to: 'refuse', reason: 'the server could not seat you' }\n\t\tif ('refuse' in answer) return { to: 'refuse', reason: String(answer.refuse) }\n\t\treturn this.answered(join, answer, address)\n\t}\n\n\t/** The game's answer, checked against the seats as they are now */\n\tanswered(join: Join, answer: Exclude<SeatAnswer, { refuse: string }>, address: string): Door {\n\t\tconst { server } = this\n\t\tconst { player, id } = answer\n\t\tlet seat: Seat | undefined\n\t\tif (player === undefined) seat = server.phase === 'lobby' ? server.seats.find((each) => each.isFree) : undefined\n\t\telse {\n\t\t\tseat = server.seats.find((each) => each.player === player)\n\t\t\tif (!seat) return { to: 'refuse', reason: `there is no seat ${player}` }\n\t\t\tif (seat.ai) return { to: 'refuse', reason: \"that seat is the computer's\" }\n\t\t\t// held by another, or by nobody the game knows: not theirs to take\n\t\t\tif (!seat.isFree && (id === undefined || seat.id !== id)) return { to: 'refuse', reason: 'that seat is taken' }\n\t\t\tif (seat.isFree && server.phase !== 'lobby') return { to: 'refuse', reason: 'the game has started' }\n\t\t}\n\t\tif (!seat) return this.noSeat(join, address)\n\t\tconst rate = answer.rate || join.who || id\n\t\treturn {\n\t\t\tto: 'seat',\n\t\t\tseat,\n\t\t\tname: answer.name ?? join.name,\n\t\t\tnamed: answer.name !== undefined,\n\t\t\tid,\n\t\t\trated: rate !== undefined ? ratedId(rate) : undefined\n\t\t}\n\t}\n\n\t/** No seat for who joined: they watch, if they may, or are told so */\n\tprivate noSeat(join: Join, address: string): Door {\n\t\tconst { phase } = this.server\n\t\tif (phase === 'lobby' && !join.watch) return { to: 'full' }\n\t\tif (this.mayWatch(join, address)) return { to: 'watch' }\n\t\tif (phase === 'lobby') return { to: 'full' }\n\t\t// a game on, with no seat for them and nothing to watch\n\t\treturn { to: 'refuse', reason: 'watching is not open' }\n\t}\n\n\t/** Whether who asks may watch, as the server was told (`watch`) */\n\tprivate mayWatch(join: Join, address: string): boolean {\n\t\tconst { watch } = this.server.options\n\t\tif (!watch) return false\n\t\tif (watch === true) return true\n\t\tif (typeof watch === 'object') return join.key !== undefined && sameSecret(join.key, watch.key)\n\t\tconst seated = this.server.seats.some((seat) => seat.connected && seat.connection?.address === address)\n\t\treturn watch({ address, name: join.name, key: join.key, seated, phase: this.server.phase })\n\t}\n}\n"],"mappings":"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"}
|