@v12-engine/engine 0.1.1 → 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,283 @@
|
|
|
1
|
+
import { hypot } from "./exactMath.js";
|
|
2
|
+
import { footprintOf } from "./defs.js";
|
|
3
|
+
import { BuildGrid } from "./grid.js";
|
|
4
|
+
import { mapTerrain } from "./map/terrain.js";
|
|
5
|
+
import { mapCells } from "./mapCheck/cells.js";
|
|
6
|
+
//#region src/mapMeasure.ts
|
|
7
|
+
function walking(map, registry) {
|
|
8
|
+
const { width, depth, levels, ramps } = map;
|
|
9
|
+
const { open } = mapCells(map, registry, mapTerrain(map), true);
|
|
10
|
+
const cellAt = (point) => {
|
|
11
|
+
const cx = Math.floor(point.x);
|
|
12
|
+
const cz = Math.floor(point.z);
|
|
13
|
+
for (let r = 0; r <= 6; r++) for (let z = cz - r; z <= cz + r; z++) for (let x = cx - r; x <= cx + r; x++) {
|
|
14
|
+
if (x < 0 || z < 0 || x >= width || z >= depth || Math.max(Math.abs(x - cx), Math.abs(z - cz)) !== r) continue;
|
|
15
|
+
if (open[z * width + x]) return z * width + x;
|
|
16
|
+
}
|
|
17
|
+
return -1;
|
|
18
|
+
};
|
|
19
|
+
return {
|
|
20
|
+
width,
|
|
21
|
+
depth,
|
|
22
|
+
open,
|
|
23
|
+
passable: (a, b) => levels[a] === levels[b] || ramps[a] > 0 || ramps[b] > 0,
|
|
24
|
+
cellAt
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/** The way on foot between two cells: A* over the cells, eight ways, corners not cut. Nothing when there is none */
|
|
28
|
+
function walk(walking, from, to) {
|
|
29
|
+
const { width, depth, open, passable } = walking;
|
|
30
|
+
if (from < 0 || to < 0) return void 0;
|
|
31
|
+
const cells = width * depth;
|
|
32
|
+
const cost = new Float32Array(cells).fill(Infinity);
|
|
33
|
+
const came = new Int32Array(cells).fill(-1);
|
|
34
|
+
const closed = new Uint8Array(cells);
|
|
35
|
+
const tx = to % width;
|
|
36
|
+
const tz = Math.floor(to / width);
|
|
37
|
+
const guess = (c) => {
|
|
38
|
+
const dx = Math.abs(c % width - tx);
|
|
39
|
+
const dz = Math.abs(Math.floor(c / width) - tz);
|
|
40
|
+
return Math.max(dx, dz) + (Math.SQRT2 - 1) * Math.min(dx, dz);
|
|
41
|
+
};
|
|
42
|
+
const heap = [];
|
|
43
|
+
const score = new Float32Array(cells);
|
|
44
|
+
const push = (c) => {
|
|
45
|
+
heap.push(c);
|
|
46
|
+
let i = heap.length - 1;
|
|
47
|
+
while (i > 0) {
|
|
48
|
+
const parent = i - 1 >> 1;
|
|
49
|
+
if (score[heap[parent]] <= score[heap[i]]) break;
|
|
50
|
+
[heap[parent], heap[i]] = [heap[i], heap[parent]];
|
|
51
|
+
i = parent;
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
const pop = () => {
|
|
55
|
+
const top = heap[0];
|
|
56
|
+
const last = heap.pop();
|
|
57
|
+
if (heap.length) {
|
|
58
|
+
heap[0] = last;
|
|
59
|
+
let i = 0;
|
|
60
|
+
for (;;) {
|
|
61
|
+
const left = i * 2 + 1;
|
|
62
|
+
const right = left + 1;
|
|
63
|
+
let least = i;
|
|
64
|
+
if (left < heap.length && score[heap[left]] < score[heap[least]]) least = left;
|
|
65
|
+
if (right < heap.length && score[heap[right]] < score[heap[least]]) least = right;
|
|
66
|
+
if (least === i) break;
|
|
67
|
+
[heap[least], heap[i]] = [heap[i], heap[least]];
|
|
68
|
+
i = least;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return top;
|
|
72
|
+
};
|
|
73
|
+
cost[from] = 0;
|
|
74
|
+
score[from] = guess(from);
|
|
75
|
+
push(from);
|
|
76
|
+
while (heap.length) {
|
|
77
|
+
const c = pop();
|
|
78
|
+
if (closed[c]) continue;
|
|
79
|
+
if (c === to) break;
|
|
80
|
+
closed[c] = 1;
|
|
81
|
+
const x = c % width;
|
|
82
|
+
const z = (c - x) / width;
|
|
83
|
+
for (let dz = -1; dz <= 1; dz++) for (let dx = -1; dx <= 1; dx++) {
|
|
84
|
+
if (!dx && !dz) continue;
|
|
85
|
+
const nx = x + dx;
|
|
86
|
+
const nz = z + dz;
|
|
87
|
+
if (nx < 0 || nz < 0 || nx >= width || nz >= depth) continue;
|
|
88
|
+
const n = nz * width + nx;
|
|
89
|
+
if (!open[n] || closed[n] || !passable(c, n)) continue;
|
|
90
|
+
if (dx && dz) {
|
|
91
|
+
const side1 = z * width + nx;
|
|
92
|
+
const side2 = nz * width + x;
|
|
93
|
+
if (!open[side1] || !open[side2] || !passable(c, side1) || !passable(c, side2)) continue;
|
|
94
|
+
}
|
|
95
|
+
const next = cost[c] + (dx && dz ? Math.SQRT2 : 1);
|
|
96
|
+
if (next >= cost[n]) continue;
|
|
97
|
+
cost[n] = next;
|
|
98
|
+
came[n] = c;
|
|
99
|
+
score[n] = next + guess(n);
|
|
100
|
+
push(n);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (!Number.isFinite(cost[to])) return void 0;
|
|
104
|
+
const points = [];
|
|
105
|
+
for (let c = to; c >= 0; c = came[c]) points.push({
|
|
106
|
+
x: c % width + .5,
|
|
107
|
+
z: Math.floor(c / width) + .5
|
|
108
|
+
});
|
|
109
|
+
return {
|
|
110
|
+
length: cost[to],
|
|
111
|
+
points: points.reverse()
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* The way on foot between two points of a map, with what the checks count as in the way. Nothing when there is none
|
|
116
|
+
*
|
|
117
|
+
* @beta
|
|
118
|
+
*/
|
|
119
|
+
function walkBetween(map, registry, from, to) {
|
|
120
|
+
const cells = walking(map, registry);
|
|
121
|
+
return walk(cells, cells.cellAt(from), cells.cellAt(to));
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* How many cells each open cell is from what is not: half the width of the way there. A passage two cells wide has
|
|
125
|
+
* cells 1 from its sides in its middle
|
|
126
|
+
*/
|
|
127
|
+
function clearance(walking) {
|
|
128
|
+
const { width, depth, open } = walking;
|
|
129
|
+
const far = new Float32Array(width * depth);
|
|
130
|
+
for (let c = 0; c < far.length; c++) far[c] = open[c] ? Infinity : 0;
|
|
131
|
+
const step = (c, x, z, dx, dz, weight) => {
|
|
132
|
+
const nx = x + dx;
|
|
133
|
+
const nz = z + dz;
|
|
134
|
+
const next = nx < 0 || nz < 0 || nx >= width || nz >= depth ? 0 : far[nz * width + nx];
|
|
135
|
+
if (next + weight < far[c]) far[c] = next + weight;
|
|
136
|
+
};
|
|
137
|
+
for (let z = 0; z < depth; z++) for (let x = 0; x < width; x++) {
|
|
138
|
+
const c = z * width + x;
|
|
139
|
+
if (!far[c]) continue;
|
|
140
|
+
step(c, x, z, -1, 0, 1);
|
|
141
|
+
step(c, x, z, 0, -1, 1);
|
|
142
|
+
step(c, x, z, -1, -1, Math.SQRT2);
|
|
143
|
+
step(c, x, z, 1, -1, Math.SQRT2);
|
|
144
|
+
}
|
|
145
|
+
for (let z = depth - 1; z >= 0; z--) for (let x = width - 1; x >= 0; x--) {
|
|
146
|
+
const c = z * width + x;
|
|
147
|
+
if (!far[c]) continue;
|
|
148
|
+
step(c, x, z, 1, 0, 1);
|
|
149
|
+
step(c, x, z, 0, 1, 1);
|
|
150
|
+
step(c, x, z, 1, 1, Math.SQRT2);
|
|
151
|
+
step(c, x, z, -1, 1, Math.SQRT2);
|
|
152
|
+
}
|
|
153
|
+
return far;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* How far around a start counts as its ground, for building and trees
|
|
157
|
+
*
|
|
158
|
+
* @beta
|
|
159
|
+
*/
|
|
160
|
+
var BUILD_REACH = 16;
|
|
161
|
+
/**
|
|
162
|
+
* How much more one start can have of something than another before it is not fair, as a part
|
|
163
|
+
*
|
|
164
|
+
* @internal
|
|
165
|
+
*/
|
|
166
|
+
var FAIR_MARGIN = .15;
|
|
167
|
+
/** The ends of a way, in cells, where the bases stand: the narrowest place is looked for between them */
|
|
168
|
+
var BASE_ROOM = 8;
|
|
169
|
+
/**
|
|
170
|
+
* What a map is like to play on: the way on foot between every two starts, the narrowest place on those ways, and for
|
|
171
|
+
* each start the nearest mine and how much it holds, the ground around it that can be built on, and its trees; side
|
|
172
|
+
* by side, with what one start has much more of than another said. Then what the game measures of its own
|
|
173
|
+
*
|
|
174
|
+
* @beta
|
|
175
|
+
*/
|
|
176
|
+
function measureMap(map, registry) {
|
|
177
|
+
const cells = walking(map, registry);
|
|
178
|
+
const terrain = mapTerrain(map);
|
|
179
|
+
const grid = new BuildGrid(terrain);
|
|
180
|
+
const { built } = mapCells(map, registry, terrain);
|
|
181
|
+
const starts = map.players.filter((player) => player.start);
|
|
182
|
+
const rushes = [];
|
|
183
|
+
for (let i = 0; i < starts.length; i++) for (let j = i + 1; j < starts.length; j++) {
|
|
184
|
+
const way = walk(cells, cells.cellAt(starts[i].start), cells.cellAt(starts[j].start));
|
|
185
|
+
rushes.push({
|
|
186
|
+
from: starts[i].id,
|
|
187
|
+
to: starts[j].id,
|
|
188
|
+
...way && {
|
|
189
|
+
length: Math.round(way.length * 10) / 10,
|
|
190
|
+
points: way.points
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
const far = clearance(cells);
|
|
195
|
+
let narrowest;
|
|
196
|
+
for (const rush of rushes) {
|
|
197
|
+
const points = rush.points ?? [];
|
|
198
|
+
for (let i = BASE_ROOM; i < points.length - BASE_ROOM; i++) {
|
|
199
|
+
const c = Math.floor(points[i].z) * cells.width + Math.floor(points[i].x);
|
|
200
|
+
const width = Math.round((far[c] * 2 - 1) * 10) / 10;
|
|
201
|
+
if (!narrowest || width < narrowest.width) narrowest = {
|
|
202
|
+
width,
|
|
203
|
+
at: points[i]
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
const mines = map.objects.filter((object) => {
|
|
208
|
+
if (!registry.units.has(object.type)) return false;
|
|
209
|
+
const def = registry.unit(object.type);
|
|
210
|
+
return def.kind === "resource" && footprintOf(def).w >= 2;
|
|
211
|
+
});
|
|
212
|
+
const measures = starts.map((player) => {
|
|
213
|
+
const start = player.start;
|
|
214
|
+
const from = cells.cellAt(start);
|
|
215
|
+
let mine;
|
|
216
|
+
for (const object of mines) {
|
|
217
|
+
const way = walk(cells, from, cells.cellAt(object));
|
|
218
|
+
if (!way || mine && way.length >= mine.distance) continue;
|
|
219
|
+
const def = registry.unit(object.type);
|
|
220
|
+
mine = {
|
|
221
|
+
distance: Math.round(way.length * 10) / 10,
|
|
222
|
+
amount: object.amount ?? def.resource?.amount ?? 0,
|
|
223
|
+
at: {
|
|
224
|
+
x: object.x,
|
|
225
|
+
z: object.z
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
let buildable = 0;
|
|
230
|
+
for (let z = Math.floor(start.z - 16); z <= Math.ceil(start.z + 16); z++) for (let x = Math.floor(start.x - 16); x <= Math.ceil(start.x + 16); x++) {
|
|
231
|
+
if (hypot(x + .5 - start.x, z + .5 - start.z) > 16) continue;
|
|
232
|
+
if (grid.isBuildable(x, z) && !built[z * map.width + x]) buildable++;
|
|
233
|
+
}
|
|
234
|
+
const trees = map.objects.filter((object) => {
|
|
235
|
+
if (!registry.units.has(object.type) || hypot(object.x - start.x, object.z - start.z) > 16) return false;
|
|
236
|
+
const def = registry.unit(object.type);
|
|
237
|
+
return def.kind === "resource" && footprintOf(def).w < 2;
|
|
238
|
+
}).length;
|
|
239
|
+
return {
|
|
240
|
+
player: player.id,
|
|
241
|
+
name: player.name,
|
|
242
|
+
...mine && { mine },
|
|
243
|
+
buildable,
|
|
244
|
+
trees
|
|
245
|
+
};
|
|
246
|
+
});
|
|
247
|
+
const unfair = [];
|
|
248
|
+
const compare = (what, value, more = "more") => {
|
|
249
|
+
const known = measures.map((start) => ({
|
|
250
|
+
start,
|
|
251
|
+
value: value(start)
|
|
252
|
+
})).filter((entry) => entry.value !== void 0);
|
|
253
|
+
if (known.length < 2) return;
|
|
254
|
+
const most = known.reduce((a, b) => b.value > a.value ? b : a);
|
|
255
|
+
const least = known.reduce((a, b) => b.value < a.value ? b : a);
|
|
256
|
+
if (most.value > least.value * 1.15 && most.value - least.value > 1) unfair.push(`${most.start.name} has ${more} ${what} than ${least.start.name}: ${most.value} against ${least.value}`);
|
|
257
|
+
};
|
|
258
|
+
compare("way to their nearest mine", (start) => start.mine?.distance, "a longer");
|
|
259
|
+
compare("gold in their nearest mine", (start) => start.mine?.amount);
|
|
260
|
+
compare("ground to build on", (start) => start.buildable);
|
|
261
|
+
compare("trees near their start", (start) => start.trees);
|
|
262
|
+
return {
|
|
263
|
+
rushes: rushes.map(({ points: _, ...rush }) => rush),
|
|
264
|
+
...narrowest && { narrowest },
|
|
265
|
+
starts: measures,
|
|
266
|
+
unfair,
|
|
267
|
+
game: registry.module?.editor?.measure?.(map, registry) ?? []
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Seconds a unit type takes over a way on foot, at the speed it starts with
|
|
272
|
+
*
|
|
273
|
+
* @beta
|
|
274
|
+
*/
|
|
275
|
+
var walkingTime = (registry, type, length) => {
|
|
276
|
+
if (!registry.units.has(type)) return void 0;
|
|
277
|
+
const speed = registry.unit(type).stats.moveSpeed ?? 0;
|
|
278
|
+
return speed > 0 ? Math.round(length / speed * 10) / 10 : void 0;
|
|
279
|
+
};
|
|
280
|
+
//#endregion
|
|
281
|
+
export { BUILD_REACH, FAIR_MARGIN, measureMap, walkBetween, walkingTime };
|
|
282
|
+
|
|
283
|
+
//# sourceMappingURL=mapMeasure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mapMeasure.js","names":[],"sources":["../src/mapMeasure.ts"],"sourcesContent":["import { footprintOf } from './defs'\nimport type { PlayerId } from './entity'\nimport { BuildGrid, footprintCell } from './grid'\nimport { type GameMap, mapTerrain } from './map'\nimport { mapCells } from './mapCheck'\nimport type { Vec2 } from './math'\nimport type { Registry } from './registry'\nimport { hypot } from './exactMath'\n\n/**\n * A way on foot over a map: its length, and the points it goes through\n *\n * @beta\n */\nexport interface Walk {\n\t/** The length of the way, in cells */\n\tlength: number\n\t/** The points the way goes through, from its start to its end */\n\tpoints: Vec2[]\n}\n\n/** How the cells of a map are walked: which are open, and between which a step is no cliff */\ninterface Walking {\n\twidth: number\n\tdepth: number\n\topen: Uint8Array\n\tpassable(a: number, b: number): boolean\n\t/** The open cell nearest a point, for what stands on cells nothing walks on, or -1 */\n\tcellAt(point: Vec2): number\n}\n\nfunction walking(map: GameMap, registry: Registry): Walking {\n\tconst { width, depth, levels, ramps } = map\n\tconst { open } = mapCells(map, registry, mapTerrain(map), true)\n\tconst cellAt = (point: Vec2) => {\n\t\tconst cx = Math.floor(point.x)\n\t\tconst cz = Math.floor(point.z)\n\t\tfor (let r = 0; r <= 6; r++) {\n\t\t\tfor (let z = cz - r; z <= cz + r; z++) {\n\t\t\t\tfor (let x = cx - r; x <= cx + r; x++) {\n\t\t\t\t\tif (x < 0 || z < 0 || x >= width || z >= depth || Math.max(Math.abs(x - cx), Math.abs(z - cz)) !== r) continue\n\t\t\t\t\tif (open[z * width + x]) return z * width + x\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn -1\n\t}\n\treturn { width, depth, open, passable: (a, b) => levels[a] === levels[b] || ramps[a] > 0 || ramps[b] > 0, cellAt }\n}\n\n/** The way on foot between two cells: A* over the cells, eight ways, corners not cut. Nothing when there is none */\nfunction walk(walking: Walking, from: number, to: number): Walk | undefined {\n\tconst { width, depth, open, passable } = walking\n\tif (from < 0 || to < 0) return undefined\n\tconst cells = width * depth\n\tconst cost = new Float32Array(cells).fill(Infinity)\n\tconst came = new Int32Array(cells).fill(-1)\n\tconst closed = new Uint8Array(cells)\n\tconst tx = to % width\n\tconst tz = Math.floor(to / width)\n\tconst guess = (c: number) => {\n\t\tconst dx = Math.abs((c % width) - tx)\n\t\tconst dz = Math.abs(Math.floor(c / width) - tz)\n\t\treturn Math.max(dx, dz) + (Math.SQRT2 - 1) * Math.min(dx, dz)\n\t}\n\t// a binary heap of cells by cost and guess\n\tconst heap: number[] = []\n\tconst score = new Float32Array(cells)\n\tconst push = (c: number) => {\n\t\theap.push(c)\n\t\tlet i = heap.length - 1\n\t\twhile (i > 0) {\n\t\t\tconst parent = (i - 1) >> 1\n\t\t\tif (score[heap[parent]] <= score[heap[i]]) break\n\t\t\t;[heap[parent], heap[i]] = [heap[i], heap[parent]]\n\t\t\ti = parent\n\t\t}\n\t}\n\tconst pop = () => {\n\t\tconst top = heap[0]\n\t\tconst last = heap.pop()!\n\t\tif (heap.length) {\n\t\t\theap[0] = last\n\t\t\tlet i = 0\n\t\t\tfor (;;) {\n\t\t\t\tconst left = i * 2 + 1\n\t\t\t\tconst right = left + 1\n\t\t\t\tlet least = i\n\t\t\t\tif (left < heap.length && score[heap[left]] < score[heap[least]]) least = left\n\t\t\t\tif (right < heap.length && score[heap[right]] < score[heap[least]]) least = right\n\t\t\t\tif (least === i) break\n\t\t\t\t;[heap[least], heap[i]] = [heap[i], heap[least]]\n\t\t\t\ti = least\n\t\t\t}\n\t\t}\n\t\treturn top\n\t}\n\tcost[from] = 0\n\tscore[from] = guess(from)\n\tpush(from)\n\twhile (heap.length) {\n\t\tconst c = pop()\n\t\tif (closed[c]) continue\n\t\tif (c === to) break\n\t\tclosed[c] = 1\n\t\tconst x = c % width\n\t\tconst z = (c - x) / width\n\t\tfor (let dz = -1; dz <= 1; dz++) {\n\t\t\tfor (let dx = -1; dx <= 1; dx++) {\n\t\t\t\tif (!dx && !dz) continue\n\t\t\t\tconst nx = x + dx\n\t\t\t\tconst nz = z + dz\n\t\t\t\tif (nx < 0 || nz < 0 || nx >= width || nz >= depth) continue\n\t\t\t\tconst n = nz * width + nx\n\t\t\t\tif (!open[n] || closed[n] || !passable(c, n)) continue\n\t\t\t\t// a diagonal step only past two open cells: no cutting the corner of a cliff\n\t\t\t\tif (dx && dz) {\n\t\t\t\t\tconst side1 = z * width + nx\n\t\t\t\t\tconst side2 = nz * width + x\n\t\t\t\t\tif (!open[side1] || !open[side2] || !passable(c, side1) || !passable(c, side2)) continue\n\t\t\t\t}\n\t\t\t\tconst next = cost[c] + (dx && dz ? Math.SQRT2 : 1)\n\t\t\t\tif (next >= cost[n]) continue\n\t\t\t\tcost[n] = next\n\t\t\t\tcame[n] = c\n\t\t\t\tscore[n] = next + guess(n)\n\t\t\t\tpush(n)\n\t\t\t}\n\t\t}\n\t}\n\tif (!Number.isFinite(cost[to])) return undefined\n\tconst points: Vec2[] = []\n\tfor (let c = to; c >= 0; c = came[c]) points.push({ x: (c % width) + 0.5, z: Math.floor(c / width) + 0.5 })\n\treturn { length: cost[to], points: points.reverse() }\n}\n\n/**\n * The way on foot between two points of a map, with what the checks count as in the way. Nothing when there is none\n *\n * @beta\n */\nexport function walkBetween(map: GameMap, registry: Registry, from: Vec2, to: Vec2): Walk | undefined {\n\tconst cells = walking(map, registry)\n\treturn walk(cells, cells.cellAt(from), cells.cellAt(to))\n}\n\n/**\n * How many cells each open cell is from what is not: half the width of the way there. A passage two cells wide has\n * cells 1 from its sides in its middle\n */\nfunction clearance(walking: Walking): Float32Array {\n\tconst { width, depth, open } = walking\n\tconst far = new Float32Array(width * depth)\n\tfor (let c = 0; c < far.length; c++) far[c] = open[c] ? Infinity : 0\n\t// two passes of a chamfer distance, eight ways\n\tconst step = (c: number, x: number, z: number, dx: number, dz: number, weight: number) => {\n\t\tconst nx = x + dx\n\t\tconst nz = z + dz\n\t\tconst next = nx < 0 || nz < 0 || nx >= width || nz >= depth ? 0 : far[nz * width + nx]\n\t\tif (next + weight < far[c]) far[c] = next + weight\n\t}\n\tfor (let z = 0; z < depth; z++) {\n\t\tfor (let x = 0; x < width; x++) {\n\t\t\tconst c = z * width + x\n\t\t\tif (!far[c]) continue\n\t\t\tstep(c, x, z, -1, 0, 1)\n\t\t\tstep(c, x, z, 0, -1, 1)\n\t\t\tstep(c, x, z, -1, -1, Math.SQRT2)\n\t\t\tstep(c, x, z, 1, -1, Math.SQRT2)\n\t\t}\n\t}\n\tfor (let z = depth - 1; z >= 0; z--) {\n\t\tfor (let x = width - 1; x >= 0; x--) {\n\t\t\tconst c = z * width + x\n\t\t\tif (!far[c]) continue\n\t\t\tstep(c, x, z, 1, 0, 1)\n\t\t\tstep(c, x, z, 0, 1, 1)\n\t\t\tstep(c, x, z, 1, 1, Math.SQRT2)\n\t\t\tstep(c, x, z, -1, 1, Math.SQRT2)\n\t\t}\n\t}\n\treturn far\n}\n\n/**\n * What one player's start has around it\n *\n * @beta\n */\nexport interface StartMeasure {\n\t/** The player the start is for */\n\tplayer: PlayerId\n\t/** The start's name, as the map names its player */\n\tname: string\n\t/** The way on foot to the nearest mine, and how much it holds. Nothing without a mine they can walk to */\n\tmine?: { distance: number; amount: number; at: Vec2 }\n\t/** How many cells within `BUILD_REACH` of the start can be built on */\n\tbuildable: number\n\t/** Trees within `BUILD_REACH` of the start */\n\ttrees: number\n}\n\n/**\n * A number of a map a game measures of its own (`MapEditorDef.measure`): the length of the road, for a tower defense\n *\n * @beta\n */\nexport interface GameMeasure {\n\t/** The name of the measure, as the editor shows it */\n\tname: string\n\t/** The measured number or text */\n\tvalue: number | string\n}\n\n/**\n * What a map is like to play on, measured (see `measureMap`)\n *\n * @beta\n */\nexport interface MapReport {\n\t/** The way on foot between every two starts: how far a rush goes. Nothing for starts cut off from each other */\n\trushes: { from: PlayerId; to: PlayerId; length?: number; points?: Vec2[] }[]\n\t/** The narrowest place on the ways between the starts, and how wide it is */\n\tnarrowest?: { width: number; at: Vec2 }\n\t/** The measure of every player's start */\n\tstarts: StartMeasure[]\n\t/** What each start has that another has more than `FAIR_MARGIN` more of: what is not fair */\n\tunfair: string[]\n\t/** The numbers the game measures of its own (`MapEditorDef.measure`) */\n\tgame: GameMeasure[]\n}\n\n/**\n * How far around a start counts as its ground, for building and trees\n *\n * @beta\n */\nexport const BUILD_REACH = 16\n/**\n * How much more one start can have of something than another before it is not fair, as a part\n *\n * @internal\n */\nexport const FAIR_MARGIN = 0.15\n/** The ends of a way, in cells, where the bases stand: the narrowest place is looked for between them */\nconst BASE_ROOM = 8\n\n/**\n * What a map is like to play on: the way on foot between every two starts, the narrowest place on those ways, and for\n * each start the nearest mine and how much it holds, the ground around it that can be built on, and its trees; side\n * by side, with what one start has much more of than another said. Then what the game measures of its own\n *\n * @beta\n */\nexport function measureMap(map: GameMap, registry: Registry): MapReport {\n\tconst cells = walking(map, registry)\n\tconst terrain = mapTerrain(map)\n\tconst grid = new BuildGrid(terrain)\n\tconst { built } = mapCells(map, registry, terrain)\n\tconst starts = map.players.filter((player) => player.start)\n\tconst rushes: MapReport['rushes'] = []\n\tfor (let i = 0; i < starts.length; i++) {\n\t\tfor (let j = i + 1; j < starts.length; j++) {\n\t\t\tconst way = walk(cells, cells.cellAt(starts[i].start!), cells.cellAt(starts[j].start!))\n\t\t\trushes.push({ from: starts[i].id, to: starts[j].id, ...(way && { length: Math.round(way.length * 10) / 10, points: way.points }) })\n\t\t}\n\t}\n\t// the narrowest place on the ways between the bases, not in the bases\n\tconst far = clearance(cells)\n\tlet narrowest: MapReport['narrowest']\n\tfor (const rush of rushes) {\n\t\tconst points = rush.points ?? []\n\t\tfor (let i = BASE_ROOM; i < points.length - BASE_ROOM; i++) {\n\t\t\tconst c = Math.floor(points[i].z) * cells.width + Math.floor(points[i].x)\n\t\t\tconst width = Math.round((far[c] * 2 - 1) * 10) / 10\n\t\t\tif (!narrowest || width < narrowest.width) narrowest = { width, at: points[i] }\n\t\t}\n\t}\n\tconst mines = map.objects.filter((object) => {\n\t\tif (!registry.units.has(object.type)) return false\n\t\tconst def = registry.unit(object.type)\n\t\treturn def.kind === 'resource' && footprintOf(def).w >= 2\n\t})\n\tconst measures: StartMeasure[] = starts.map((player) => {\n\t\tconst start = player.start!\n\t\tconst from = cells.cellAt(start)\n\t\tlet mine: StartMeasure['mine']\n\t\tfor (const object of mines) {\n\t\t\tconst way = walk(cells, from, cells.cellAt(object))\n\t\t\tif (!way || (mine && way.length >= mine.distance)) continue\n\t\t\tconst def = registry.unit(object.type)\n\t\t\tmine = { distance: Math.round(way.length * 10) / 10, amount: object.amount ?? def.resource?.amount ?? 0, at: { x: object.x, z: object.z } }\n\t\t}\n\t\tlet buildable = 0\n\t\tfor (let z = Math.floor(start.z - BUILD_REACH); z <= Math.ceil(start.z + BUILD_REACH); z++) {\n\t\t\tfor (let x = Math.floor(start.x - BUILD_REACH); x <= Math.ceil(start.x + BUILD_REACH); x++) {\n\t\t\t\tif (hypot(x + 0.5 - start.x, z + 0.5 - start.z) > BUILD_REACH) continue\n\t\t\t\tif (grid.isBuildable(x, z) && !built[z * map.width + x]) buildable++\n\t\t\t}\n\t\t}\n\t\tconst trees = map.objects.filter((object) => {\n\t\t\tif (!registry.units.has(object.type) || hypot(object.x - start.x, object.z - start.z) > BUILD_REACH) return false\n\t\t\tconst def = registry.unit(object.type)\n\t\t\treturn def.kind === 'resource' && footprintOf(def).w < 2\n\t\t}).length\n\t\treturn { player: player.id, name: player.name, ...(mine && { mine }), buildable, trees }\n\t})\n\t// what is not fair: one start with much more of something than another\n\tconst unfair: string[] = []\n\tconst compare = (what: string, value: (start: StartMeasure) => number | undefined, more = 'more') => {\n\t\tconst values = measures.map((start) => ({ start, value: value(start) }))\n\t\tconst known = values.filter((entry) => entry.value !== undefined) as { start: StartMeasure; value: number }[]\n\t\tif (known.length < 2) return\n\t\tconst most = known.reduce((a, b) => (b.value > a.value ? b : a))\n\t\tconst least = known.reduce((a, b) => (b.value < a.value ? b : a))\n\t\tif (most.value > least.value * (1 + FAIR_MARGIN) && most.value - least.value > 1) {\n\t\t\tunfair.push(`${most.start.name} has ${more} ${what} than ${least.start.name}: ${most.value} against ${least.value}`)\n\t\t}\n\t}\n\tcompare('way to their nearest mine', (start) => start.mine?.distance, 'a longer')\n\tcompare('gold in their nearest mine', (start) => start.mine?.amount)\n\tcompare('ground to build on', (start) => start.buildable)\n\tcompare('trees near their start', (start) => start.trees)\n\treturn {\n\t\trushes: rushes.map(({ points: _, ...rush }) => rush),\n\t\t...(narrowest && { narrowest }),\n\t\tstarts: measures,\n\t\tunfair,\n\t\tgame: registry.module?.editor?.measure?.(map, registry) ?? []\n\t}\n}\n\n/**\n * Seconds a unit type takes over a way on foot, at the speed it starts with\n *\n * @beta\n */\nexport const walkingTime = (registry: Registry, type: string, length: number): number | undefined => {\n\tif (!registry.units.has(type)) return undefined\n\tconst speed = registry.unit(type).stats.moveSpeed ?? 0\n\treturn speed > 0 ? Math.round((length / speed) * 10) / 10 : undefined\n}\n\n/** The cell of a footprint, for drawing where a mine stands */\nexport const footprintAt = (registry: Registry, type: string, at: Vec2) => {\n\tconst { w, d } = footprintOf(registry.unit(type))\n\treturn footprintCell(at.x, at.z, w, d)\n}\n"],"mappings":";;;;;;AA+BA,SAAS,QAAQ,KAAc,UAA6B;CAC3D,MAAM,EAAE,OAAO,OAAO,QAAQ,UAAU;CACxC,MAAM,EAAE,SAAS,SAAS,KAAK,UAAU,WAAW,GAAG,GAAG,IAAI;CAC9D,MAAM,UAAU,UAAgB;EAC/B,MAAM,KAAK,KAAK,MAAM,MAAM,CAAC;EAC7B,MAAM,KAAK,KAAK,MAAM,MAAM,CAAC;EAC7B,KAAK,IAAI,IAAI,GAAG,KAAK,GAAG,KACvB,KAAK,IAAI,IAAI,KAAK,GAAG,KAAK,KAAK,GAAG,KACjC,KAAK,IAAI,IAAI,KAAK,GAAG,KAAK,KAAK,GAAG,KAAK;GACtC,IAAI,IAAI,KAAK,IAAI,KAAK,KAAK,SAAS,KAAK,SAAS,KAAK,IAAI,KAAK,IAAI,IAAI,EAAE,GAAG,KAAK,IAAI,IAAI,EAAE,CAAC,MAAM,GAAG;GACtG,IAAI,KAAK,IAAI,QAAQ,IAAI,OAAO,IAAI,QAAQ;EAC7C;EAGF,OAAO;CACR;CACA,OAAO;EAAE;EAAO;EAAO;EAAM,WAAW,GAAG,MAAM,OAAO,OAAO,OAAO,MAAM,MAAM,KAAK,KAAK,MAAM,KAAK;EAAG;CAAO;AAClH;;AAGA,SAAS,KAAK,SAAkB,MAAc,IAA8B;CAC3E,MAAM,EAAE,OAAO,OAAO,MAAM,aAAa;CACzC,IAAI,OAAO,KAAK,KAAK,GAAG,OAAO,KAAA;CAC/B,MAAM,QAAQ,QAAQ;CACtB,MAAM,OAAO,IAAI,aAAa,KAAK,CAAC,CAAC,KAAK,QAAQ;CAClD,MAAM,OAAO,IAAI,WAAW,KAAK,CAAC,CAAC,KAAK,EAAE;CAC1C,MAAM,SAAS,IAAI,WAAW,KAAK;CACnC,MAAM,KAAK,KAAK;CAChB,MAAM,KAAK,KAAK,MAAM,KAAK,KAAK;CAChC,MAAM,SAAS,MAAc;EAC5B,MAAM,KAAK,KAAK,IAAK,IAAI,QAAS,EAAE;EACpC,MAAM,KAAK,KAAK,IAAI,KAAK,MAAM,IAAI,KAAK,IAAI,EAAE;EAC9C,OAAO,KAAK,IAAI,IAAI,EAAE,KAAK,KAAK,QAAQ,KAAK,KAAK,IAAI,IAAI,EAAE;CAC7D;CAEA,MAAM,OAAiB,CAAC;CACxB,MAAM,QAAQ,IAAI,aAAa,KAAK;CACpC,MAAM,QAAQ,MAAc;EAC3B,KAAK,KAAK,CAAC;EACX,IAAI,IAAI,KAAK,SAAS;EACtB,OAAO,IAAI,GAAG;GACb,MAAM,SAAU,IAAI,KAAM;GAC1B,IAAI,MAAM,KAAK,YAAY,MAAM,KAAK,KAAK;GAC1C,CAAC,KAAK,SAAS,KAAK,MAAM,CAAC,KAAK,IAAI,KAAK,OAAO;GACjD,IAAI;EACL;CACD;CACA,MAAM,YAAY;EACjB,MAAM,MAAM,KAAK;EACjB,MAAM,OAAO,KAAK,IAAI;EACtB,IAAI,KAAK,QAAQ;GAChB,KAAK,KAAK;GACV,IAAI,IAAI;GACR,SAAS;IACR,MAAM,OAAO,IAAI,IAAI;IACrB,MAAM,QAAQ,OAAO;IACrB,IAAI,QAAQ;IACZ,IAAI,OAAO,KAAK,UAAU,MAAM,KAAK,SAAS,MAAM,KAAK,SAAS,QAAQ;IAC1E,IAAI,QAAQ,KAAK,UAAU,MAAM,KAAK,UAAU,MAAM,KAAK,SAAS,QAAQ;IAC5E,IAAI,UAAU,GAAG;IAChB,CAAC,KAAK,QAAQ,KAAK,MAAM,CAAC,KAAK,IAAI,KAAK,MAAM;IAC/C,IAAI;GACL;EACD;EACA,OAAO;CACR;CACA,KAAK,QAAQ;CACb,MAAM,QAAQ,MAAM,IAAI;CACxB,KAAK,IAAI;CACT,OAAO,KAAK,QAAQ;EACnB,MAAM,IAAI,IAAI;EACd,IAAI,OAAO,IAAI;EACf,IAAI,MAAM,IAAI;EACd,OAAO,KAAK;EACZ,MAAM,IAAI,IAAI;EACd,MAAM,KAAK,IAAI,KAAK;EACpB,KAAK,IAAI,KAAK,IAAI,MAAM,GAAG,MAC1B,KAAK,IAAI,KAAK,IAAI,MAAM,GAAG,MAAM;GAChC,IAAI,CAAC,MAAM,CAAC,IAAI;GAChB,MAAM,KAAK,IAAI;GACf,MAAM,KAAK,IAAI;GACf,IAAI,KAAK,KAAK,KAAK,KAAK,MAAM,SAAS,MAAM,OAAO;GACpD,MAAM,IAAI,KAAK,QAAQ;GACvB,IAAI,CAAC,KAAK,MAAM,OAAO,MAAM,CAAC,SAAS,GAAG,CAAC,GAAG;GAE9C,IAAI,MAAM,IAAI;IACb,MAAM,QAAQ,IAAI,QAAQ;IAC1B,MAAM,QAAQ,KAAK,QAAQ;IAC3B,IAAI,CAAC,KAAK,UAAU,CAAC,KAAK,UAAU,CAAC,SAAS,GAAG,KAAK,KAAK,CAAC,SAAS,GAAG,KAAK,GAAG;GACjF;GACA,MAAM,OAAO,KAAK,MAAM,MAAM,KAAK,KAAK,QAAQ;GAChD,IAAI,QAAQ,KAAK,IAAI;GACrB,KAAK,KAAK;GACV,KAAK,KAAK;GACV,MAAM,KAAK,OAAO,MAAM,CAAC;GACzB,KAAK,CAAC;EACP;CAEF;CACA,IAAI,CAAC,OAAO,SAAS,KAAK,GAAG,GAAG,OAAO,KAAA;CACvC,MAAM,SAAiB,CAAC;CACxB,KAAK,IAAI,IAAI,IAAI,KAAK,GAAG,IAAI,KAAK,IAAI,OAAO,KAAK;EAAE,GAAI,IAAI,QAAS;EAAK,GAAG,KAAK,MAAM,IAAI,KAAK,IAAI;CAAI,CAAC;CAC1G,OAAO;EAAE,QAAQ,KAAK;EAAK,QAAQ,OAAO,QAAQ;CAAE;AACrD;;;;;;AAOA,SAAgB,YAAY,KAAc,UAAoB,MAAY,IAA4B;CACrG,MAAM,QAAQ,QAAQ,KAAK,QAAQ;CACnC,OAAO,KAAK,OAAO,MAAM,OAAO,IAAI,GAAG,MAAM,OAAO,EAAE,CAAC;AACxD;;;;;AAMA,SAAS,UAAU,SAAgC;CAClD,MAAM,EAAE,OAAO,OAAO,SAAS;CAC/B,MAAM,MAAM,IAAI,aAAa,QAAQ,KAAK;CAC1C,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK,IAAI,KAAK,KAAK,KAAK,WAAW;CAEnE,MAAM,QAAQ,GAAW,GAAW,GAAW,IAAY,IAAY,WAAmB;EACzF,MAAM,KAAK,IAAI;EACf,MAAM,KAAK,IAAI;EACf,MAAM,OAAO,KAAK,KAAK,KAAK,KAAK,MAAM,SAAS,MAAM,QAAQ,IAAI,IAAI,KAAK,QAAQ;EACnF,IAAI,OAAO,SAAS,IAAI,IAAI,IAAI,KAAK,OAAO;CAC7C;CACA,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,KAC1B,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,KAAK;EAC/B,MAAM,IAAI,IAAI,QAAQ;EACtB,IAAI,CAAC,IAAI,IAAI;EACb,KAAK,GAAG,GAAG,GAAG,IAAI,GAAG,CAAC;EACtB,KAAK,GAAG,GAAG,GAAG,GAAG,IAAI,CAAC;EACtB,KAAK,GAAG,GAAG,GAAG,IAAI,IAAI,KAAK,KAAK;EAChC,KAAK,GAAG,GAAG,GAAG,GAAG,IAAI,KAAK,KAAK;CAChC;CAED,KAAK,IAAI,IAAI,QAAQ,GAAG,KAAK,GAAG,KAC/B,KAAK,IAAI,IAAI,QAAQ,GAAG,KAAK,GAAG,KAAK;EACpC,MAAM,IAAI,IAAI,QAAQ;EACtB,IAAI,CAAC,IAAI,IAAI;EACb,KAAK,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;EACrB,KAAK,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;EACrB,KAAK,GAAG,GAAG,GAAG,GAAG,GAAG,KAAK,KAAK;EAC9B,KAAK,GAAG,GAAG,GAAG,IAAI,GAAG,KAAK,KAAK;CAChC;CAED,OAAO;AACR;;;;;;AAuDA,IAAa,cAAc;;;;;;AAM3B,IAAa,cAAc;;AAE3B,IAAM,YAAY;;;;;;;;AASlB,SAAgB,WAAW,KAAc,UAA+B;CACvE,MAAM,QAAQ,QAAQ,KAAK,QAAQ;CACnC,MAAM,UAAU,WAAW,GAAG;CAC9B,MAAM,OAAO,IAAI,UAAU,OAAO;CAClC,MAAM,EAAE,UAAU,SAAS,KAAK,UAAU,OAAO;CACjD,MAAM,SAAS,IAAI,QAAQ,QAAQ,WAAW,OAAO,KAAK;CAC1D,MAAM,SAA8B,CAAC;CACrC,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,KAClC,KAAK,IAAI,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;EAC3C,MAAM,MAAM,KAAK,OAAO,MAAM,OAAO,OAAO,EAAE,CAAC,KAAM,GAAG,MAAM,OAAO,OAAO,EAAE,CAAC,KAAM,CAAC;EACtF,OAAO,KAAK;GAAE,MAAM,OAAO,EAAE,CAAC;GAAI,IAAI,OAAO,EAAE,CAAC;GAAI,GAAI,OAAO;IAAE,QAAQ,KAAK,MAAM,IAAI,SAAS,EAAE,IAAI;IAAI,QAAQ,IAAI;GAAO;EAAG,CAAC;CACnI;CAGD,MAAM,MAAM,UAAU,KAAK;CAC3B,IAAI;CACJ,KAAK,MAAM,QAAQ,QAAQ;EAC1B,MAAM,SAAS,KAAK,UAAU,CAAC;EAC/B,KAAK,IAAI,IAAI,WAAW,IAAI,OAAO,SAAS,WAAW,KAAK;GAC3D,MAAM,IAAI,KAAK,MAAM,OAAO,EAAE,CAAC,CAAC,IAAI,MAAM,QAAQ,KAAK,MAAM,OAAO,EAAE,CAAC,CAAC;GACxE,MAAM,QAAQ,KAAK,OAAO,IAAI,KAAK,IAAI,KAAK,EAAE,IAAI;GAClD,IAAI,CAAC,aAAa,QAAQ,UAAU,OAAO,YAAY;IAAE;IAAO,IAAI,OAAO;GAAG;EAC/E;CACD;CACA,MAAM,QAAQ,IAAI,QAAQ,QAAQ,WAAW;EAC5C,IAAI,CAAC,SAAS,MAAM,IAAI,OAAO,IAAI,GAAG,OAAO;EAC7C,MAAM,MAAM,SAAS,KAAK,OAAO,IAAI;EACrC,OAAO,IAAI,SAAS,cAAc,YAAY,GAAG,CAAC,CAAC,KAAK;CACzD,CAAC;CACD,MAAM,WAA2B,OAAO,KAAK,WAAW;EACvD,MAAM,QAAQ,OAAO;EACrB,MAAM,OAAO,MAAM,OAAO,KAAK;EAC/B,IAAI;EACJ,KAAK,MAAM,UAAU,OAAO;GAC3B,MAAM,MAAM,KAAK,OAAO,MAAM,MAAM,OAAO,MAAM,CAAC;GAClD,IAAI,CAAC,OAAQ,QAAQ,IAAI,UAAU,KAAK,UAAW;GACnD,MAAM,MAAM,SAAS,KAAK,OAAO,IAAI;GACrC,OAAO;IAAE,UAAU,KAAK,MAAM,IAAI,SAAS,EAAE,IAAI;IAAI,QAAQ,OAAO,UAAU,IAAI,UAAU,UAAU;IAAG,IAAI;KAAE,GAAG,OAAO;KAAG,GAAG,OAAO;IAAE;GAAE;EAC3I;EACA,IAAI,YAAY;EAChB,KAAK,IAAI,IAAI,KAAK,MAAM,MAAM,IAAA,EAAe,GAAG,KAAK,KAAK,KAAK,MAAM,IAAA,EAAe,GAAG,KACtF,KAAK,IAAI,IAAI,KAAK,MAAM,MAAM,IAAA,EAAe,GAAG,KAAK,KAAK,KAAK,MAAM,IAAA,EAAe,GAAG,KAAK;GAC3F,IAAI,MAAM,IAAI,KAAM,MAAM,GAAG,IAAI,KAAM,MAAM,CAAC,IAAA,IAAiB;GAC/D,IAAI,KAAK,YAAY,GAAG,CAAC,KAAK,CAAC,MAAM,IAAI,IAAI,QAAQ,IAAI;EAC1D;EAED,MAAM,QAAQ,IAAI,QAAQ,QAAQ,WAAW;GAC5C,IAAI,CAAC,SAAS,MAAM,IAAI,OAAO,IAAI,KAAK,MAAM,OAAO,IAAI,MAAM,GAAG,OAAO,IAAI,MAAM,CAAC,IAAA,IAAiB,OAAO;GAC5G,MAAM,MAAM,SAAS,KAAK,OAAO,IAAI;GACrC,OAAO,IAAI,SAAS,cAAc,YAAY,GAAG,CAAC,CAAC,IAAI;EACxD,CAAC,CAAC,CAAC;EACH,OAAO;GAAE,QAAQ,OAAO;GAAI,MAAM,OAAO;GAAM,GAAI,QAAQ,EAAE,KAAK;GAAI;GAAW;EAAM;CACxF,CAAC;CAED,MAAM,SAAmB,CAAC;CAC1B,MAAM,WAAW,MAAc,OAAoD,OAAO,WAAW;EAEpG,MAAM,QADS,SAAS,KAAK,WAAW;GAAE;GAAO,OAAO,MAAM,KAAK;EAAE,EACvD,CAAA,CAAO,QAAQ,UAAU,MAAM,UAAU,KAAA,CAAS;EAChE,IAAI,MAAM,SAAS,GAAG;EACtB,MAAM,OAAO,MAAM,QAAQ,GAAG,MAAO,EAAE,QAAQ,EAAE,QAAQ,IAAI,CAAE;EAC/D,MAAM,QAAQ,MAAM,QAAQ,GAAG,MAAO,EAAE,QAAQ,EAAE,QAAQ,IAAI,CAAE;EAChE,IAAI,KAAK,QAAQ,MAAM,QAAS,QAAoB,KAAK,QAAQ,MAAM,QAAQ,GAC9E,OAAO,KAAK,GAAG,KAAK,MAAM,KAAK,OAAO,KAAK,GAAG,KAAK,QAAQ,MAAM,MAAM,KAAK,IAAI,KAAK,MAAM,WAAW,MAAM,OAAO;CAErH;CACA,QAAQ,8BAA8B,UAAU,MAAM,MAAM,UAAU,UAAU;CAChF,QAAQ,+BAA+B,UAAU,MAAM,MAAM,MAAM;CACnE,QAAQ,uBAAuB,UAAU,MAAM,SAAS;CACxD,QAAQ,2BAA2B,UAAU,MAAM,KAAK;CACxD,OAAO;EACN,QAAQ,OAAO,KAAK,EAAE,QAAQ,GAAG,GAAG,WAAW,IAAI;EACnD,GAAI,aAAa,EAAE,UAAU;EAC7B,QAAQ;EACR;EACA,MAAM,SAAS,QAAQ,QAAQ,UAAU,KAAK,QAAQ,KAAK,CAAC;CAC7D;AACD;;;;;;AAOA,IAAa,eAAe,UAAoB,MAAc,WAAuC;CACpG,IAAI,CAAC,SAAS,MAAM,IAAI,IAAI,GAAG,OAAO,KAAA;CACtC,MAAM,QAAQ,SAAS,KAAK,IAAI,CAAC,CAAC,MAAM,aAAa;CACrD,OAAO,QAAQ,IAAI,KAAK,MAAO,SAAS,QAAS,EAAE,IAAI,KAAK,KAAA;AAC7D"}
|
package/dist/mapMerge.d.ts
CHANGED
package/dist/mapMerge.js
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { BY_ID as BY_ID$1, LAYERS } from "./map/schema.js";
|
|
2
|
+
import { parseMap, serializeMap } from "./map/file.js";
|
|
3
|
+
//#region src/mapMerge.ts
|
|
4
|
+
/** The parts of a map file that are lists of things with ids, merged thing by thing: the map's table says (`MAP_FIELDS`) */
|
|
5
|
+
var BY_ID = new Set(BY_ID$1);
|
|
6
|
+
/** What they are as text, to be compared: the same value, the same text */
|
|
7
|
+
var same = (a, b) => JSON.stringify(a) === JSON.stringify(b);
|
|
8
|
+
/**
|
|
9
|
+
* The three-way choice of one value: what only one side changed is that side's; both alike, either; both otherwise,
|
|
10
|
+
* ours, and a conflict. `undefined` is a value too: a part one side took out
|
|
11
|
+
*/
|
|
12
|
+
function pick(base, ours, theirs) {
|
|
13
|
+
if (same(ours, theirs)) return {
|
|
14
|
+
value: ours,
|
|
15
|
+
conflict: false
|
|
16
|
+
};
|
|
17
|
+
if (same(ours, base)) return {
|
|
18
|
+
value: theirs,
|
|
19
|
+
conflict: false
|
|
20
|
+
};
|
|
21
|
+
if (same(theirs, base)) return {
|
|
22
|
+
value: ours,
|
|
23
|
+
conflict: false
|
|
24
|
+
};
|
|
25
|
+
return {
|
|
26
|
+
value: ours,
|
|
27
|
+
conflict: true
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/** What a thing of a list is called in what is said: its kind and its id, and its name or type where it has one */
|
|
31
|
+
function nameOf(list, entry, id) {
|
|
32
|
+
return `${list === "objects" ? "object" : list.replace(/s$/, "")} ${id}${typeof entry?.name === "string" ? ` "${entry.name}"` : typeof entry?.type === "string" ? ` (${entry.type})` : ""}`;
|
|
33
|
+
}
|
|
34
|
+
/** Merges two lists of things by their ids: each thing chosen as a value of its own, in the order of their ids */
|
|
35
|
+
function mergeList(list, base, ours, theirs, conflicts) {
|
|
36
|
+
const byId = (entries) => new Map(entries.map((entry) => [entry.id, entry]));
|
|
37
|
+
const [b, o, t] = [
|
|
38
|
+
byId(base),
|
|
39
|
+
byId(ours),
|
|
40
|
+
byId(theirs)
|
|
41
|
+
];
|
|
42
|
+
const ids = [.../* @__PURE__ */ new Set([
|
|
43
|
+
...b.keys(),
|
|
44
|
+
...o.keys(),
|
|
45
|
+
...t.keys()
|
|
46
|
+
])].sort((x, y) => x - y);
|
|
47
|
+
const merged = [];
|
|
48
|
+
for (const id of ids) {
|
|
49
|
+
const chosen = pick(b.get(id), o.get(id), t.get(id));
|
|
50
|
+
if (chosen.conflict) {
|
|
51
|
+
const what = nameOf(list, o.get(id) ?? t.get(id), id);
|
|
52
|
+
conflicts.push(o.has(id) && t.has(id) ? `${what} was changed on both sides: ours is kept` : `${what} was changed on one side and taken out on the other: ours is kept`);
|
|
53
|
+
}
|
|
54
|
+
if (chosen.value !== void 0) merged.push(chosen.value);
|
|
55
|
+
}
|
|
56
|
+
return merged;
|
|
57
|
+
}
|
|
58
|
+
/** Whether a value is a list of things with ids: what of a map's look is merged thing by thing (its lights, effects, decals) */
|
|
59
|
+
var listOfIds = (value) => Array.isArray(value) && value.every((entry) => !!entry && typeof entry === "object" && typeof entry.id === "number");
|
|
60
|
+
/**
|
|
61
|
+
* Merges what a map looks like (`GameMap.environment`, the client's to read) part by part: a list of things with ids
|
|
62
|
+
* (its lights, effects, decals, sounds) thing by thing, as the map's own lists are, and each other part as a value
|
|
63
|
+
*/
|
|
64
|
+
function mergeEnvironment(base, ours, theirs, conflicts) {
|
|
65
|
+
const plain = (value) => !!value && typeof value === "object" && !Array.isArray(value);
|
|
66
|
+
if (![
|
|
67
|
+
base,
|
|
68
|
+
ours,
|
|
69
|
+
theirs
|
|
70
|
+
].every((value) => value === void 0 || plain(value))) return pick(base, ours, theirs);
|
|
71
|
+
const [b, o, t] = [
|
|
72
|
+
base,
|
|
73
|
+
ours,
|
|
74
|
+
theirs
|
|
75
|
+
].map((value) => value ?? {});
|
|
76
|
+
const merged = {};
|
|
77
|
+
for (const key of /* @__PURE__ */ new Set([
|
|
78
|
+
...Object.keys(b),
|
|
79
|
+
...Object.keys(o),
|
|
80
|
+
...Object.keys(t)
|
|
81
|
+
])) {
|
|
82
|
+
if ([
|
|
83
|
+
b[key],
|
|
84
|
+
o[key],
|
|
85
|
+
t[key]
|
|
86
|
+
].every((value) => value === void 0 || listOfIds(value))) {
|
|
87
|
+
const list = mergeList(key, b[key] ?? [], o[key] ?? [], t[key] ?? [], conflicts);
|
|
88
|
+
if (list.length || o[key] !== void 0) merged[key] = list;
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
const chosen = pick(b[key], o[key], t[key]);
|
|
92
|
+
if (chosen.conflict) conflicts.push(`the map's look's ${key} was changed on both sides: ours is kept`);
|
|
93
|
+
if (chosen.value !== void 0) merged[key] = chosen.value;
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
value: Object.keys(merged).length || ours !== void 0 ? merged : void 0,
|
|
97
|
+
conflict: false
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Merges two versions of a map from the one they came from: parts and things by their ids (those of its look too: its
|
|
102
|
+
* lights, effects, decals), the ground cell by cell. Never throws for what both changed: ours is kept there, and said
|
|
103
|
+
* (`conflicts`). Maps of different sizes are not merged (ours, and said)
|
|
104
|
+
*
|
|
105
|
+
* @beta
|
|
106
|
+
*/
|
|
107
|
+
function mergeMaps(base, ours, theirs) {
|
|
108
|
+
const conflicts = [];
|
|
109
|
+
if (ours.width !== theirs.width || ours.depth !== theirs.depth || base.width !== ours.width || base.depth !== ours.depth) return {
|
|
110
|
+
map: ours,
|
|
111
|
+
conflicts: ["the size of the map changed: ours is kept whole"]
|
|
112
|
+
};
|
|
113
|
+
const [b, o, t] = [
|
|
114
|
+
base,
|
|
115
|
+
ours,
|
|
116
|
+
theirs
|
|
117
|
+
].map((map) => serializeMap(map));
|
|
118
|
+
const merged = { ...o };
|
|
119
|
+
const keys = /* @__PURE__ */ new Set([
|
|
120
|
+
...Object.keys(b),
|
|
121
|
+
...Object.keys(o),
|
|
122
|
+
...Object.keys(t)
|
|
123
|
+
]);
|
|
124
|
+
for (const key of keys) {
|
|
125
|
+
if (key === "format" || LAYERS.includes(key)) continue;
|
|
126
|
+
if (BY_ID.has(key) && [
|
|
127
|
+
b[key] ?? [],
|
|
128
|
+
o[key] ?? [],
|
|
129
|
+
t[key] ?? []
|
|
130
|
+
].every(Array.isArray)) {
|
|
131
|
+
const list = mergeList(key, b[key] ?? [], o[key] ?? [], t[key] ?? [], conflicts);
|
|
132
|
+
if (list.length || o[key] !== void 0) merged[key] = list;
|
|
133
|
+
else delete merged[key];
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
const chosen = key === "environment" ? mergeEnvironment(b[key], o[key], t[key], conflicts) : pick(b[key], o[key], t[key]);
|
|
137
|
+
if (chosen.conflict) conflicts.push(`the map's ${key} was changed on both sides: ours is kept`);
|
|
138
|
+
if (chosen.value === void 0) delete merged[key];
|
|
139
|
+
else merged[key] = chosen.value;
|
|
140
|
+
}
|
|
141
|
+
const map = parseMap(merged);
|
|
142
|
+
const paintable = same(o.tileset, t.tileset) && same(b.tileset, o.tileset);
|
|
143
|
+
for (const layer of LAYERS) {
|
|
144
|
+
if (layer === "tiles" && !paintable) {
|
|
145
|
+
if (!same(Array.from(ours.tiles), Array.from(theirs.tiles))) conflicts.push("the paint was changed on both sides with different tiles: ours is kept");
|
|
146
|
+
map.tiles = ours.tiles.slice();
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
const [from, mine, yours] = [
|
|
150
|
+
base[layer],
|
|
151
|
+
ours[layer],
|
|
152
|
+
theirs[layer]
|
|
153
|
+
];
|
|
154
|
+
const into = mine.slice();
|
|
155
|
+
let both = 0;
|
|
156
|
+
for (let i = 0; i < into.length; i++) {
|
|
157
|
+
if (mine[i] === yours[i]) continue;
|
|
158
|
+
if (mine[i] === from[i]) into[i] = yours[i];
|
|
159
|
+
else if (yours[i] !== from[i]) both++;
|
|
160
|
+
}
|
|
161
|
+
if (both) conflicts.push(`${both} ${layer === "ground" ? "corners of the ground" : `cells of the ${layer === "tiles" ? "paint" : layer}`} were changed on both sides: ours is kept there`);
|
|
162
|
+
map[layer] = into;
|
|
163
|
+
}
|
|
164
|
+
return {
|
|
165
|
+
map,
|
|
166
|
+
conflicts
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
//#endregion
|
|
170
|
+
export { mergeMaps };
|
|
171
|
+
|
|
172
|
+
//# sourceMappingURL=mapMerge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mapMerge.js","names":["ID_LISTS"],"sources":["../src/mapMerge.ts"],"sourcesContent":["import { type GameMap, parseMap, serializeMap } from './map'\nimport { BY_ID as ID_LISTS, LAYERS } from './map/schema'\n\n/*\n * Map files that merge (S26). Git merges a map file line by line, which goes a long way since format 3 (an object to a\n * line, a row of the ground to a line): what it cannot, two changes to the same row or the same object, comes here,\n * as the three files git gives a merge driver (what both came from, ours, theirs). What only one side changed is\n * taken; what both changed alike is taken once; what both changed otherwise is ours, and said, for a person to see to.\n */\n\n/**\n * A merge of two versions of a map from the one they came from\n *\n * @beta\n */\nexport interface MapMerge {\n\t/** The map the two versions were merged into */\n\tmap: GameMap\n\t/** What both sides changed otherwise, in words: ours was kept for each */\n\tconflicts: string[]\n}\n\n/** The parts of a map file that are lists of things with ids, merged thing by thing: the map's table says (`MAP_FIELDS`) */\nconst BY_ID = new Set(ID_LISTS)\n\n/** What they are as text, to be compared: the same value, the same text */\nconst same = (a: unknown, b: unknown) => JSON.stringify(a) === JSON.stringify(b)\n\n/**\n * The three-way choice of one value: what only one side changed is that side's; both alike, either; both otherwise,\n * ours, and a conflict. `undefined` is a value too: a part one side took out\n */\nfunction pick<T>(base: T, ours: T, theirs: T): { value: T; conflict: boolean } {\n\tif (same(ours, theirs)) return { value: ours, conflict: false }\n\tif (same(ours, base)) return { value: theirs, conflict: false }\n\tif (same(theirs, base)) return { value: ours, conflict: false }\n\treturn { value: ours, conflict: true }\n}\n\n/** What a thing of a list is called in what is said: its kind and its id, and its name or type where it has one */\nfunction nameOf(list: string, entry: { id: number; name?: unknown; type?: unknown } | undefined, id: number): string {\n\tconst kind = list === 'objects' ? 'object' : list.replace(/s$/, '')\n\tconst called = typeof entry?.name === 'string' ? ` \"${entry.name}\"` : typeof entry?.type === 'string' ? ` (${entry.type})` : ''\n\treturn `${kind} ${id}${called}`\n}\n\n/** Merges two lists of things by their ids: each thing chosen as a value of its own, in the order of their ids */\nfunction mergeList(list: string, base: unknown[], ours: unknown[], theirs: unknown[], conflicts: string[]): unknown[] {\n\tconst byId = (entries: unknown[]) => new Map(entries.map((entry) => [(entry as { id: number }).id, entry]))\n\tconst [b, o, t] = [byId(base), byId(ours), byId(theirs)]\n\tconst ids = [...new Set([...b.keys(), ...o.keys(), ...t.keys()])].sort((x, y) => x - y)\n\tconst merged: unknown[] = []\n\tfor (const id of ids) {\n\t\tconst chosen = pick(b.get(id), o.get(id), t.get(id))\n\t\tif (chosen.conflict) {\n\t\t\tconst what = nameOf(list, (o.get(id) ?? t.get(id)) as { id: number }, id)\n\t\t\tconflicts.push(\n\t\t\t\to.has(id) && t.has(id)\n\t\t\t\t\t? `${what} was changed on both sides: ours is kept`\n\t\t\t\t\t: `${what} was changed on one side and taken out on the other: ours is kept`\n\t\t\t)\n\t\t}\n\t\tif (chosen.value !== undefined) merged.push(chosen.value)\n\t}\n\treturn merged\n}\n\n/** Whether a value is a list of things with ids: what of a map's look is merged thing by thing (its lights, effects, decals) */\nconst listOfIds = (value: unknown): value is { id: number }[] =>\n\tArray.isArray(value) && value.every((entry) => !!entry && typeof entry === 'object' && typeof (entry as { id?: unknown }).id === 'number')\n\n/**\n * Merges what a map looks like (`GameMap.environment`, the client's to read) part by part: a list of things with ids\n * (its lights, effects, decals, sounds) thing by thing, as the map's own lists are, and each other part as a value\n */\nfunction mergeEnvironment(base: unknown, ours: unknown, theirs: unknown, conflicts: string[]): { value: unknown; conflict: boolean } {\n\tconst plain = (value: unknown): value is Record<string, unknown> => !!value && typeof value === 'object' && !Array.isArray(value)\n\tif (![base, ours, theirs].every((value) => value === undefined || plain(value))) return pick(base, ours, theirs)\n\tconst [b, o, t] = [base, ours, theirs].map((value) => (value ?? {}) as Record<string, unknown>)\n\tconst merged: Record<string, unknown> = {}\n\tfor (const key of new Set([...Object.keys(b), ...Object.keys(o), ...Object.keys(t)])) {\n\t\tif ([b[key], o[key], t[key]].every((value) => value === undefined || listOfIds(value))) {\n\t\t\tconst list = mergeList(key, (b[key] ?? []) as unknown[], (o[key] ?? []) as unknown[], (t[key] ?? []) as unknown[], conflicts)\n\t\t\tif (list.length || o[key] !== undefined) merged[key] = list\n\t\t\tcontinue\n\t\t}\n\t\tconst chosen = pick(b[key], o[key], t[key])\n\t\tif (chosen.conflict) conflicts.push(`the map's look's ${key} was changed on both sides: ours is kept`)\n\t\tif (chosen.value !== undefined) merged[key] = chosen.value\n\t}\n\treturn { value: Object.keys(merged).length || ours !== undefined ? merged : undefined, conflict: false }\n}\n\n/**\n * Merges two versions of a map from the one they came from: parts and things by their ids (those of its look too: its\n * lights, effects, decals), the ground cell by cell. Never throws for what both changed: ours is kept there, and said\n * (`conflicts`). Maps of different sizes are not merged (ours, and said)\n *\n * @beta\n */\nexport function mergeMaps(base: GameMap, ours: GameMap, theirs: GameMap): MapMerge {\n\tconst conflicts: string[] = []\n\tif (ours.width !== theirs.width || ours.depth !== theirs.depth || base.width !== ours.width || base.depth !== ours.depth) {\n\t\treturn { map: ours, conflicts: ['the size of the map changed: ours is kept whole'] }\n\t}\n\tconst [b, o, t] = [base, ours, theirs].map((map) => serializeMap(map) as unknown as Record<string, unknown>)\n\tconst merged: Record<string, unknown> = { ...o }\n\tconst keys = new Set([...Object.keys(b), ...Object.keys(o), ...Object.keys(t)])\n\tfor (const key of keys) {\n\t\tif (key === 'format' || (LAYERS as readonly string[]).includes(key)) continue\n\t\tif (BY_ID.has(key) && [b[key] ?? [], o[key] ?? [], t[key] ?? []].every(Array.isArray)) {\n\t\t\tconst list = mergeList(key, (b[key] ?? []) as unknown[], (o[key] ?? []) as unknown[], (t[key] ?? []) as unknown[], conflicts)\n\t\t\tif (list.length || o[key] !== undefined) merged[key] = list\n\t\t\telse delete merged[key]\n\t\t\tcontinue\n\t\t}\n\t\tconst chosen = key === 'environment' ? mergeEnvironment(b[key], o[key], t[key], conflicts) : pick(b[key], o[key], t[key])\n\t\tif (chosen.conflict) conflicts.push(`the map's ${key} was changed on both sides: ours is kept`)\n\t\tif (chosen.value === undefined) delete merged[key]\n\t\telse merged[key] = chosen.value\n\t}\n\tconst map = parseMap(merged)\n\t// the paint by cell only where both name their tiles alike: an index means another tile otherwise\n\tconst paintable = same(o.tileset, t.tileset) && same(b.tileset, o.tileset)\n\tfor (const layer of LAYERS) {\n\t\tif (layer === 'tiles' && !paintable) {\n\t\t\tif (!same(Array.from(ours.tiles), Array.from(theirs.tiles)))\n\t\t\t\tconflicts.push('the paint was changed on both sides with different tiles: ours is kept')\n\t\t\tmap.tiles = ours.tiles.slice()\n\t\t\tcontinue\n\t\t}\n\t\tconst [from, mine, yours] = [base[layer], ours[layer], theirs[layer]]\n\t\tconst into = mine.slice()\n\t\tlet both = 0\n\t\tfor (let i = 0; i < into.length; i++) {\n\t\t\tif (mine[i] === yours[i]) continue\n\t\t\tif (mine[i] === from[i]) into[i] = yours[i]\n\t\t\telse if (yours[i] !== from[i]) both++\n\t\t}\n\t\tif (both)\n\t\t\tconflicts.push(\n\t\t\t\t`${both} ${layer === 'ground' ? 'corners of the ground' : `cells of the ${layer === 'tiles' ? 'paint' : layer}`} were changed on both sides: ours is kept there`\n\t\t\t)\n\t\t;(map as unknown as Record<string, unknown>)[layer] = into\n\t}\n\treturn { map, conflicts }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { defineHook } from "./hooks.js";
|
|
2
|
+
//#region src/mapObjectives.ts
|
|
3
|
+
/**
|
|
4
|
+
* The map objectives pack's id
|
|
5
|
+
*
|
|
6
|
+
* @beta
|
|
7
|
+
*/
|
|
8
|
+
var MAP_OBJECTIVES = "core.mapObjectives";
|
|
9
|
+
/**
|
|
10
|
+
* The key of the map's data its objectives are kept under (`GameMap.data.objectives`)
|
|
11
|
+
*
|
|
12
|
+
* @beta
|
|
13
|
+
*/
|
|
14
|
+
var MAP_OBJECTIVES_KEY = "objectives";
|
|
15
|
+
/** The words of an objective as a file may hold them: a key, or a key with params */
|
|
16
|
+
var isWords = (text) => typeof text === "string" ? text.trim() !== "" : typeof text === "object" && text !== null && typeof text.key === "string" && text.key !== "";
|
|
17
|
+
/**
|
|
18
|
+
* The objectives a map gives (`GameMap.data.objectives`), in the order it gives them: none for a map with none. What is
|
|
19
|
+
* kept there and is no objective (no id, no words) is left out, so that a file changed by hand breaks no rule that reads
|
|
20
|
+
* it; the map's checks say so (`mapObjectives`)
|
|
21
|
+
*
|
|
22
|
+
* @beta
|
|
23
|
+
*/
|
|
24
|
+
function mapObjectivesOf(map) {
|
|
25
|
+
const kept = map.data[MAP_OBJECTIVES_KEY];
|
|
26
|
+
if (!Array.isArray(kept)) return [];
|
|
27
|
+
return kept.filter((each) => typeof each === "object" && each !== null && typeof each.id === "string" && each.id !== "" && isWords(each.text)).map((each) => ({
|
|
28
|
+
id: each.id,
|
|
29
|
+
text: each.text,
|
|
30
|
+
...each.detail !== void 0 && isWords(each.detail) && { detail: each.detail },
|
|
31
|
+
...each.required !== void 0 && { required: each.required !== false },
|
|
32
|
+
at: each.at === "rule" ? "rule" : "start"
|
|
33
|
+
}));
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Who is given a map's objective when the rules do not say (`giveMapObjective`): the map's players a person plays, not
|
|
37
|
+
* those it says the computer plays or nobody does (`MapPlayer.controller`), in the order of their ids
|
|
38
|
+
*
|
|
39
|
+
* @beta
|
|
40
|
+
*/
|
|
41
|
+
function mapObjectivePlayers(world) {
|
|
42
|
+
return [...world.players.values()].filter((player) => !player.neutral && !player.creeps).filter((player) => {
|
|
43
|
+
const controller = world.map.player(player.id)?.controller;
|
|
44
|
+
return controller !== "computer" && controller !== "nobody";
|
|
45
|
+
}).map((player) => player.id).sort((a, b) => a - b);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Gives players an objective of the map's, by its id (`MapObjective`): those given by a rule (`at: 'rule'`), when the
|
|
49
|
+
* rules say. To every player a person plays when `players` is left out (`mapObjectivePlayers`); a player who has it
|
|
50
|
+
* already keeps theirs. Its words' params and its progress go with it, as `world.objectives.add`. Throws for an id the
|
|
51
|
+
* map does not have: an id in the code that is not on the map is a mistake
|
|
52
|
+
*
|
|
53
|
+
* @beta
|
|
54
|
+
*/
|
|
55
|
+
function giveMapObjective(world, id, options = {}) {
|
|
56
|
+
const def = mapObjectivesOf(world.map).find((objective) => objective.id === id);
|
|
57
|
+
if (!def) throw new Error(`The map${world.map.name ? ` "${world.map.name}"` : ""} has no objective "${id}"`);
|
|
58
|
+
const { at: _at, ...objective } = def;
|
|
59
|
+
const given = [];
|
|
60
|
+
for (const player of options.players ?? mapObjectivePlayers(world)) {
|
|
61
|
+
if (world.objectives.has(player, id)) continue;
|
|
62
|
+
given.push(world.objectives.add(player, objective, {
|
|
63
|
+
params: options.params,
|
|
64
|
+
progress: options.progress
|
|
65
|
+
}));
|
|
66
|
+
}
|
|
67
|
+
return given;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* What is wrong with a map's objectives (`GameMap.data.objectives`): one with no id or with another's, one with no
|
|
71
|
+
* words, a list that is not one. Each a click away in the Objectives panel
|
|
72
|
+
*
|
|
73
|
+
* @beta
|
|
74
|
+
*/
|
|
75
|
+
function checkMapObjectives(map) {
|
|
76
|
+
const kept = map.data[MAP_OBJECTIVES_KEY];
|
|
77
|
+
if (kept === void 0) return [];
|
|
78
|
+
if (!Array.isArray(kept)) return [{
|
|
79
|
+
message: "The map’s objectives are not a list",
|
|
80
|
+
error: true,
|
|
81
|
+
rule: "objectives"
|
|
82
|
+
}];
|
|
83
|
+
const problems = [];
|
|
84
|
+
const seen = /* @__PURE__ */ new Set();
|
|
85
|
+
kept.forEach((each, index) => {
|
|
86
|
+
const id = typeof each?.id === "string" ? each.id : "";
|
|
87
|
+
const reveal = {
|
|
88
|
+
panel: "objectives",
|
|
89
|
+
entry: id || String(index)
|
|
90
|
+
};
|
|
91
|
+
if (!id) problems.push({
|
|
92
|
+
message: `Objective ${index + 1} has no id`,
|
|
93
|
+
error: true,
|
|
94
|
+
rule: "objective-id",
|
|
95
|
+
reveal
|
|
96
|
+
});
|
|
97
|
+
else if (seen.has(id)) problems.push({
|
|
98
|
+
message: `Two objectives have the id "${id}"`,
|
|
99
|
+
error: true,
|
|
100
|
+
rule: "objective-id",
|
|
101
|
+
reveal
|
|
102
|
+
});
|
|
103
|
+
seen.add(id);
|
|
104
|
+
if (!isWords(each?.text)) problems.push({
|
|
105
|
+
message: `The objective "${id || index + 1}" has no words`,
|
|
106
|
+
error: true,
|
|
107
|
+
rule: "objective-text",
|
|
108
|
+
reveal
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
return problems;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Objectives as data on the map (campaign plan EQ3): a map's objectives (`MapObjective`, kept in `GameMap.data.objectives`,
|
|
115
|
+
* written by the editor's Objectives panel) given at the start to every player a person plays, as the world is made
|
|
116
|
+
* from the map; those given by a rule wait for the rules (`giveMapObjective(world, id)`). Done and failed as any
|
|
117
|
+
* objective is (`world.objectives.complete`, `fail`); a game that is won by them has `objectiveVictory` as its
|
|
118
|
+
* `victory`. The map's checks say what is wrong with them (`checkMapObjectives`)
|
|
119
|
+
*
|
|
120
|
+
* @beta
|
|
121
|
+
*/
|
|
122
|
+
function mapObjectives() {
|
|
123
|
+
return {
|
|
124
|
+
id: MAP_OBJECTIVES,
|
|
125
|
+
hooks: [defineHook({
|
|
126
|
+
hook: "mapStart",
|
|
127
|
+
id: MAP_OBJECTIVES,
|
|
128
|
+
run(world) {
|
|
129
|
+
for (const objective of mapObjectivesOf(world.map)) if (objective.at === "start") giveMapObjective(world, objective.id);
|
|
130
|
+
}
|
|
131
|
+
})],
|
|
132
|
+
check: (map) => checkMapObjectives(map)
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
//#endregion
|
|
136
|
+
export { MAP_OBJECTIVES, MAP_OBJECTIVES_KEY, checkMapObjectives, giveMapObjective, mapObjectivePlayers, mapObjectives, mapObjectivesOf };
|
|
137
|
+
|
|
138
|
+
//# sourceMappingURL=mapObjectives.js.map
|