@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":"production.js","names":[],"sources":["../../src/systems/production.ts"],"sourcesContent":["import { morphStarted, researchFinished, unitTrained } from '#engine/engineEvents'\nimport { gathering } from '#engine/orders/harvest'\nimport type { Entity } from '#engine/entity'\nimport { heroesOf, heroState, reviveCost, reviveHero } from '#engine/hero'\nimport { closestPointOnRect, type Vec2 } from '#engine/math'\nimport { createOrder, giveOrder } from '#engine/orders/queue'\nimport { morph, techOf, unlocked } from '#engine/tech'\nimport { type PlayerFacts, trainRefusal } from '#engine/shared'\nimport { type Cost, supplyPoolsOf, upgradesOf } from '#engine/defs'\nimport type { ProductionKind } from '#engine/hooks'\nimport { shortOf, spend } from '#engine/player'\nimport type { System } from '#engine/registry'\nimport type { World } from '#engine/world'\nimport { engineMessage } from '#engine/messages'\nimport { atan2 } from '#engine/exactMath'\nimport { giveBack, productionOf, productionQueue } from './productionQueue'\nimport { deposit } from '../entity'\nimport { replicateEvent } from '../replication'\n\nfunction hasRoom(world: World, building: Entity): boolean {\n\tif (productionOf(building)!.queue.length < world.settings.production.queue) return true\n\tworld.message(building.owner, engineMessage('queueFull'))\n\treturn false\n}\n\n/**\n * Lets the `beforeProduce` hook have its say about something about to be made, then has the player pay for it.\n * What it ends up costing and how long it takes, or undefined when it is not made (and the player was told why).\n * `producer` is the building it is made in, or the worker putting down a structure\n */\nexport function startProducing(\n\tworld: World,\n\tproducer: Entity,\n\tkind: ProductionKind,\n\tid: string,\n\tcost: Cost | undefined,\n\ttime: number\n): { cost: Cost; time: number } | undefined {\n\tconst player = world.player(producer.owner)\n\tconst event = world.hooks.run('beforeProduce', { player: player.id, producer, kind, id, cost: { ...cost }, time, cancelled: false })\n\tif (event.cancelled) {\n\t\tif (event.reason) world.message(player.id, event.reason)\n\t\treturn undefined\n\t}\n\tconst short = shortOf(player.resources, event.cost)\n\tif (short) {\n\t\tworld.message(player.id, engineMessage('notEnough', { resource: short }))\n\t\treturn undefined\n\t}\n\tspend(world, player.id, event.cost, kind, id)\n\treturn event\n}\n\n/** Queues a unit for training. Returns false (and tells the player why) when that is not possible. */\nexport function enqueueProduction(world: World, building: Entity, unitType: string): boolean {\n\tconst production = productionOf(building)\n\tif (!production || !building.operational || !building.def.trains?.includes(unitType)) return false\n\tconst def = world.registry.unit(unitType)\n\tconst player = world.player(building.owner)\n\tif (!hasRoom(world, building)) return false\n\tif (!unlocked(world, player.id, 'unit', unitType, def.requires)) return false\n\t// the same rule the player's screen goes by (what it requires was asked above, the game's hook with it)\n\tconst refusal = trainRefusal(world.registry, def, playerFacts(world, player.id), { cost: false, tech: false })\n\tif (refusal) {\n\t\tworld.message(player.id, refusal)\n\t\treturn false\n\t}\n\t// what it will take, as the game's rule says of a unit not made yet\n\tconst supply = world.settings.supply.of(world, { def, owner: player.id, queued: true })\n\tconst made = startProducing(world, building, 'unit', unitType, def.cost, def.buildTime ?? 1)\n\tif (!made) return false\n\t// reserve it right away, so several commands in the same tick cannot overshoot the cap\n\tplayer.supplyUsed += supply\n\tconst pools = supplyPoolsOf(def)\n\tfor (const name in pools) if (player.supplies[name]) player.supplies[name].used += pools[name]\n\tproduction.queue.push({ kind: 'unit', id: unitType, paid: made.cost, progress: 0, duration: made.time })\n\treturn true\n}\n\n/**\n * What there is to know about a player for whether they can make something, see `trainRefusal`\n *\n * @beta\n */\nexport function playerFacts(world: World, playerId: number): PlayerFacts {\n\tconst player = world.player(playerId)\n\t// every hero counts: alive, fallen, or in a queue\n\tconst heroes = heroesOf(world, playerId).map((hero) => hero.def.id)\n\tfor (const other of world.index.ownedBy(playerId)) {\n\t\tconst production = productionOf(other)\n\t\tif (!production) continue\n\t\tfor (const item of production.queue) if (item.kind === 'unit' && world.registry.unit(item.id).hero) heroes.push(item.id)\n\t}\n\treturn {\n\t\tresources: player.resources,\n\t\tsupplyUsed: player.supplyUsed,\n\t\tsupplyCap: player.supplyCap,\n\t\t...(Object.keys(player.supplies).length > 0 && { supplies: player.supplies }),\n\t\ttech: techOf(world, playerId),\n\t\theroes,\n\t\t...(player.race !== undefined && { race: player.race })\n\t}\n}\n\n/**\n * Levels of an upgrade a player has, counting the one being researched\n *\n * @beta\n */\nexport function upgradeLevel(world: World, playerId: number, upgrade: string): { level: number; researching: boolean } {\n\tconst player = world.player(playerId)\n\treturn { level: player.upgrades.get(upgrade) ?? 0, researching: player.researching.has(upgrade) }\n}\n\n/** Queues an upgrade. One level at a time, and only in one building at once. */\nexport function enqueueResearch(world: World, building: Entity, upgrade: string): boolean {\n\tconst production = productionOf(building)\n\tif (!production || !building.operational || !building.def.researches?.includes(upgrade)) return false\n\tconst def = world.registry.upgrade(upgrade)\n\tconst player = world.player(building.owner)\n\tconst { level, researching } = upgradeLevel(world, player.id, upgrade)\n\tif (researching) {\n\t\tworld.message(player.id, engineMessage('alreadyResearching'))\n\t\treturn false\n\t}\n\tif (level >= (def.maxLevel ?? 1)) return false\n\tif (!unlocked(world, player.id, 'upgrade', upgrade, def.requires?.[level], level + 1)) return false\n\tif (!hasRoom(world, building)) return false\n\tconst made = startProducing(world, building, 'upgrade', upgrade, def.cost, def.researchTime)\n\tif (!made) return false\n\tplayer.researching.add(upgrade)\n\tproduction.queue.push({ kind: 'upgrade', id: upgrade, paid: made.cost, progress: 0, duration: made.time })\n\treturn true\n}\n\n/** Queues bringing a fallen hero back */\nexport function enqueueRevive(world: World, building: Entity, heroId: number): boolean {\n\tconst production = productionOf(building)\n\tconst hero = world.entities.get(heroId)\n\tif (!production || !building.operational || !building.def.revives) return false\n\tif (!hero?.has(heroState) || hero.alive || hero.owner !== building.owner || hero.reviving) return false\n\tconst { cost, time } = reviveCost(world, hero)\n\tif (!hasRoom(world, building)) return false\n\tconst made = startProducing(world, building, 'revive', String(heroId), cost, time)\n\tif (!made) return false\n\thero.reviving = true\n\tproduction.queue.push({ kind: 'revive', id: String(heroId), paid: made.cost, progress: 0, duration: made.time })\n\treturn true\n}\n\n/**\n * Queues upgrading a building into a type it can become (`UnitTypeDef.upgradesTo`): `into`, one of them, or the first\n * where none is named. One at a time\n */\nexport function enqueueMorph(world: World, building: Entity, into = upgradesOf(building.def)[0]): boolean {\n\tconst production = productionOf(building)\n\tif (!production || !building.operational || into === undefined || !upgradesOf(building.def).includes(into)) return false\n\tif (production.queue.some((item) => item.kind === 'morph')) return false\n\tconst def = world.registry.unit(into)\n\tif (!unlocked(world, building.owner, 'unit', into, def.requires) || !hasRoom(world, building)) return false\n\tconst made = startProducing(world, building, 'morph', into, def.cost, def.buildTime ?? 1)\n\tif (!made) return false\n\tproduction.queue.push({ kind: 'morph', id: into, paid: made.cost, progress: 0, duration: made.time })\n\tworld.events.emit(morphStarted, { entity: building, into, time: made.time })\n\treturn true\n}\n\nexport function cancelProduction(world: World, building: Entity, index: number): boolean {\n\tconst production = productionOf(building)\n\tconst item = production?.queue[index]\n\tif (!production || !item) return false\n\tproduction.queue.splice(index, 1)\n\tgiveBack(world, building, item)\n\treturn true\n}\n\n/** Where what a building produced comes out: on the side of its rally point */\nfunction exitOf(world: World, building: Entity, radius: number): { exit: Vec2; towards: Vec2 } {\n\tconst rally = productionOf(building)!.rally\n\tconst towards = world.get(rally?.target)?.pos ?? rally?.point ?? { x: building.pos.x, z: building.pos.z - 100 }\n\treturn { exit: closestPointOnRect(towards, building.rect, radius + 0.3), towards }\n}\n\nfunction finishUnit(world: World, building: Entity, unitType: string): void {\n\tconst def = world.registry.unit(unitType)\n\tconst rally = productionOf(building)!.rally\n\tconst rallyTarget = world.get(rally?.target)\n\tconst { exit, towards } = exitOf(world, building, def.radius)\n\tconst unit = world.spawn(unitType, building.owner, exit, { facing: atan2(towards.x - exit.x, towards.z - exit.z) })\n\tworld.events.emit(unitTrained, { building, unit })\n\tworld.hooks.run('produced', { producer: building, kind: 'unit', id: unitType, unit })\n\tif (!rally) return\n\n\tif (rallyTarget?.get(deposit) && unit.has(gathering)) giveOrder(world, unit, createOrder(world, { type: 'harvest', target: rallyTarget.id }))\n\telse if (rallyTarget && rallyTarget.isUnit) giveOrder(world, unit, createOrder(world, { type: 'move', target: rallyTarget.id }))\n\telse giveOrder(world, unit, createOrder(world, { type: 'move', point: rally.point }))\n}\n\nfunction finishUpgrade(world: World, building: Entity, upgrade: string): void {\n\tconst player = world.player(building.owner)\n\tconst level = (player.upgrades.get(upgrade) ?? 0) + 1\n\tplayer.setUpgrade(upgrade, level)\n\tplayer.researching.delete(upgrade)\n\t// what it does besides stats, to every unit the player has\n\tconst { apply } = world.registry.upgrade(upgrade)\n\tif (apply) for (const entity of [...world.index.ownedBy(player.id)]) if (entity.alive) apply(world, entity, level)\n\tworld.events.emit(researchFinished, { building, upgrade, level })\n\tworld.hooks.run('produced', { producer: building, kind: 'upgrade', id: upgrade, level })\n\tworld.message(player.id, engineMessage('researchDone', { upgrade }), 'info')\n}\n\nexport const productionSystem: System = {\n\tname: 'production',\n\tphase: 'resolve',\n\t// only what trains, researches or turns into something: not every unit and tree of the map (OB5)\n\tover: productionQueue,\n\teach(world, entity, dt) {\n\t\tconst production = productionOf(entity)\n\t\tif (!production || !entity.operational || entity.scenery) return\n\t\tconst item = production.queue[0]\n\t\tif (!item) return\n\t\titem.progress += dt\n\t\tif (item.progress < item.duration) return\n\t\tproduction.queue.shift()\n\t\tif (item.kind === 'unit') finishUnit(world, entity, item.id)\n\t\telse if (item.kind === 'upgrade') finishUpgrade(world, entity, item.id)\n\t\telse if (item.kind === 'morph') {\n\t\t\tmorph(world, entity, item.id)\n\t\t\tworld.hooks.run('produced', { producer: entity, kind: 'morph', id: item.id, unit: entity })\n\t\t} else {\n\t\t\tconst hero = world.entities.get(Number(item.id))\n\t\t\tif (hero) {\n\t\t\t\treviveHero(world, hero, exitOf(world, entity, hero.def.radius).exit)\n\t\t\t\tworld.hooks.run('produced', { producer: entity, kind: 'revive', id: item.id, unit: hero })\n\t\t\t}\n\t\t}\n\t}\n}\n\n/** A unit made, to those who see it */\nexport const toldTrained = replicateEvent(unitTrained, 'trained', ({ building, unit }, view) =>\n\tview.knows(unit) ? { type: 'trained', id: unit.id, building: view.knows(building) ? building.id : undefined } : undefined\n)\n\n/** Research done: to its side */\nexport const toldResearched = replicateEvent(researchFinished, 'researched', ({ building, upgrade, level }, view) =>\n\tview.isAlly(building.owner) ? { type: 'researched', upgrade, level, building: building.id } : undefined\n)\n\n/** A building starting to become another, to those who see it */\nexport const toldUpgradeStarted = replicateEvent(morphStarted, 'upgradeStarted', ({ entity, into, time }, view) =>\n\tview.knows(entity) ? { type: 'upgradeStarted', id: entity.id, to: into, time } : undefined\n)\n"],"mappings":"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"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { upgradesOf } from "../defs.js";
|
|
2
|
+
import { defineComponent, snapshotOf } from "../components.js";
|
|
3
|
+
import { morphCancelled } from "../engineEvents.js";
|
|
4
|
+
import { replicateEvent } from "../replication.js";
|
|
5
|
+
import { sameHundredth } from "./construction.js";
|
|
6
|
+
import { giveBack as giveBack$1 } from "../player.js";
|
|
7
|
+
//#region src/systems/productionQueue.ts
|
|
8
|
+
/**
|
|
9
|
+
* What a building makes (`productionQueue`): its queue and its rally point, and what a player's screen is told of it.
|
|
10
|
+
* The state alone, of nothing but components, so that what reads or sets it (a unit turning into another type, the
|
|
11
|
+
* tech) loads nothing of the production system (`production.ts`)
|
|
12
|
+
*/
|
|
13
|
+
var NOTHING = [];
|
|
14
|
+
var sameItem = (a, b) => a.kind === b.kind && a.id === b.id && sameHundredth(a.progress, b.progress);
|
|
15
|
+
/**
|
|
16
|
+
* What a building makes (`UnitTypeDef.trains`, `researches`, `upgradesTo`, `revives`): its queue, and where what comes
|
|
17
|
+
* out goes. Set as it is spawned (and as its type changes), for a type that makes anything. Its owner and their allies
|
|
18
|
+
* are told the queue and the rally point; everyone who sees it how far it is in turning into another type
|
|
19
|
+
* (`ProductionInfo`)
|
|
20
|
+
*
|
|
21
|
+
* @beta
|
|
22
|
+
*/
|
|
23
|
+
var productionQueue = defineComponent({
|
|
24
|
+
id: "core.production",
|
|
25
|
+
refs: (saved) => {
|
|
26
|
+
const { queue } = saved;
|
|
27
|
+
return {
|
|
28
|
+
upgrades: queue.filter((queued) => queued.kind === "upgrade").map((queued) => queued.id),
|
|
29
|
+
units: queue.filter((queued) => queued.kind !== "upgrade" && queued.kind !== "revive").map((queued) => queued.id)
|
|
30
|
+
};
|
|
31
|
+
},
|
|
32
|
+
onSpawn: (entity) => {
|
|
33
|
+
const { def } = entity;
|
|
34
|
+
if (def.kind !== "unit" && (def.trains?.length || def.researches?.length || upgradesOf(def).length)) entity.set(productionQueue, {
|
|
35
|
+
queue: [],
|
|
36
|
+
rally: null
|
|
37
|
+
});
|
|
38
|
+
},
|
|
39
|
+
onLeave: (entity, world) => cancelAllProduction(world, entity),
|
|
40
|
+
replicate: "everyone",
|
|
41
|
+
snapshot(production, _entity, { world, ally }) {
|
|
42
|
+
const info = {};
|
|
43
|
+
const first = production.queue[0];
|
|
44
|
+
if (first?.kind === "morph") {
|
|
45
|
+
info.upgrade = first.progress / first.duration;
|
|
46
|
+
info.upgradeTo = first.id;
|
|
47
|
+
}
|
|
48
|
+
if (ally) {
|
|
49
|
+
if (production.queue.length) info.queue = production.queue.map((item) => ({
|
|
50
|
+
kind: item.kind,
|
|
51
|
+
id: item.id,
|
|
52
|
+
progress: item.progress / item.duration
|
|
53
|
+
}));
|
|
54
|
+
const rally = world.get(production.rally?.target)?.pos ?? production.rally?.point;
|
|
55
|
+
if (rally) info.rally = {
|
|
56
|
+
x: rally.x,
|
|
57
|
+
z: rally.z
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
return info.upgradeTo !== void 0 || info.queue || info.rally ? info : void 0;
|
|
61
|
+
},
|
|
62
|
+
same: (a, b) => a.upgradeTo === b.upgradeTo && (a.upgrade === void 0 ? b.upgrade === void 0 : b.upgrade !== void 0 && sameHundredth(a.upgrade, b.upgrade)) && a.rally?.x === b.rally?.x && a.rally?.z === b.rally?.z && (a.queue?.length ?? 0) === (b.queue?.length ?? 0) && (a.queue ?? []).every((item, i) => sameItem(item, b.queue[i]))
|
|
63
|
+
});
|
|
64
|
+
/**
|
|
65
|
+
* What a building makes, and where it goes: none for a type that makes nothing (`productionQueue`)
|
|
66
|
+
*
|
|
67
|
+
* @beta
|
|
68
|
+
*/
|
|
69
|
+
var productionOf = (entity) => entity.get(productionQueue);
|
|
70
|
+
/**
|
|
71
|
+
* What a building in a snapshot makes, the first being made: empty for one that makes nothing, or another's (a
|
|
72
|
+
* screen's, a computer player's view)
|
|
73
|
+
*
|
|
74
|
+
* @beta
|
|
75
|
+
*/
|
|
76
|
+
var queueOf = (state) => snapshotOf(state, productionQueue)?.queue ?? NOTHING;
|
|
77
|
+
/**
|
|
78
|
+
* The type a building in a snapshot is turning into, and how far, 0..1: undefined for one that is not
|
|
79
|
+
*
|
|
80
|
+
* @beta
|
|
81
|
+
*/
|
|
82
|
+
function upgradeOf(state) {
|
|
83
|
+
const info = snapshotOf(state, productionQueue);
|
|
84
|
+
return info?.upgradeTo === void 0 ? void 0 : {
|
|
85
|
+
to: info.upgradeTo,
|
|
86
|
+
progress: info.upgrade ?? 0
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
/** What a building had queued, given back: the money paid, a hero no longer coming back, research no longer under way */
|
|
90
|
+
function giveBack(world, building, item) {
|
|
91
|
+
const player = world.player(building.owner);
|
|
92
|
+
const { registry } = world;
|
|
93
|
+
if (item.kind === "revive") {
|
|
94
|
+
const hero = world.entities.get(Number(item.id));
|
|
95
|
+
if (hero) hero.reviving = false;
|
|
96
|
+
} else if (item.kind === "upgrade") player.researching.delete(item.id);
|
|
97
|
+
else if (item.kind === "morph") world.events.emit(morphCancelled, {
|
|
98
|
+
entity: building,
|
|
99
|
+
into: item.id
|
|
100
|
+
});
|
|
101
|
+
const paid = item.paid ?? (item.kind === "upgrade" ? registry.upgrade(item.id).cost : registry.unit(item.id).cost);
|
|
102
|
+
giveBack$1(world, player.id, paid, 1, item.kind, item.id);
|
|
103
|
+
}
|
|
104
|
+
/** Gives back everything a building had queued, for when it is destroyed */
|
|
105
|
+
function cancelAllProduction(world, building) {
|
|
106
|
+
const production = productionOf(building);
|
|
107
|
+
if (!production) return;
|
|
108
|
+
for (const item of production.queue) giveBack(world, building, item);
|
|
109
|
+
production.queue.length = 0;
|
|
110
|
+
}
|
|
111
|
+
/** A building's becoming another called off, to those who see it */
|
|
112
|
+
var toldUpgradeCancelled = replicateEvent(morphCancelled, "upgradeCancelled", ({ entity, into }, view) => view.knows(entity) ? {
|
|
113
|
+
type: "upgradeCancelled",
|
|
114
|
+
id: entity.id,
|
|
115
|
+
to: into
|
|
116
|
+
} : void 0);
|
|
117
|
+
//#endregion
|
|
118
|
+
export { cancelAllProduction, giveBack, productionOf, productionQueue, queueOf, toldUpgradeCancelled, upgradeOf };
|
|
119
|
+
|
|
120
|
+
//# sourceMappingURL=productionQueue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"productionQueue.js","names":[],"sources":["../../src/systems/productionQueue.ts"],"sourcesContent":["/**\n * What a building makes (`productionQueue`): its queue and its rally point, and what a player's screen is told of it.\n * The state alone, of nothing but components, so that what reads or sets it (a unit turning into another type, the\n * tech) loads nothing of the production system (`production.ts`)\n */\nimport { morphCancelled } from '#engine/engineEvents'\nimport { upgradesOf } from '#engine/defs'\nimport { defineComponent, snapshotOf } from '#engine/components'\nimport type { Entity, ProductionItem, ProductionState } from '#engine/entity'\nimport { giveBack as refundTo } from '#engine/player'\nimport type { World } from '#engine/world'\nimport type { EntityState, ProductionInfo, QueueItemState } from '#engine/session/protocol'\nimport { sameHundredth } from './construction'\nimport { replicateEvent } from '../replication'\n\nconst NOTHING: readonly QueueItemState[] = []\n\nconst sameItem = (a: QueueItemState, b: QueueItemState) => a.kind === b.kind && a.id === b.id && sameHundredth(a.progress, b.progress)\n\n/**\n * What a building makes (`UnitTypeDef.trains`, `researches`, `upgradesTo`, `revives`): its queue, and where what comes\n * out goes. Set as it is spawned (and as its type changes), for a type that makes anything. Its owner and their allies\n * are told the queue and the rally point; everyone who sees it how far it is in turning into another type\n * (`ProductionInfo`)\n *\n * @beta\n */\nexport const productionQueue = defineComponent<ProductionState, ProductionInfo>({ id: 'core.production', refs: (saved) => {\n\t\tconst { queue } = saved as ProductionState\n\t\treturn {\n\t\t\tupgrades: queue.filter((queued) => queued.kind === 'upgrade').map((queued) => queued.id),\n\t\t\tunits: queue.filter((queued) => queued.kind !== 'upgrade' && queued.kind !== 'revive').map((queued) => queued.id)\n\t\t}\n\t},\n\t// a queue, empty, for a structure that makes anything\n\tonSpawn: (entity) => {\n\t\tconst { def } = entity\n\t\tif (def.kind !== 'unit' && (def.trains?.length || def.researches?.length || upgradesOf(def).length))\n\t\t\tentity.set(productionQueue, { queue: [], rally: null })\n\t},\n\t// what it was making given back to whose it was, as it falls or is given away\n\tonLeave: (entity, world) => cancelAllProduction(world, entity),\n\treplicate: 'everyone',\n\tsnapshot(production, _entity, { world, ally }) {\n\t\tconst info: ProductionInfo = {}\n\t\t// a building turning into another: how far, for everyone who sees it\n\t\tconst first = production.queue[0]\n\t\tif (first?.kind === 'morph') {\n\t\t\tinfo.upgrade = first.progress / first.duration\n\t\t\tinfo.upgradeTo = first.id\n\t\t}\n\t\tif (ally) {\n\t\t\tif (production.queue.length)\n\t\t\t\tinfo.queue = production.queue.map((item) => ({ kind: item.kind, id: item.id, progress: item.progress / item.duration }))\n\t\t\tconst rally = world.get(production.rally?.target)?.pos ?? production.rally?.point\n\t\t\tif (rally) info.rally = { x: rally.x, z: rally.z }\n\t\t}\n\t\treturn info.upgradeTo !== undefined || info.queue || info.rally ? info : undefined\n\t},\n\t// a delta for every hundredth of what is under way, not every tick\n\tsame: (a, b) =>\n\t\ta.upgradeTo === b.upgradeTo &&\n\t\t(a.upgrade === undefined ? b.upgrade === undefined : b.upgrade !== undefined && sameHundredth(a.upgrade, b.upgrade)) &&\n\t\ta.rally?.x === b.rally?.x &&\n\t\ta.rally?.z === b.rally?.z &&\n\t\t(a.queue?.length ?? 0) === (b.queue?.length ?? 0) &&\n\t\t(a.queue ?? []).every((item, i) => sameItem(item, b.queue![i])) })\n\n/**\n * What a building makes, and where it goes: none for a type that makes nothing (`productionQueue`)\n *\n * @beta\n */\nexport const productionOf = (entity: Entity): ProductionState | undefined => entity.get(productionQueue)\n\n/**\n * What a building in a snapshot makes, the first being made: empty for one that makes nothing, or another's (a\n * screen's, a computer player's view)\n *\n * @beta\n */\nexport const queueOf = (state: EntityState): readonly QueueItemState[] => snapshotOf(state, productionQueue)?.queue ?? NOTHING\n\n/**\n * The type a building in a snapshot is turning into, and how far, 0..1: undefined for one that is not\n *\n * @beta\n */\nexport function upgradeOf(state: EntityState): { to: string; progress: number } | undefined {\n\tconst info = snapshotOf(state, productionQueue)\n\treturn info?.upgradeTo === undefined ? undefined : { to: info.upgradeTo, progress: info.upgrade ?? 0 }\n}\n\n/** What a building had queued, given back: the money paid, a hero no longer coming back, research no longer under way */\nexport function giveBack(world: World, building: Entity, item: ProductionItem): void {\n\tconst player = world.player(building.owner)\n\tconst { registry } = world\n\tif (item.kind === 'revive') {\n\t\tconst hero = world.entities.get(Number(item.id))\n\t\tif (hero) hero.reviving = false\n\t} else if (item.kind === 'upgrade') {\n\t\tplayer.researching.delete(item.id)\n\t} else if (item.kind === 'morph') {\n\t\tworld.events.emit(morphCancelled, { entity: building, into: item.id })\n\t}\n\tconst paid = item.paid ?? (item.kind === 'upgrade' ? registry.upgrade(item.id).cost : registry.unit(item.id).cost)\n\trefundTo(world, player.id, paid, 1, item.kind, item.id)\n}\n\n/** Gives back everything a building had queued, for when it is destroyed */\nexport function cancelAllProduction(world: World, building: Entity): void {\n\tconst production = productionOf(building)\n\tif (!production) return\n\tfor (const item of production.queue) giveBack(world, building, item)\n\tproduction.queue.length = 0\n}\n\n/** A building's becoming another called off, to those who see it */\nexport const toldUpgradeCancelled = replicateEvent(morphCancelled, 'upgradeCancelled', ({ entity, into }, view) =>\n\tview.knows(entity) ? { type: 'upgradeCancelled', id: entity.id, to: into } : undefined\n)\n"],"mappings":"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"}
|
|
@@ -11,4 +11,4 @@ export declare function defeat(world: World, playerId: number): void;
|
|
|
11
11
|
*/
|
|
12
12
|
export declare const lastTeamStanding: System;
|
|
13
13
|
/** Whether the player's team won, lost or plays on (`Snapshot.outcome`): an observer neither wins nor loses */
|
|
14
|
-
export declare const outcomePart: import("..").
|
|
14
|
+
export declare const outcomePart: import("..").SnapshotField<keyof import("..").Snapshot>;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { gameOver, playerDefeated } from "../engineEvents.js";
|
|
2
|
+
import { snapshotField } from "../replication.js";
|
|
3
|
+
import { engineMessage } from "../messages.js";
|
|
4
|
+
//#region src/systems/victory.ts
|
|
5
|
+
/** Puts a player out of the game: they are told, and see the whole map from then on */
|
|
6
|
+
function defeat(world, playerId) {
|
|
7
|
+
const player = world.player(playerId);
|
|
8
|
+
player.defeated = true;
|
|
9
|
+
world.fog.setRevealed(player.team, world.sides.teamDefeated(player.team));
|
|
10
|
+
world.events.emit(playerDefeated, player);
|
|
11
|
+
world.message(playerId, engineMessage("defeated"), "info");
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* The rule of a melee game: whoever has no building left is out, and the last team in the game wins.
|
|
15
|
+
* Players only take part once they have had a building, so a world with nothing but a few units
|
|
16
|
+
* in it, like most tests, has no losers. Game modules with other ways to win bring their own system.
|
|
17
|
+
*
|
|
18
|
+
* @beta
|
|
19
|
+
*/
|
|
20
|
+
var lastTeamStanding = {
|
|
21
|
+
name: "victory",
|
|
22
|
+
phase: "cleanup",
|
|
23
|
+
every: 15,
|
|
24
|
+
update(world) {
|
|
25
|
+
if (world.winner !== null) return;
|
|
26
|
+
const buildings = /* @__PURE__ */ new Set();
|
|
27
|
+
for (const entity of world.units.values()) if (entity.alive && entity.isBuilding) buildings.add(entity.owner);
|
|
28
|
+
for (const player of world.players.values()) {
|
|
29
|
+
if (player.neutral || player.creeps || player.defeated) continue;
|
|
30
|
+
if (buildings.has(player.id)) player.established = true;
|
|
31
|
+
else if (player.established) defeat(world, player.id);
|
|
32
|
+
}
|
|
33
|
+
const teams = /* @__PURE__ */ new Set();
|
|
34
|
+
const standing = /* @__PURE__ */ new Set();
|
|
35
|
+
for (const player of world.players.values()) {
|
|
36
|
+
if (!player.established) continue;
|
|
37
|
+
teams.add(player.team);
|
|
38
|
+
if (!player.defeated) standing.add(player.team);
|
|
39
|
+
}
|
|
40
|
+
if (teams.size < 2 || standing.size !== 1) return;
|
|
41
|
+
const [winner] = standing;
|
|
42
|
+
world.winner = winner;
|
|
43
|
+
world.events.emit(gameOver, { winner });
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
/** Whether the player's team won, lost or plays on (`Snapshot.outcome`): an observer neither wins nor loses */
|
|
47
|
+
var outcomePart = snapshotField("outcome", (view) => {
|
|
48
|
+
const { world } = view;
|
|
49
|
+
if (view.observer) return "playing";
|
|
50
|
+
const team = view.team;
|
|
51
|
+
return world.winner === team ? "victory" : world.winner !== null || world.sides.teamDefeated(team) ? "defeat" : "playing";
|
|
52
|
+
}, true);
|
|
53
|
+
//#endregion
|
|
54
|
+
export { defeat, lastTeamStanding, outcomePart };
|
|
55
|
+
|
|
56
|
+
//# sourceMappingURL=victory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"victory.js","names":[],"sources":["../../src/systems/victory.ts"],"sourcesContent":["import { gameOver, playerDefeated } from '#engine/engineEvents'\nimport type { System } from '#engine/registry'\nimport type { World } from '#engine/world'\nimport { engineMessage } from '#engine/messages'\nimport { snapshotField } from '../replication'\n\n/** Puts a player out of the game: they are told, and see the whole map from then on */\nexport function defeat(world: World, playerId: number): void {\n\tconst player = world.player(playerId)\n\tplayer.defeated = true\n\t// nothing left to hide from someone who is out\n\tworld.fog.setRevealed(player.team, world.sides.teamDefeated(player.team))\n\tworld.events.emit(playerDefeated, player)\n\tworld.message(playerId, engineMessage('defeated'), 'info')\n}\n\n/**\n * The rule of a melee game: whoever has no building left is out, and the last team in the game wins.\n * Players only take part once they have had a building, so a world with nothing but a few units\n * in it, like most tests, has no losers. Game modules with other ways to win bring their own system.\n *\n * @beta\n */\nexport const lastTeamStanding: System = {\n\tname: 'victory',\n\tphase: 'cleanup',\n\t// a look at who is still in the game, twice a second or so\n\tevery: 15,\n\tupdate(world) {\n\t\tif (world.winner !== null) return\n\n\t\tconst buildings = new Set<number>()\n\t\tfor (const entity of world.units.values()) {\n\t\t\tif (entity.alive && entity.isBuilding) buildings.add(entity.owner)\n\t\t}\n\t\tfor (const player of world.players.values()) {\n\t\t\tif (player.neutral || player.creeps || player.defeated) continue\n\t\t\tif (buildings.has(player.id)) player.established = true\n\t\t\telse if (player.established) defeat(world, player.id)\n\t\t}\n\n\t\tconst teams = new Set<number>()\n\t\tconst standing = new Set<number>()\n\t\tfor (const player of world.players.values()) {\n\t\t\tif (!player.established) continue\n\t\t\tteams.add(player.team)\n\t\t\tif (!player.defeated) standing.add(player.team)\n\t\t}\n\t\tif (teams.size < 2 || standing.size !== 1) return\n\t\tconst [winner] = standing\n\t\tworld.winner = winner\n\t\tworld.events.emit(gameOver, { winner })\n\t}\n}\n\n/** Whether the player's team won, lost or plays on (`Snapshot.outcome`): an observer neither wins nor loses */\nexport const outcomePart = snapshotField(\n\t'outcome',\n\t(view) => {\n\t\tconst { world } = view\n\t\tif (view.observer) return 'playing'\n\t\tconst team = view.team\n\t\treturn world.winner === team ? 'victory' : world.winner !== null || world.sides.teamDefeated(team) ? 'defeat' : 'playing'\n\t},\n\ttrue\n)\n"],"mappings":";;;;;AAOA,SAAgB,OAAO,OAAc,UAAwB;CAC5D,MAAM,SAAS,MAAM,OAAO,QAAQ;CACpC,OAAO,WAAW;CAElB,MAAM,IAAI,YAAY,OAAO,MAAM,MAAM,MAAM,aAAa,OAAO,IAAI,CAAC;CACxE,MAAM,OAAO,KAAK,gBAAgB,MAAM;CACxC,MAAM,QAAQ,UAAU,cAAc,UAAU,GAAG,MAAM;AAC1D;;;;;;;;AASA,IAAa,mBAA2B;CACvC,MAAM;CACN,OAAO;CAEP,OAAO;CACP,OAAO,OAAO;EACb,IAAI,MAAM,WAAW,MAAM;EAE3B,MAAM,4BAAY,IAAI,IAAY;EAClC,KAAK,MAAM,UAAU,MAAM,MAAM,OAAO,GACvC,IAAI,OAAO,SAAS,OAAO,YAAY,UAAU,IAAI,OAAO,KAAK;EAElE,KAAK,MAAM,UAAU,MAAM,QAAQ,OAAO,GAAG;GAC5C,IAAI,OAAO,WAAW,OAAO,UAAU,OAAO,UAAU;GACxD,IAAI,UAAU,IAAI,OAAO,EAAE,GAAG,OAAO,cAAc;QAC9C,IAAI,OAAO,aAAa,OAAO,OAAO,OAAO,EAAE;EACrD;EAEA,MAAM,wBAAQ,IAAI,IAAY;EAC9B,MAAM,2BAAW,IAAI,IAAY;EACjC,KAAK,MAAM,UAAU,MAAM,QAAQ,OAAO,GAAG;GAC5C,IAAI,CAAC,OAAO,aAAa;GACzB,MAAM,IAAI,OAAO,IAAI;GACrB,IAAI,CAAC,OAAO,UAAU,SAAS,IAAI,OAAO,IAAI;EAC/C;EACA,IAAI,MAAM,OAAO,KAAK,SAAS,SAAS,GAAG;EAC3C,MAAM,CAAC,UAAU;EACjB,MAAM,SAAS;EACf,MAAM,OAAO,KAAK,UAAU,EAAE,OAAO,CAAC;CACvC;AACD;;AAGA,IAAa,cAAc,cAC1B,YACC,SAAS;CACT,MAAM,EAAE,UAAU;CAClB,IAAI,KAAK,UAAU,OAAO;CAC1B,MAAM,OAAO,KAAK;CAClB,OAAO,MAAM,WAAW,OAAO,YAAY,MAAM,WAAW,QAAQ,MAAM,MAAM,aAAa,IAAI,IAAI,WAAW;AACjH,GACA,IACD"}
|
package/dist/talk.d.ts
CHANGED
|
@@ -17,19 +17,19 @@ export declare function allowed(world: World, player: PlayerId, kind: string, li
|
|
|
17
17
|
within: number;
|
|
18
18
|
}): boolean;
|
|
19
19
|
/**
|
|
20
|
-
* The kinds of ping hero arena games have: a game's are its rules' (`
|
|
20
|
+
* The kinds of ping hero arena games have: a game's are its rules' (`RuleSettings.talk.pings.kinds`), `look` first
|
|
21
21
|
*
|
|
22
22
|
* @beta
|
|
23
23
|
*/
|
|
24
24
|
export declare const PING_KINDS: readonly ['look', 'danger', 'assist', 'onMyWay'];
|
|
25
25
|
/**
|
|
26
|
-
* A kind of ping: one of `
|
|
26
|
+
* A kind of ping: one of `RuleSettings.talk.pings.kinds`
|
|
27
27
|
*
|
|
28
28
|
* @beta
|
|
29
29
|
*/
|
|
30
|
-
export type
|
|
30
|
+
export type PingId = string;
|
|
31
31
|
/**
|
|
32
|
-
* The kinds of ping a game's rules let go (`
|
|
32
|
+
* The kinds of ping a game's rules let go (`RuleSettings.talk.pings.kinds`), as they are now: its list, or what it works
|
|
33
33
|
* out from the registry (a file of the game's the editor writes)
|
|
34
34
|
*
|
|
35
35
|
* @beta
|
|
@@ -38,7 +38,7 @@ export declare function pingKinds(registry: Registry): readonly string[];
|
|
|
38
38
|
/**
|
|
39
39
|
* A player marks a spot of the map (`pinged`) for their allies (`to: 'allies'`, when left out) or for everyone
|
|
40
40
|
* (`'all'`): told to them and to who watches, as sessions do. Of a kind the game's rules have
|
|
41
|
-
* (`
|
|
41
|
+
* (`RuleSettings.talk.pings.kinds`), as many in a while as they let (`RuleSettings.talk`), and as the `beforeTalk` hook lets it,
|
|
42
42
|
* which may change who hears it
|
|
43
43
|
*
|
|
44
44
|
* @beta
|
|
@@ -53,7 +53,7 @@ export declare function ping(world: World, player: PlayerId, point: Vec2, kind?:
|
|
|
53
53
|
export type ChatAudience = 'allies' | 'all' | 'observers';
|
|
54
54
|
/**
|
|
55
55
|
* A player says a line (`chatted`): to their side, or to everyone, and to who watches either way. Spaces run
|
|
56
|
-
* together, and cut to the game's length (`
|
|
56
|
+
* together, and cut to the game's length (`RuleSettings.talk`); nothing for an empty line, a message for too many in a
|
|
57
57
|
* while; and as the `beforeTalk` hook lets it, which may change the words or who hears them
|
|
58
58
|
*
|
|
59
59
|
* @beta
|
package/dist/talk.js
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { defineComponent } from "./components.js";
|
|
2
|
+
import { chatted, pinged } from "./engineEvents.js";
|
|
3
|
+
import { replicateEvent } from "./replication.js";
|
|
4
|
+
import { engineMessage } from "./messages.js";
|
|
5
|
+
//#region src/talk.ts
|
|
6
|
+
/**
|
|
7
|
+
* When each player's last ones of each kind went out (`ping:1`, the world's times): the world's, and saved with it, so
|
|
8
|
+
* that a player who used up the limit is still refused in the game loaded from a save, as in the game that went on
|
|
9
|
+
*/
|
|
10
|
+
var sent = defineComponent({
|
|
11
|
+
id: "core.talkSent",
|
|
12
|
+
default: () => ({})
|
|
13
|
+
});
|
|
14
|
+
/**
|
|
15
|
+
* Whether a player may send another of a kind now: and counts it, when they may
|
|
16
|
+
*
|
|
17
|
+
* @beta
|
|
18
|
+
*/
|
|
19
|
+
function allowed(world, player, kind, limit) {
|
|
20
|
+
const byPlayer = world.state(sent);
|
|
21
|
+
const key = `${kind}:${player}`;
|
|
22
|
+
const times = (byPlayer[key] ?? []).filter((time) => world.time - time < limit.within);
|
|
23
|
+
byPlayer[key] = times;
|
|
24
|
+
if (times.length >= limit.most) return false;
|
|
25
|
+
times.push(world.time);
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* The kinds of ping hero arena games have: a game's are its rules' (`RuleSettings.talk.pings.kinds`), `look` first
|
|
30
|
+
*
|
|
31
|
+
* @beta
|
|
32
|
+
*/
|
|
33
|
+
var PING_KINDS = [
|
|
34
|
+
"look",
|
|
35
|
+
"danger",
|
|
36
|
+
"assist",
|
|
37
|
+
"onMyWay"
|
|
38
|
+
];
|
|
39
|
+
/**
|
|
40
|
+
* Whether the rules let a player say this (`beforeTalk`): the event as the handlers left it, or nothing when one of
|
|
41
|
+
* them called it off
|
|
42
|
+
*/
|
|
43
|
+
function heard(world, talk) {
|
|
44
|
+
const event = {
|
|
45
|
+
...talk,
|
|
46
|
+
cancelled: false
|
|
47
|
+
};
|
|
48
|
+
if (world.hooks.has("beforeTalk")) world.hooks.run("beforeTalk", event);
|
|
49
|
+
return event.cancelled ? void 0 : event;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* The kinds of ping a game's rules let go (`RuleSettings.talk.pings.kinds`), as they are now: its list, or what it works
|
|
53
|
+
* out from the registry (a file of the game's the editor writes)
|
|
54
|
+
*
|
|
55
|
+
* @beta
|
|
56
|
+
*/
|
|
57
|
+
function pingKinds(registry) {
|
|
58
|
+
const { kinds } = registry.settings.talk.pings;
|
|
59
|
+
return typeof kinds === "function" ? kinds(registry) : kinds;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* A player marks a spot of the map (`pinged`) for their allies (`to: 'allies'`, when left out) or for everyone
|
|
63
|
+
* (`'all'`): told to them and to who watches, as sessions do. Of a kind the game's rules have
|
|
64
|
+
* (`RuleSettings.talk.pings.kinds`), as many in a while as they let (`RuleSettings.talk`), and as the `beforeTalk` hook lets it,
|
|
65
|
+
* which may change who hears it
|
|
66
|
+
*
|
|
67
|
+
* @beta
|
|
68
|
+
*/
|
|
69
|
+
function ping(world, player, point, kind = pingKinds(world.registry)[0] ?? "look", to = "allies", by) {
|
|
70
|
+
if (!pingKinds(world.registry).includes(kind)) return;
|
|
71
|
+
if (!isAudience(to)) return;
|
|
72
|
+
if (!allowed(world, player, "ping", world.settings.talk.pings)) return world.message(player, engineMessage("tooManyPings"));
|
|
73
|
+
const event = heard(world, {
|
|
74
|
+
player,
|
|
75
|
+
kind: "ping",
|
|
76
|
+
point,
|
|
77
|
+
pingKind: kind,
|
|
78
|
+
to
|
|
79
|
+
});
|
|
80
|
+
if (!event) return;
|
|
81
|
+
world.events.emit(pinged, {
|
|
82
|
+
player,
|
|
83
|
+
point: {
|
|
84
|
+
x: point.x,
|
|
85
|
+
z: point.z
|
|
86
|
+
},
|
|
87
|
+
kind,
|
|
88
|
+
to: event.to ?? to,
|
|
89
|
+
...watcher(to, by)
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
/** Whether a word is who a line or a ping is for */
|
|
93
|
+
var isAudience = (to) => to === "allies" || to === "all" || to === "observers";
|
|
94
|
+
/** How long the name of who watches may be, as their lines say it */
|
|
95
|
+
var WATCHER_NAME = 24;
|
|
96
|
+
/** The name of who watches, as their line or ping says it: only theirs, to who watches */
|
|
97
|
+
var watcher = (to, by) => to === "observers" && by?.trim() ? { by: by.trim().slice(0, WATCHER_NAME) } : {};
|
|
98
|
+
/**
|
|
99
|
+
* How long a line may be, unless the game's rules say otherwise (`RuleSettings.talk`)
|
|
100
|
+
*
|
|
101
|
+
* @internal
|
|
102
|
+
*/
|
|
103
|
+
var CHAT_LENGTH = 160;
|
|
104
|
+
/**
|
|
105
|
+
* A player says a line (`chatted`): to their side, or to everyone, and to who watches either way. Spaces run
|
|
106
|
+
* together, and cut to the game's length (`RuleSettings.talk`); nothing for an empty line, a message for too many in a
|
|
107
|
+
* while; and as the `beforeTalk` hook lets it, which may change the words or who hears them
|
|
108
|
+
*
|
|
109
|
+
* @beta
|
|
110
|
+
*/
|
|
111
|
+
function chat(world, player, text, to = "allies", by) {
|
|
112
|
+
if (!isAudience(to)) return;
|
|
113
|
+
const said = text.replace(/\s+/g, " ").trim().slice(0, world.settings.talk.lines.length);
|
|
114
|
+
if (!said) return;
|
|
115
|
+
if (!allowed(world, player, "chat", world.settings.talk.lines)) return world.message(player, engineMessage("tooManyLines"));
|
|
116
|
+
const event = heard(world, {
|
|
117
|
+
player,
|
|
118
|
+
kind: "chat",
|
|
119
|
+
text: said,
|
|
120
|
+
to
|
|
121
|
+
});
|
|
122
|
+
if (!event?.text) return;
|
|
123
|
+
world.events.emit(chatted, {
|
|
124
|
+
player,
|
|
125
|
+
text: event.text,
|
|
126
|
+
to: event.to ?? to,
|
|
127
|
+
...watcher(to, by)
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
/** Whether a screen hears what was said or pinged: everyone what is to all, who watches everything, a side its own; what who watches says, only who watches */
|
|
131
|
+
var hears = (to, player, view) => to === "observers" ? view.observer : to === "all" || view.observer || view.isAlly(player);
|
|
132
|
+
/** A ping: to everyone where it is to all, else to the pinger's side; one who watches pinged, to who watches */
|
|
133
|
+
var toldPing = replicateEvent(pinged, "ping", ({ player, point, kind, to, by }, view) => hears(to, player, view) ? {
|
|
134
|
+
type: "ping",
|
|
135
|
+
player,
|
|
136
|
+
x: point.x,
|
|
137
|
+
z: point.z,
|
|
138
|
+
kind,
|
|
139
|
+
to,
|
|
140
|
+
...by !== void 0 && { by }
|
|
141
|
+
} : void 0);
|
|
142
|
+
/** A line of chat: to everyone where it is to all, else to the speaker's side; one who watches said it, to who watches */
|
|
143
|
+
var toldChat = replicateEvent(chatted, "chat", ({ player, text, to, by }, view) => hears(to, player, view) ? {
|
|
144
|
+
type: "chat",
|
|
145
|
+
player,
|
|
146
|
+
text,
|
|
147
|
+
to,
|
|
148
|
+
...by !== void 0 && { by }
|
|
149
|
+
} : void 0);
|
|
150
|
+
//#endregion
|
|
151
|
+
export { CHAT_LENGTH, PING_KINDS, allowed, chat, ping, pingKinds, sent, toldChat, toldPing };
|
|
152
|
+
|
|
153
|
+
//# sourceMappingURL=talk.js.map
|
package/dist/talk.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"talk.js","names":["pingedEvent","chattedEvent"],"sources":["../src/talk.ts"],"sourcesContent":["import { chatted as chattedEvent, pinged as pingedEvent } from '#engine/engineEvents'\nimport { defineComponent } from './components'\nimport type { PlayerId } from './entity'\nimport type { Registry } from './registry'\nimport type { Vec2 } from './math'\nimport { engineMessage } from './messages'\nimport type { BeforeTalk } from './hooks'\nimport type { World } from './world'\nimport { replicateEvent } from './replication'\n\n/*\n * What players say to each other, besides the game: pings on the map, and (see `chat`) lines of text. Commands like\n * any other, so that they go over a wire and into a replay; limited in how often, as anyone may send them\n */\n\n/**\n * When each player's last ones of each kind went out (`ping:1`, the world's times): the world's, and saved with it, so\n * that a player who used up the limit is still refused in the game loaded from a save, as in the game that went on\n */\nexport const sent = defineComponent<Record<string, number[]>>({ id: 'core.talkSent', default: () => ({}) })\n\n/**\n * Whether a player may send another of a kind now: and counts it, when they may\n *\n * @beta\n */\nexport function allowed(world: World, player: PlayerId, kind: string, limit: { most: number; within: number }): boolean {\n\tconst byPlayer = world.state(sent)\n\tconst key = `${kind}:${player}`\n\tconst times = (byPlayer[key] ?? []).filter((time) => world.time - time < limit.within)\n\tbyPlayer[key] = times\n\tif (times.length >= limit.most) return false\n\ttimes.push(world.time)\n\treturn true\n}\n\n/**\n * The kinds of ping hero arena games have: a game's are its rules' (`RuleSettings.talk.pings.kinds`), `look` first\n *\n * @beta\n */\nexport const PING_KINDS = ['look', 'danger', 'assist', 'onMyWay'] as const\n/**\n * A kind of ping: one of `RuleSettings.talk.pings.kinds`\n *\n * @beta\n */\nexport type PingId = string\n\n/**\n * Whether the rules let a player say this (`beforeTalk`): the event as the handlers left it, or nothing when one of\n * them called it off\n */\nfunction heard<T extends Omit<BeforeTalk, 'cancelled' | 'cancel'>>(world: World, talk: T): (T & { cancelled: boolean }) | undefined {\n\tconst event = { ...talk, cancelled: false }\n\tif (world.hooks.has('beforeTalk')) world.hooks.run('beforeTalk', event)\n\treturn event.cancelled ? undefined : event\n}\n\n/**\n * The kinds of ping a game's rules let go (`RuleSettings.talk.pings.kinds`), as they are now: its list, or what it works\n * out from the registry (a file of the game's the editor writes)\n *\n * @beta\n */\nexport function pingKinds(registry: Registry): readonly string[] {\n\tconst { kinds } = registry.settings.talk.pings\n\treturn typeof kinds === 'function' ? kinds(registry) : kinds\n}\n\n/**\n * A player marks a spot of the map (`pinged`) for their allies (`to: 'allies'`, when left out) or for everyone\n * (`'all'`): told to them and to who watches, as sessions do. Of a kind the game's rules have\n * (`RuleSettings.talk.pings.kinds`), as many in a while as they let (`RuleSettings.talk`), and as the `beforeTalk` hook lets it,\n * which may change who hears it\n *\n * @beta\n */\nexport function ping(\n\tworld: World,\n\tplayer: PlayerId,\n\tpoint: Vec2,\n\tkind: string = pingKinds(world.registry)[0] ?? 'look',\n\tto: string = 'allies',\n\tby?: string\n): void {\n\tif (!pingKinds(world.registry).includes(kind)) return\n\tif (!isAudience(to)) return\n\tif (!allowed(world, player, 'ping', world.settings.talk.pings)) return world.message(player, engineMessage('tooManyPings'))\n\tconst event = heard(world, { player, kind: 'ping', point, pingKind: kind, to })\n\tif (!event) return\n\tworld.events.emit(pingedEvent, { player, point: { x: point.x, z: point.z }, kind, to: event.to ?? to, ...watcher(to, by) })\n}\n\n/** Whether a word is who a line or a ping is for */\nconst isAudience = (to: string): to is ChatAudience => to === 'allies' || to === 'all' || to === 'observers'\n\n/** How long the name of who watches may be, as their lines say it */\nconst WATCHER_NAME = 24\n\n/** The name of who watches, as their line or ping says it: only theirs, to who watches */\nconst watcher = (to: string, by: string | undefined) => (to === 'observers' && by?.trim() ? { by: by.trim().slice(0, WATCHER_NAME) } : {})\n\n/**\n * How long a line may be, unless the game's rules say otherwise (`RuleSettings.talk`)\n *\n * @internal\n */\nexport const CHAT_LENGTH = 160\n\n/**\n * Who a line of chat or a ping is for: the player's side, everyone in the game, or who watches alone (`observers`:\n * what one who watches says, which no player hears; a host gives every line of theirs this, `SessionHost`)\n *\n * @beta\n */\nexport type ChatAudience = 'allies' | 'all' | 'observers'\n\n/**\n * A player says a line (`chatted`): to their side, or to everyone, and to who watches either way. Spaces run\n * together, and cut to the game's length (`RuleSettings.talk`); nothing for an empty line, a message for too many in a\n * while; and as the `beforeTalk` hook lets it, which may change the words or who hears them\n *\n * @beta\n */\nexport function chat(world: World, player: PlayerId, text: string, to: string = 'allies', by?: string): void {\n\tif (!isAudience(to)) return\n\tconst said = text.replace(/\\s+/g, ' ').trim().slice(0, world.settings.talk.lines.length)\n\tif (!said) return\n\tif (!allowed(world, player, 'chat', world.settings.talk.lines)) return world.message(player, engineMessage('tooManyLines'))\n\tconst event = heard(world, { player, kind: 'chat', text: said, to })\n\tif (!event?.text) return\n\tworld.events.emit(chattedEvent, { player, text: event.text, to: event.to ?? to, ...watcher(to, by) })\n}\n\n/** Whether a screen hears what was said or pinged: everyone what is to all, who watches everything, a side its own; what who watches says, only who watches */\nconst hears = (to: ChatAudience, player: PlayerId, view: { observer: boolean; isAlly(player: PlayerId): boolean }) =>\n\tto === 'observers' ? view.observer : to === 'all' || view.observer || view.isAlly(player)\n\n/** A ping: to everyone where it is to all, else to the pinger's side; one who watches pinged, to who watches */\nexport const toldPing = replicateEvent(pingedEvent, 'ping', ({ player, point, kind, to, by }, view) =>\n\thears(to, player, view) ? { type: 'ping', player, x: point.x, z: point.z, kind, to, ...(by !== undefined && { by }) } : undefined\n)\n\n/** A line of chat: to everyone where it is to all, else to the speaker's side; one who watches said it, to who watches */\nexport const toldChat = replicateEvent(chattedEvent, 'chat', ({ player, text, to, by }, view) =>\n\thears(to, player, view) ? { type: 'chat', player, text, to, ...(by !== undefined && { by }) } : undefined\n)\n"],"mappings":"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"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How an ability is aimed (E2E-PLAN AB4): the engine's ways (`AbilityDef.target`: nothing, a unit, a point, a direction,
|
|
3
|
+
* two points, passive) and a game's own (`defineTargeting`, listed in `Rules.targetings`): how the order checks and
|
|
4
|
+
* aims it, and what the screen's indicator draws while the player aims it
|
|
5
|
+
*/
|
|
6
|
+
import type { AbilityDef, AimShape } from './defs';
|
|
7
|
+
import type { Entity } from './entity';
|
|
8
|
+
import type { Vec2 } from './math';
|
|
9
|
+
import type { MessageRef } from './messages';
|
|
10
|
+
import type { World } from './world';
|
|
11
|
+
/**
|
|
12
|
+
* The engine's ways of aiming an ability, what every way of a game's own is like (`Targeting.like`): at once
|
|
13
|
+
* (`none`), at a unit, at a point (walked into range of), towards a point (from where the caster stands), along two
|
|
14
|
+
* points (`vector`: where it starts, in range, and the way it goes from there), or not cast at all (`passive`)
|
|
15
|
+
*
|
|
16
|
+
* @beta
|
|
17
|
+
*/
|
|
18
|
+
export type AimKind = 'none' | 'unit' | 'point' | 'direction' | 'vector' | 'passive';
|
|
19
|
+
/**
|
|
20
|
+
* Every `AimKind`, in the order the aims are listed in tools
|
|
21
|
+
*
|
|
22
|
+
* @beta
|
|
23
|
+
*/
|
|
24
|
+
export declare const AIM_KINDS: readonly AimKind[];
|
|
25
|
+
/**
|
|
26
|
+
* How an ability was aimed, as its order carries it: the unit, the point, and for two points (`vector`) where it goes
|
|
27
|
+
* from the point (`to`)
|
|
28
|
+
*
|
|
29
|
+
* @beta
|
|
30
|
+
*/
|
|
31
|
+
export interface CastAim {
|
|
32
|
+
/** The ability's level */
|
|
33
|
+
level: number;
|
|
34
|
+
/** The unit the ability was aimed at, for a unit-aimed ability */
|
|
35
|
+
target?: Entity;
|
|
36
|
+
/** The ground point it was aimed at, or the first point of a two-point ability */
|
|
37
|
+
point?: Vec2;
|
|
38
|
+
/** For two points: the second, the way it goes from `point` */
|
|
39
|
+
to?: Vec2;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Where an ability's effects go, from how it was aimed (`Targeting.aim`): their point, the unit they are for, and what
|
|
43
|
+
* they go off from when not the caster (`EffectContext.origin`)
|
|
44
|
+
*
|
|
45
|
+
* @beta
|
|
46
|
+
*/
|
|
47
|
+
export interface CastAimed {
|
|
48
|
+
/** Where the effects go, in world coordinates */
|
|
49
|
+
point?: Vec2;
|
|
50
|
+
/** The unit the effects are for */
|
|
51
|
+
target?: Entity;
|
|
52
|
+
/** What the effects go off from when it is not the caster: an entity or a point */
|
|
53
|
+
origin?: Entity | Vec2;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* A piece of what an indicator draws (`Targeting.indicator`): a shape (`AimShape`) at a place on the ground, turned
|
|
57
|
+
* to `heading` (radians, 0 the way of +z) for one that points somewhere (a line, a cone, an arc)
|
|
58
|
+
*
|
|
59
|
+
* @beta
|
|
60
|
+
*/
|
|
61
|
+
export type AimPiece = AimShape & {
|
|
62
|
+
at: Vec2;
|
|
63
|
+
heading?: number;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* What the screen knows as the player aims (`Targeting.indicator`): the ability and its level, where the caster
|
|
67
|
+
* stands, where the pointer is on the ground, and for two points the first one, once it is given
|
|
68
|
+
*
|
|
69
|
+
* @beta
|
|
70
|
+
*/
|
|
71
|
+
export interface AimView {
|
|
72
|
+
/** The ability being aimed */
|
|
73
|
+
ability: AbilityDef;
|
|
74
|
+
/** The level of the ability being aimed */
|
|
75
|
+
level: number;
|
|
76
|
+
/** Where the caster stands, in world coordinates */
|
|
77
|
+
from: Vec2;
|
|
78
|
+
/** Where the pointer is on the ground, when it is over the ground */
|
|
79
|
+
pointer?: Vec2;
|
|
80
|
+
/** The first point of a two-point ability once it is given */
|
|
81
|
+
start?: Vec2;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* A way of aiming of a game's own, for `AbilityDef.target` (`defineTargeting`): the engine's way it is like (what the
|
|
85
|
+
* player gives, what the order walks to), and on top of that what may be aimed at (`check`), where the effects go
|
|
86
|
+
* from what was aimed (`aim`), and what the screen draws while it is aimed (`indicator`)
|
|
87
|
+
*
|
|
88
|
+
* @beta
|
|
89
|
+
*/
|
|
90
|
+
export interface Targeting {
|
|
91
|
+
/** What `AbilityDef.target` says for it */
|
|
92
|
+
readonly id: string;
|
|
93
|
+
/** The engine's way it is like: what the player gives (a unit, a point, two points, nothing) and what the order walks to */
|
|
94
|
+
readonly like: Exclude<AimKind, 'passive'>;
|
|
95
|
+
/**
|
|
96
|
+
* Why it cannot be aimed so, or nothing where it can: asked as the order takes it and again as it goes off (the
|
|
97
|
+
* player is told the reason). A wall only on open ground, a point only beside an ally
|
|
98
|
+
*/
|
|
99
|
+
check?(world: World, caster: Entity, ability: AbilityDef, aim: CastAim): MessageRef | undefined;
|
|
100
|
+
/**
|
|
101
|
+
* Where the effects go, from how it was aimed: over what the engine makes of it (its `point`, `target`, and for two
|
|
102
|
+
* points the first as the `origin` and the second as the `point`)
|
|
103
|
+
*/
|
|
104
|
+
aim?(world: World, caster: Entity, ability: AbilityDef, aim: CastAim): CastAimed | undefined;
|
|
105
|
+
/**
|
|
106
|
+
* What the screen draws on the ground while the player aims it, in place of the engine's (`aimOf`): pieces of the
|
|
107
|
+
* shapes there are, each at a place, turned as it says. Code of the game's own, run on the screen: no world
|
|
108
|
+
*/
|
|
109
|
+
indicator?(view: AimView): readonly AimPiece[] | undefined;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* A way of aiming of a game's own: `defineTargeting({ id: 'wall', like: 'point', check, indicator })`, listed in
|
|
113
|
+
* `Rules.targetings` and named by an ability's `target`. Its name is said by declaring it in `AbilityTargetings`
|
|
114
|
+
* (`declare module '@v12-engine/engine' { interface AbilityTargetings { wall: true } }`), so that an ability's
|
|
115
|
+
* `target: 'wall'` is typed
|
|
116
|
+
*
|
|
117
|
+
* @beta
|
|
118
|
+
*/
|
|
119
|
+
export declare function defineTargeting(def: Targeting): Targeting;
|
|
120
|
+
/**
|
|
121
|
+
* How an ability is aimed, as the engine's way it is or is like (`AimKind`): its `target` itself for the engine's, the
|
|
122
|
+
* `like` of a game's own (`Rules.targetings`). `none` for a name nothing defines
|
|
123
|
+
*
|
|
124
|
+
* @beta
|
|
125
|
+
*/
|
|
126
|
+
export declare function aimKind(registry: {
|
|
127
|
+
readonly targetings: {
|
|
128
|
+
has(id: string): boolean;
|
|
129
|
+
get(id: string): Targeting;
|
|
130
|
+
};
|
|
131
|
+
}, ability: AbilityDef): AimKind;
|
|
132
|
+
/**
|
|
133
|
+
* A game's own way of aiming an ability (`Rules.targetings`), where its `target` names one
|
|
134
|
+
*
|
|
135
|
+
* @beta
|
|
136
|
+
*/
|
|
137
|
+
export declare function targetingOf(registry: {
|
|
138
|
+
readonly targetings: {
|
|
139
|
+
has(id: string): boolean;
|
|
140
|
+
get(id: string): Targeting;
|
|
141
|
+
};
|
|
142
|
+
}, ability: AbilityDef): Targeting | undefined;
|