@v12-engine/engine 0.1.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/abilities/amounts.d.ts +28 -0
- package/dist/abilities/amounts.js +74 -0
- package/dist/abilities/amounts.js.map +1 -0
- package/dist/abilities/buffs.d.ts +106 -6
- package/dist/abilities/buffs.js +443 -0
- package/dist/abilities/buffs.js.map +1 -0
- package/dist/abilities/castTold.d.ts +2 -0
- package/dist/abilities/castTold.js +66 -0
- package/dist/abilities/castTold.js.map +1 -0
- package/dist/abilities/chance.d.ts +38 -0
- package/dist/abilities/chance.js +77 -0
- package/dist/abilities/chance.js.map +1 -0
- package/dist/abilities/charges.d.ts +18 -0
- package/dist/abilities/charges.js +101 -0
- package/dist/abilities/charges.js.map +1 -0
- package/dist/abilities/control.d.ts +28 -0
- package/dist/abilities/control.js +113 -0
- package/dist/abilities/control.js.map +1 -0
- package/dist/abilities/dispel.js +51 -0
- package/dist/abilities/dispel.js.map +1 -0
- package/dist/abilities/effectFields.d.ts +1 -1
- package/dist/abilities/effectFields.js +676 -0
- package/dist/abilities/effectFields.js.map +1 -0
- package/dist/abilities/effectIndex.d.ts +27 -0
- package/dist/abilities/effectIndex.js +64 -0
- package/dist/abilities/effectIndex.js.map +1 -0
- package/dist/abilities/effects/buff.d.ts +9 -3
- package/dist/abilities/effects/buff.js +84 -0
- package/dist/abilities/effects/buff.js.map +1 -0
- package/dist/abilities/effects/conditions.d.ts +2 -0
- package/dist/abilities/effects/conditions.js +41 -0
- package/dist/abilities/effects/conditions.js.map +1 -0
- package/dist/abilities/effects/core.js +54 -0
- package/dist/abilities/effects/core.js.map +1 -0
- package/dist/abilities/effects/damage.d.ts +1 -1
- package/dist/abilities/effects/damage.js +43 -0
- package/dist/abilities/effects/damage.js.map +1 -0
- package/dist/abilities/effects/heal.d.ts +2 -2
- package/dist/abilities/effects/heal.js +51 -0
- package/dist/abilities/effects/heal.js.map +1 -0
- package/dist/abilities/effects/missile.d.ts +13 -1
- package/dist/abilities/effects/missile.js +104 -0
- package/dist/abilities/effects/missile.js.map +1 -0
- package/dist/abilities/effects/morph.d.ts +5 -0
- package/dist/abilities/effects/morph.js +43 -0
- package/dist/abilities/effects/morph.js.map +1 -0
- package/dist/abilities/effects/moves.d.ts +16 -4
- package/dist/abilities/effects/moves.js +212 -0
- package/dist/abilities/effects/moves.js.map +1 -0
- package/dist/abilities/effects/passives.d.ts +19 -9
- package/dist/abilities/effects/passives.js +131 -0
- package/dist/abilities/effects/passives.js.map +1 -0
- package/dist/abilities/effects/proxy.d.ts +5 -0
- package/dist/abilities/effects/proxy.js +60 -0
- package/dist/abilities/effects/proxy.js.map +1 -0
- package/dist/abilities/effects/sight.d.ts +2 -2
- package/dist/abilities/effects/sight.js +39 -0
- package/dist/abilities/effects/sight.js.map +1 -0
- package/dist/abilities/effects/spawn.d.ts +5 -2
- package/dist/abilities/effects/spawn.js +40 -0
- package/dist/abilities/effects/spawn.js.map +1 -0
- package/dist/abilities/effects/timed.d.ts +2 -2
- package/dist/abilities/effects/timed.js +96 -0
- package/dist/abilities/effects/timed.js.map +1 -0
- package/dist/abilities/effects/trade.d.ts +1 -1
- package/dist/abilities/effects/trade.js +25 -0
- package/dist/abilities/effects/trade.js.map +1 -0
- package/dist/abilities/effects.d.ts +97 -23
- package/dist/abilities/effects.js +860 -0
- package/dist/abilities/effects.js.map +1 -0
- package/dist/abilities/land.d.ts +38 -4
- package/dist/abilities/land.js +189 -0
- package/dist/abilities/land.js.map +1 -0
- package/dist/abilities/recast.d.ts +45 -0
- package/dist/abilities/recast.js +118 -0
- package/dist/abilities/recast.js.map +1 -0
- package/dist/abilities/scaled.js +40 -0
- package/dist/abilities/scaled.js.map +1 -0
- package/dist/abilities/screen.d.ts +6 -0
- package/dist/abilities/screen.js +83 -0
- package/dist/abilities/screen.js.map +1 -0
- package/dist/abilities/shapes.d.ts +66 -0
- package/dist/abilities/shapes.js +122 -0
- package/dist/abilities/shapes.js.map +1 -0
- package/dist/abilities/text.d.ts +14 -2
- package/dist/abilities/text.js +204 -0
- package/dist/abilities/text.js.map +1 -0
- package/dist/abilities/triggers.d.ts +98 -0
- package/dist/abilities/triggers.js +351 -0
- package/dist/abilities/triggers.js.map +1 -0
- package/dist/abilityChanges.d.ts +131 -0
- package/dist/abilityChanges.js +345 -0
- package/dist/abilityChanges.js.map +1 -0
- package/dist/ai/area.d.ts +4 -1
- package/dist/ai/brain.d.ts +4 -1
- package/dist/ai/brain.js +844 -0
- package/dist/ai/brain.js.map +1 -0
- package/dist/ai/budget.js +74 -0
- package/dist/ai/budget.js.map +1 -0
- package/dist/ai/checks.d.ts +9 -1
- package/dist/ai/checks.js +242 -0
- package/dist/ai/checks.js.map +1 -0
- package/dist/ai/computer.d.ts +11 -4
- package/dist/ai/computer.js +251 -0
- package/dist/ai/computer.js.map +1 -0
- package/dist/ai/defence.d.ts +4 -0
- package/dist/ai/defence.js +430 -0
- package/dist/ai/defence.js.map +1 -0
- package/dist/ai/define.d.ts +3 -2
- package/dist/ai/define.js +31 -0
- package/dist/ai/define.js.map +1 -0
- package/dist/ai/economy.d.ts +10 -7
- package/dist/ai/economy.js +780 -0
- package/dist/ai/economy.js.map +1 -0
- package/dist/ai/geometry.js +38 -0
- package/dist/ai/geometry.js.map +1 -0
- package/dist/ai/goals.d.ts +1 -0
- package/dist/ai/goals.js +560 -0
- package/dist/ai/goals.js.map +1 -0
- package/dist/ai/knowledge.d.ts +72 -7
- package/dist/ai/knowledge.js +804 -0
- package/dist/ai/knowledge.js.map +1 -0
- package/dist/ai/lanes.d.ts +10 -2
- package/dist/ai/lanes.js +715 -0
- package/dist/ai/lanes.js.map +1 -0
- package/dist/ai/melee/build.js +264 -0
- package/dist/ai/melee/build.js.map +1 -0
- package/dist/ai/melee/goals.d.ts +7 -0
- package/dist/ai/melee/goals.js +720 -0
- package/dist/ai/melee/goals.js.map +1 -0
- package/dist/ai/melee/heroes.js +68 -0
- package/dist/ai/melee/heroes.js.map +1 -0
- package/dist/ai/melee/index.d.ts +1 -1
- package/dist/ai/melee/index.js +51 -0
- package/dist/ai/melee/index.js.map +1 -0
- package/dist/ai/melee/production.js +29 -0
- package/dist/ai/melee/production.js.map +1 -0
- package/dist/ai/melee/surrender.js +64 -0
- package/dist/ai/melee/surrender.js.map +1 -0
- package/dist/ai/micro.d.ts +9 -0
- package/dist/ai/micro.js +1316 -0
- package/dist/ai/micro.js.map +1 -0
- package/dist/ai/mission.d.ts +9 -2
- package/dist/ai/mission.js +538 -0
- package/dist/ai/mission.js.map +1 -0
- package/dist/ai/missionRules.d.ts +1 -1
- package/dist/ai/missionRules.js +26 -0
- package/dist/ai/missionRules.js.map +1 -0
- package/dist/ai/module.d.ts +6 -2
- package/dist/ai/module.js +37 -0
- package/dist/ai/module.js.map +1 -0
- package/dist/ai/options.d.ts +3 -3
- package/dist/ai/plans/build.d.ts +20 -1
- package/dist/ai/plans/build.js +608 -0
- package/dist/ai/plans/build.js.map +1 -0
- package/dist/ai/plans/placement.d.ts +4 -1
- package/dist/ai/plans/placement.js +295 -0
- package/dist/ai/plans/placement.js.map +1 -0
- package/dist/ai/plans/plans.d.ts +9 -0
- package/dist/ai/plans/plans.js +110 -0
- package/dist/ai/plans/plans.js.map +1 -0
- package/dist/ai/plans/production.d.ts +14 -2
- package/dist/ai/plans/production.js +434 -0
- package/dist/ai/plans/production.js.map +1 -0
- package/dist/ai/plans/purse.d.ts +6 -3
- package/dist/ai/plans/purse.js +139 -0
- package/dist/ai/plans/purse.js.map +1 -0
- package/dist/ai/plans/tech.d.ts +6 -0
- package/dist/ai/plans/tech.js +122 -0
- package/dist/ai/plans/tech.js.map +1 -0
- package/dist/ai/profiles.d.ts +4 -4
- package/dist/{profiles-B3NS9jwk.js → ai/profiles.js} +3 -98
- package/dist/ai/profiles.js.map +1 -0
- package/dist/ai/reach.js +54 -0
- package/dist/ai/reach.js.map +1 -0
- package/dist/ai/report.d.ts +8 -0
- package/dist/ai/report.js +87 -0
- package/dist/ai/report.js.map +1 -0
- package/dist/ai/roles.d.ts +4 -0
- package/dist/ai/roles.js +207 -0
- package/dist/ai/roles.js.map +1 -0
- package/dist/ai/rules.d.ts +8 -2
- package/dist/ai/rules.js +416 -0
- package/dist/ai/rules.js.map +1 -0
- package/dist/ai/scouting.d.ts +6 -0
- package/dist/ai/scouting.js +324 -0
- package/dist/ai/scouting.js.map +1 -0
- package/dist/ai/settings.js +99 -0
- package/dist/ai/settings.js.map +1 -0
- package/dist/ai/squads.d.ts +21 -2
- package/dist/ai/squads.js +916 -0
- package/dist/ai/squads.js.map +1 -0
- package/dist/ai/strength.js +320 -0
- package/dist/ai/strength.js.map +1 -0
- package/dist/ai/task.d.ts +3 -1
- package/dist/ai/task.js +17 -0
- package/dist/ai/task.js.map +1 -0
- package/dist/ai/tasks/attack.js +24 -0
- package/dist/ai/tasks/attack.js.map +1 -0
- package/dist/ai/tasks/capture.d.ts +3 -3
- package/dist/ai/tasks/capture.js +37 -0
- package/dist/ai/tasks/capture.js.map +1 -0
- package/dist/ai/tasks/creep.js +29 -0
- package/dist/ai/tasks/creep.js.map +1 -0
- package/dist/ai/tasks/defend.js +61 -0
- package/dist/ai/tasks/defend.js.map +1 -0
- package/dist/ai/tasks/drop.js +81 -0
- package/dist/ai/tasks/drop.js.map +1 -0
- package/dist/ai/tasks/escort.js +59 -0
- package/dist/ai/tasks/escort.js.map +1 -0
- package/dist/ai/tasks/gather.js +48 -0
- package/dist/ai/tasks/gather.js.map +1 -0
- package/dist/ai/tasks/harass.js +39 -0
- package/dist/ai/tasks/harass.js.map +1 -0
- package/dist/ai/tasks/hold.js +32 -0
- package/dist/ai/tasks/hold.js.map +1 -0
- package/dist/ai/tasks/index.js +34 -0
- package/dist/ai/tasks/index.js.map +1 -0
- package/dist/ai/tasks/move.js +26 -0
- package/dist/ai/tasks/move.js.map +1 -0
- package/dist/ai/tasks/patrol.js +59 -0
- package/dist/ai/tasks/patrol.js.map +1 -0
- package/dist/ai/tasks/retreat.js +28 -0
- package/dist/ai/tasks/retreat.js.map +1 -0
- package/dist/ai/tasks/scout.js +73 -0
- package/dist/ai/tasks/scout.js.map +1 -0
- package/dist/ai/tasks/shared.d.ts +1 -1
- package/dist/ai/tasks/shared.js +137 -0
- package/dist/ai/tasks/shared.js.map +1 -0
- package/dist/ai/team.d.ts +18 -1
- package/dist/ai/team.js +492 -0
- package/dist/ai/team.js.map +1 -0
- package/dist/ai/threat.d.ts +6 -0
- package/dist/ai/threat.js +206 -0
- package/dist/ai/threat.js.map +1 -0
- package/dist/ai/view.d.ts +21 -7
- package/dist/ai/view.js +677 -0
- package/dist/ai/view.js.map +1 -0
- package/dist/ai/waves.d.ts +6 -0
- package/dist/ai/waves.js +410 -0
- package/dist/ai/waves.js.map +1 -0
- package/dist/ai.js +54 -6239
- package/dist/aiTesting.d.ts +6 -3
- package/dist/aiTesting.js +229 -0
- package/dist/aiTesting.js.map +1 -0
- package/dist/areas.d.ts +4 -1
- package/dist/areas.js +295 -0
- package/dist/areas.js.map +1 -0
- package/dist/attacks.d.ts +3 -3
- package/dist/attacks.js +127 -0
- package/dist/attacks.js.map +1 -0
- package/dist/burning.d.ts +267 -0
- package/dist/burning.js +795 -0
- package/dist/burning.js.map +1 -0
- package/dist/bytes.js +21 -0
- package/dist/bytes.js.map +1 -0
- package/dist/callings.d.ts +71 -0
- package/dist/callings.js +157 -0
- package/dist/callings.js.map +1 -0
- package/dist/cameraOrders.d.ts +78 -0
- package/dist/cameraOrders.js +114 -0
- package/dist/cameraOrders.js.map +1 -0
- package/dist/camps.d.ts +70 -4
- package/dist/camps.js +501 -0
- package/dist/camps.js.map +1 -0
- package/dist/capture.d.ts +15 -3
- package/dist/capture.js +304 -0
- package/dist/capture.js.map +1 -0
- package/dist/cellLayers.d.ts +78 -13
- package/dist/cellLayers.js +275 -0
- package/dist/cellLayers.js.map +1 -0
- package/dist/cellPatches.d.ts +24 -0
- package/dist/cellPatches.js +73 -0
- package/dist/cellPatches.js.map +1 -0
- package/dist/cinematics.d.ts +10 -5
- package/dist/cinematics.js +161 -0
- package/dist/cinematics.js.map +1 -0
- package/dist/clock.d.ts +2 -2
- package/dist/clock.js +78 -0
- package/dist/clock.js.map +1 -0
- package/dist/commands.d.ts +36 -4
- package/dist/commands.js +636 -0
- package/dist/commands.js.map +1 -0
- package/dist/components.d.ts +31 -10
- package/dist/components.js +74 -0
- package/dist/components.js.map +1 -0
- package/dist/computers.d.ts +4 -4
- package/dist/computers.js +194 -0
- package/dist/computers.js.map +1 -0
- package/dist/concealment.d.ts +25 -2
- package/dist/concealment.js +409 -0
- package/dist/concealment.js.map +1 -0
- package/dist/coreComponents.js +130 -0
- package/dist/coreComponents.js.map +1 -0
- package/dist/createGame.d.ts +306 -0
- package/dist/createGame.js +405 -0
- package/dist/createGame.js.map +1 -0
- package/dist/dashing.d.ts +18 -2
- package/dist/dashing.js +41 -0
- package/dist/dashing.js.map +1 -0
- package/dist/debug.d.ts +8 -0
- package/dist/debug.js +5 -3
- package/dist/debug2.js +76 -0
- package/dist/debug2.js.map +1 -0
- package/dist/debugCommands.d.ts +6 -6
- package/dist/debugCommands.js +537 -0
- package/dist/debugCommands.js.map +1 -0
- package/dist/debugging.d.ts +1 -0
- package/dist/defaultSets.d.ts +183 -0
- package/dist/defaultSets.js +216 -0
- package/dist/defaultSets.js.map +1 -0
- package/dist/definitions.d.ts +6 -0
- package/dist/definitions.js +78 -0
- package/dist/definitions.js.map +1 -0
- package/dist/defs.d.ts +1895 -165
- package/dist/defs.js +380 -0
- package/dist/defs.js.map +1 -0
- package/dist/denying.d.ts +4 -4
- package/dist/denying.js +106 -0
- package/dist/denying.js.map +1 -0
- package/dist/destructibles.d.ts +2 -2
- package/dist/destructibles.js +36 -0
- package/dist/destructibles.js.map +1 -0
- package/dist/determinism.d.ts +4 -4
- package/dist/determinism.js +247 -0
- package/dist/determinism.js.map +1 -0
- package/dist/dialog.d.ts +17 -2
- package/dist/dialog.js +108 -0
- package/dist/dialog.js.map +1 -0
- package/dist/effectRefs.js +28 -0
- package/dist/effectRefs.js.map +1 -0
- package/dist/effects.d.ts +27 -11
- package/dist/effects.js +110 -0
- package/dist/effects.js.map +1 -0
- package/dist/endings.d.ts +1 -1
- package/dist/endings.js +78 -0
- package/dist/endings.js.map +1 -0
- package/dist/engagement.d.ts +40 -6
- package/dist/engagement.js +530 -0
- package/dist/engagement.js.map +1 -0
- package/dist/engineEvents.d.ts +72 -9
- package/dist/engineEvents.js +520 -0
- package/dist/engineEvents.js.map +1 -0
- package/dist/entity.d.ts +275 -26
- package/dist/entity.js +441 -0
- package/dist/entity.js.map +1 -0
- package/dist/entityIndex.d.ts +10 -3
- package/dist/entityIndex.js +149 -0
- package/dist/entityIndex.js.map +1 -0
- package/dist/errors.d.ts +6 -2
- package/dist/errors.js +59 -0
- package/dist/errors.js.map +1 -0
- package/dist/events.d.ts +11 -5
- package/dist/events.js +158 -0
- package/dist/events.js.map +1 -0
- package/dist/exactMath.js +273 -0
- package/dist/exactMath.js.map +1 -0
- package/dist/features.d.ts +1 -1
- package/dist/features.js +127 -0
- package/dist/features.js.map +1 -0
- package/dist/fields.d.ts +25 -5
- package/dist/fields.js +140 -0
- package/dist/fields.js.map +1 -0
- package/dist/fixture.d.ts +3 -3
- package/dist/fixture.js +512 -0
- package/dist/fixture.js.map +1 -0
- package/dist/fog.d.ts +26 -3
- package/dist/fog.js +333 -0
- package/dist/fog.js.map +1 -0
- package/dist/foliage.d.ts +476 -0
- package/dist/foliage.js +1478 -0
- package/dist/foliage.js.map +1 -0
- package/dist/foliageDebug.d.ts +57 -0
- package/dist/foliageDebug.js +172 -0
- package/dist/foliageDebug.js.map +1 -0
- package/dist/foliageRegrowth.d.ts +20 -0
- package/dist/foliageRegrowth.js +332 -0
- package/dist/foliageRegrowth.js.map +1 -0
- package/dist/formState.d.ts +67 -0
- package/dist/formState.js +65 -0
- package/dist/formState.js.map +1 -0
- package/dist/formation.d.ts +46 -8
- package/dist/formation.js +297 -0
- package/dist/formation.js.map +1 -0
- package/dist/forms.d.ts +58 -0
- package/dist/forms.js +146 -0
- package/dist/forms.js.map +1 -0
- package/dist/friendlyFire.d.ts +2 -2
- package/dist/friendlyFire.js +37 -0
- package/dist/friendlyFire.js.map +1 -0
- package/dist/game.d.ts +141 -48
- package/dist/game.js +834 -0
- package/dist/game.js.map +1 -0
- package/dist/gameData.d.ts +96 -22
- package/dist/gameData.js +1690 -0
- package/dist/gameData.js.map +1 -0
- package/dist/gameFiles.d.ts +3 -3
- package/dist/gameFiles.js +14 -0
- package/dist/gameFiles.js.map +1 -0
- package/dist/gates.js +92 -0
- package/dist/gates.js.map +1 -0
- package/dist/generate.d.ts +28 -1
- package/dist/generate.js +1062 -0
- package/dist/generate.js.map +1 -0
- package/dist/generateWorker.d.ts +7 -3
- package/dist/generateWorker.js +86 -0
- package/dist/generateWorker.js.map +1 -0
- package/dist/grid.d.ts +9 -0
- package/dist/grid.js +102 -0
- package/dist/grid.js.map +1 -0
- package/dist/ground.d.ts +17 -1
- package/dist/ground.js +375 -0
- package/dist/ground.js.map +1 -0
- package/dist/groundObjects.d.ts +70 -0
- package/dist/groundObjects.js +371 -0
- package/dist/groundObjects.js.map +1 -0
- package/dist/groundSpeed.d.ts +20 -3
- package/dist/groundSpeed.js +117 -0
- package/dist/groundSpeed.js.map +1 -0
- package/dist/hero.d.ts +126 -10
- package/dist/hero.js +432 -0
- package/dist/hero.js.map +1 -0
- package/dist/holds.d.ts +94 -0
- package/dist/holds.js +305 -0
- package/dist/holds.js.map +1 -0
- package/dist/home.d.ts +1 -1
- package/dist/home.js +30 -0
- package/dist/home.js.map +1 -0
- package/dist/hooks.d.ts +339 -57
- package/dist/hooks.js +105 -0
- package/dist/hooks.js.map +1 -0
- package/dist/hotReload.d.ts +6 -5
- package/dist/hotReload.js +145 -0
- package/dist/hotReload.js.map +1 -0
- package/dist/ids.d.ts +3 -3
- package/dist/ids.js +30 -0
- package/dist/ids.js.map +1 -0
- package/dist/idsFile.d.ts +36 -0
- package/dist/idsFile.js +134 -0
- package/dist/idsFile.js.map +1 -0
- package/dist/index.d.ts +105 -68
- package/dist/index.js +194 -4701
- package/dist/inspect.d.ts +29 -2
- package/dist/{inspect-D9dWHmZ0.js → inspect.js} +21 -12
- package/dist/inspect.js.map +1 -0
- package/dist/inventory.d.ts +14 -1
- package/dist/inventory.js +84 -0
- package/dist/inventory.js.map +1 -0
- package/dist/items.d.ts +136 -8
- package/dist/items.js +585 -0
- package/dist/items.js.map +1 -0
- package/dist/lanes.d.ts +12 -3
- package/dist/lanes.js +496 -0
- package/dist/lanes.js.map +1 -0
- package/dist/life.d.ts +6 -2
- package/dist/life.js +287 -0
- package/dist/life.js.map +1 -0
- package/dist/log.d.ts +26 -3
- package/dist/log.js +192 -0
- package/dist/log.js.map +1 -0
- package/dist/manaBurn.d.ts +2 -2
- package/dist/manaBurn.js +75 -0
- package/dist/manaBurn.js.map +1 -0
- package/dist/map/file.d.ts +56 -3
- package/dist/map/file.js +264 -0
- package/dist/map/file.js.map +1 -0
- package/dist/map/images.js +61 -0
- package/dist/map/images.js.map +1 -0
- package/dist/map/look.d.ts +1 -1
- package/dist/map/look.js +30 -0
- package/dist/map/look.js.map +1 -0
- package/dist/map/pathProfile.js +183 -0
- package/dist/map/pathProfile.js.map +1 -0
- package/dist/map/resize.d.ts +4 -0
- package/dist/map/resize.js +136 -0
- package/dist/map/resize.js.map +1 -0
- package/dist/map/schema.js +257 -0
- package/dist/map/schema.js.map +1 -0
- package/dist/map/terrain.js +214 -0
- package/dist/map/terrain.js.map +1 -0
- package/dist/map/types.d.ts +92 -13
- package/dist/map/types.js +251 -0
- package/dist/map/types.js.map +1 -0
- package/dist/mapCheck/cells.js +94 -0
- package/dist/mapCheck/cells.js.map +1 -0
- package/dist/mapCheck/rules/foliage.d.ts +9 -0
- package/dist/mapCheck/rules/foliage.js +83 -0
- package/dist/mapCheck/rules/foliage.js.map +1 -0
- package/dist/mapCheck/rules/names.js +39 -0
- package/dist/mapCheck/rules/names.js.map +1 -0
- package/dist/mapCheck/rules/objects.d.ts +1 -1
- package/dist/mapCheck/rules/objects.js +56 -0
- package/dist/mapCheck/rules/objects.js.map +1 -0
- package/dist/mapCheck/rules/paths.js +32 -0
- package/dist/mapCheck/rules/paths.js.map +1 -0
- package/dist/mapCheck/rules/players.js +20 -0
- package/dist/mapCheck/rules/players.js.map +1 -0
- package/dist/mapCheck/rules/races.js +56 -0
- package/dist/mapCheck/rules/races.js.map +1 -0
- package/dist/mapCheck/rules/random.js +47 -0
- package/dist/mapCheck/rules/random.js.map +1 -0
- package/dist/mapCheck/rules/regions.js +30 -0
- package/dist/mapCheck/rules/regions.js.map +1 -0
- package/dist/mapCheck/rules/targets.js +31 -0
- package/dist/mapCheck/rules/targets.js.map +1 -0
- package/dist/mapCheck/rules/walking.js +45 -0
- package/dist/mapCheck/rules/walking.js.map +1 -0
- package/dist/mapCheck.d.ts +2 -2
- package/dist/mapCheck.js +63 -0
- package/dist/mapCheck.js.map +1 -0
- package/dist/mapFields.d.ts +25 -2
- package/dist/mapFields.js +134 -0
- package/dist/mapFields.js.map +1 -0
- package/dist/mapFile.js +176 -0
- package/dist/mapFile.js.map +1 -0
- package/dist/mapMeasure.d.ts +8 -0
- package/dist/mapMeasure.js +283 -0
- package/dist/mapMeasure.js.map +1 -0
- package/dist/mapMerge.d.ts +1 -0
- package/dist/mapMerge.js +172 -0
- package/dist/mapMerge.js.map +1 -0
- package/dist/mapObjectives.js +138 -0
- package/dist/mapObjectives.js.map +1 -0
- package/dist/mapObjects.js +80 -0
- package/dist/mapObjects.js.map +1 -0
- package/dist/math.d.ts +37 -7
- package/dist/math.js +155 -0
- package/dist/math.js.map +1 -0
- package/dist/messages.d.ts +71 -4
- package/dist/messages.js +29 -0
- package/dist/messages.js.map +1 -0
- package/dist/missionRules.d.ts +10 -2
- package/dist/{missionRules-C-bGxm0Q.js → missionRules.js} +30 -150
- package/dist/missionRules.js.map +1 -0
- package/dist/mods.d.ts +39 -20
- package/dist/mods.js +271 -0
- package/dist/mods.js.map +1 -0
- package/dist/moves.d.ts +87 -0
- package/dist/moves.js +539 -0
- package/dist/moves.js.map +1 -0
- package/dist/names.d.ts +7 -0
- package/dist/names.js +122 -0
- package/dist/names.js.map +1 -0
- package/dist/navigation/agentParams.js +14 -0
- package/dist/navigation/agentParams.js.map +1 -0
- package/dist/navigation/air.d.ts +7 -3
- package/dist/navigation/air.js +401 -0
- package/dist/navigation/air.js.map +1 -0
- package/dist/navigation/builds.d.ts +34 -2
- package/dist/navigation/builds.js +287 -0
- package/dist/navigation/builds.js.map +1 -0
- package/dist/navigation/groundAreas.d.ts +59 -1
- package/dist/navigation/groundAreas.js +407 -0
- package/dist/navigation/groundAreas.js.map +1 -0
- package/dist/navigation/navigation.d.ts +98 -9
- package/dist/navigation/recast.d.ts +194 -18
- package/dist/navigation/recast.js +1379 -0
- package/dist/navigation/recast.js.map +1 -0
- package/dist/navigation/sidePaths.d.ts +8 -3
- package/dist/navigation/sidePaths.js +241 -0
- package/dist/navigation/sidePaths.js.map +1 -0
- package/dist/navigation/sized.js +243 -0
- package/dist/navigation/sized.js.map +1 -0
- package/dist/nearest.js +32 -0
- package/dist/nearest.js.map +1 -0
- package/dist/noise.js +59 -0
- package/dist/noise.js.map +1 -0
- package/dist/objectives.d.ts +12 -3
- package/dist/objectives.js +144 -0
- package/dist/objectives.js.map +1 -0
- package/dist/orders/basic.d.ts +5 -5
- package/dist/orders/basic.js +417 -0
- package/dist/orders/basic.js.map +1 -0
- package/dist/orders/build.js +278 -0
- package/dist/orders/build.js.map +1 -0
- package/dist/orders/cast.d.ts +13 -3
- package/dist/orders/cast.js +558 -0
- package/dist/orders/cast.js.map +1 -0
- package/dist/orders/facts.js +16 -0
- package/dist/orders/facts.js.map +1 -0
- package/dist/orders/harvest.d.ts +21 -5
- package/dist/orders/harvest.js +540 -0
- package/dist/orders/harvest.js.map +1 -0
- package/dist/orders/idle.d.ts +3 -1
- package/dist/orders/idle.js +234 -0
- package/dist/orders/idle.js.map +1 -0
- package/dist/orders/items.js +92 -0
- package/dist/orders/items.js.map +1 -0
- package/dist/orders/queue.js +108 -0
- package/dist/orders/queue.js.map +1 -0
- package/dist/orders/waiting.d.ts +39 -0
- package/dist/orders/waiting.js +149 -0
- package/dist/orders/waiting.js.map +1 -0
- package/dist/pack.schema.js +13 -0
- package/dist/pack.schema.js.map +1 -0
- package/dist/pack.schema.json +7622 -841
- package/dist/packs/director/index.d.ts +13 -5
- package/dist/packs/director/index.js +204 -0
- package/dist/packs/director/index.js.map +1 -0
- package/dist/packs/heroes/campaign.d.ts +3 -2
- package/dist/packs/heroes/campaign.js +241 -0
- package/dist/packs/heroes/campaign.js.map +1 -0
- package/dist/packs/heroes/carry.d.ts +6 -0
- package/dist/packs/heroes/carry.js +112 -0
- package/dist/packs/heroes/carry.js.map +1 -0
- package/dist/packs/heroes/commands.js +115 -0
- package/dist/packs/heroes/commands.js.map +1 -0
- package/dist/packs/heroes/fallen.d.ts +43 -0
- package/dist/packs/heroes/fallen.js +61 -0
- package/dist/packs/heroes/fallen.js.map +1 -0
- package/dist/packs/heroes/hire.js +60 -0
- package/dist/packs/heroes/hire.js.map +1 -0
- package/dist/packs/heroes/index.d.ts +7 -6
- package/dist/packs/heroes/index.js +130 -0
- package/dist/packs/heroes/index.js.map +1 -0
- package/dist/packs/heroes/loop.d.ts +95 -0
- package/dist/packs/heroes/loop.js +250 -0
- package/dist/packs/heroes/loop.js.map +1 -0
- package/dist/packs/heroes/making.d.ts +6 -3
- package/dist/packs/heroes/making.js +55 -0
- package/dist/packs/heroes/making.js.map +1 -0
- package/dist/packs/heroes/respawn.d.ts +3 -3
- package/dist/packs/heroes/respawn.js +87 -0
- package/dist/packs/heroes/respawn.js.map +1 -0
- package/dist/packs/heroes/sets.d.ts +32 -0
- package/dist/packs/heroes/sets.js +51 -0
- package/dist/packs/heroes/sets.js.map +1 -0
- package/dist/packs/heroes/spells.d.ts +16 -0
- package/dist/packs/heroes/spells.js +269 -0
- package/dist/packs/heroes/spells.js.map +1 -0
- package/dist/packs/items/defaults.d.ts +43 -0
- package/dist/packs/items/defaults.js +1504 -0
- package/dist/packs/items/defaults.js.map +1 -0
- package/dist/packs/items/index.d.ts +27 -0
- package/dist/packs/items/index.js +214 -0
- package/dist/packs/items/index.js.map +1 -0
- package/dist/packs/moba/index.d.ts +3 -3
- package/dist/packs/moba/index.js +174 -0
- package/dist/packs/moba/index.js.map +1 -0
- package/dist/packs/pack.d.ts +15 -15
- package/dist/packs/pack.js +14 -0
- package/dist/packs/pack.js.map +1 -0
- package/dist/packs.d.ts +15 -7
- package/dist/packs.js +222 -0
- package/dist/packs.js.map +1 -0
- package/dist/paths.d.ts +2 -0
- package/dist/paths.js +109 -0
- package/dist/paths.js.map +1 -0
- package/dist/plain.js +57 -0
- package/dist/plain.js.map +1 -0
- package/dist/player.d.ts +33 -10
- package/dist/player.js +159 -0
- package/dist/player.js.map +1 -0
- package/dist/portals.d.ts +1 -1
- package/dist/portals.js +194 -0
- package/dist/portals.js.map +1 -0
- package/dist/prefabs.d.ts +25 -2
- package/dist/prefabs.js +239 -0
- package/dist/prefabs.js.map +1 -0
- package/dist/presetBuildings.js +58 -0
- package/dist/presetBuildings.js.map +1 -0
- package/dist/presetFoliage.d.ts +27 -0
- package/dist/presetFoliage.js +98 -0
- package/dist/presetFoliage.js.map +1 -0
- package/dist/presetGround.js +65 -0
- package/dist/presetGround.js.map +1 -0
- package/dist/proxies.d.ts +12 -0
- package/dist/proxies.js +79 -0
- package/dist/proxies.js.map +1 -0
- package/dist/query.d.ts +56 -0
- package/dist/query.js +88 -0
- package/dist/query.js.map +1 -0
- package/dist/races.d.ts +15 -14
- package/dist/races.js +172 -0
- package/dist/races.js.map +1 -0
- package/dist/randomGroups.js +91 -0
- package/dist/randomGroups.js.map +1 -0
- package/dist/registry.d.ts +117 -53
- package/dist/registry.js +323 -0
- package/dist/registry.js.map +1 -0
- package/dist/remains.d.ts +11 -9
- package/dist/remains.js +188 -0
- package/dist/remains.js.map +1 -0
- package/dist/replication.d.ts +12 -7
- package/dist/replication.js +100 -0
- package/dist/replication.js.map +1 -0
- package/dist/rng.d.ts +2 -0
- package/dist/rng.js +40 -0
- package/dist/rng.js.map +1 -0
- package/dist/rules.d.ts +186 -99
- package/dist/rules.js +179 -0
- package/dist/rules.js.map +1 -0
- package/dist/rulesCheck.d.ts +5 -4
- package/dist/rulesCheck.js +693 -0
- package/dist/rulesCheck.js.map +1 -0
- package/dist/runes.d.ts +2 -2
- package/dist/runes.js +80 -0
- package/dist/runes.js.map +1 -0
- package/dist/save.d.ts +37 -12
- package/dist/save.js +532 -0
- package/dist/save.js.map +1 -0
- package/dist/scenario.d.ts +2 -2
- package/dist/scenario.js +99 -0
- package/dist/scenario.js.map +1 -0
- package/dist/scheduler.d.ts +3 -0
- package/dist/scheduler.js +156 -0
- package/dist/scheduler.js.map +1 -0
- package/dist/score.d.ts +19 -19
- package/dist/score.js +709 -0
- package/dist/score.js.map +1 -0
- package/dist/sequences.d.ts +10 -6
- package/dist/sequences.js +206 -0
- package/dist/sequences.js.map +1 -0
- package/dist/server/doorman.js +154 -0
- package/dist/server/doorman.js.map +1 -0
- package/dist/server/gameServer.d.ts +16 -1
- package/dist/server/gameServer.js +643 -0
- package/dist/server/gameServer.js.map +1 -0
- package/dist/server/index.d.ts +1 -1
- package/dist/server/lobby.js +199 -0
- package/dist/server/lobby.js.map +1 -0
- package/dist/server/log.js +18 -0
- package/dist/server/log.js.map +1 -0
- package/dist/server/match.js +267 -0
- package/dist/server/match.js.map +1 -0
- package/dist/server/mode.d.ts +18 -9
- package/dist/server/mode.js +220 -0
- package/dist/server/mode.js.map +1 -0
- package/dist/{navigation-worker.js → server/navigation-worker.js} +1 -1
- package/dist/server/navigation-worker.js.map +1 -0
- package/dist/server/navigation.js +39 -0
- package/dist/server/navigation.js.map +1 -0
- package/dist/server/ops.d.ts +4 -0
- package/dist/server/ops.js +137 -0
- package/dist/server/ops.js.map +1 -0
- package/dist/server/packs.d.ts +3 -3
- package/dist/server/packs.js +32 -0
- package/dist/server/packs.js.map +1 -0
- package/dist/server/ratings.d.ts +5 -0
- package/dist/server/ratings.js +104 -0
- package/dist/server/ratings.js.map +1 -0
- package/dist/server/relay.d.ts +12 -2
- package/dist/server/relay.js +144 -0
- package/dist/server/relay.js.map +1 -0
- package/dist/server/rooms.d.ts +9 -2
- package/dist/server/rooms.js +442 -0
- package/dist/server/rooms.js.map +1 -0
- package/dist/server/seat.js +116 -0
- package/dist/server/seat.js.map +1 -0
- package/dist/server/seatSettings.d.ts +3 -3
- package/dist/server/seatSettings.js +63 -0
- package/dist/server/seatSettings.js.map +1 -0
- package/dist/server/secret.js +13 -0
- package/dist/server/secret.js.map +1 -0
- package/dist/server/start.d.ts +13 -6
- package/dist/server/start.js +76 -0
- package/dist/server/start.js.map +1 -0
- package/dist/server/websocket.d.ts +9 -1
- package/dist/server/websocket.js +306 -0
- package/dist/server/websocket.js.map +1 -0
- package/dist/server.js +15 -2861
- package/dist/session/can.js +26 -0
- package/dist/session/can.js.map +1 -0
- package/dist/session/commandReplay.d.ts +8 -2
- package/dist/session/commandReplay.js +293 -0
- package/dist/session/commandReplay.js.map +1 -0
- package/dist/session/debug.js +151 -0
- package/dist/session/debug.js.map +1 -0
- package/dist/session/delay.js +62 -0
- package/dist/session/delay.js.map +1 -0
- package/dist/session/delta.d.ts +14 -1
- package/dist/session/delta.js +407 -0
- package/dist/session/delta.js.map +1 -0
- package/dist/session/entityState.js +415 -0
- package/dist/session/entityState.js.map +1 -0
- package/dist/session/local.d.ts +47 -5
- package/dist/session/local.js +670 -0
- package/dist/session/local.js.map +1 -0
- package/dist/session/memory.d.ts +20 -2
- package/dist/session/memory.js +131 -0
- package/dist/session/memory.js.map +1 -0
- package/dist/session/protocol.d.ts +325 -31
- package/dist/session/protocol.js +55 -0
- package/dist/session/protocol.js.map +1 -0
- package/dist/session/remote.d.ts +74 -12
- package/dist/session/remote.js +1394 -0
- package/dist/session/remote.js.map +1 -0
- package/dist/session/replay.d.ts +11 -2
- package/dist/session/replay.js +160 -0
- package/dist/session/replay.js.map +1 -0
- package/dist/session/seed.js +12 -0
- package/dist/session/seed.js.map +1 -0
- package/dist/session/share.d.ts +5 -1
- package/dist/session/share.js +94 -0
- package/dist/session/share.js.map +1 -0
- package/dist/session/socket.d.ts +1 -1
- package/dist/session/socket.js +29 -0
- package/dist/session/socket.js.map +1 -0
- package/dist/session/wire.d.ts +5 -0
- package/dist/session/wire.js +84 -0
- package/dist/session/wire.js.map +1 -0
- package/dist/session/worker.d.ts +77 -12
- package/dist/session/worker.js +499 -0
- package/dist/session/worker.js.map +1 -0
- package/dist/shared.d.ts +31 -5
- package/dist/shared.js +166 -0
- package/dist/shared.js.map +1 -0
- package/dist/sides.d.ts +9 -3
- package/dist/sides.js +149 -0
- package/dist/sides.js.map +1 -0
- package/dist/sight.js +85 -0
- package/dist/sight.js.map +1 -0
- package/dist/simulate-worker.js +1 -1
- package/dist/simulate.d.ts +12 -8
- package/dist/{simulate-oXBiw1Ff.js → simulate.js} +10 -11
- package/dist/simulate.js.map +1 -0
- package/dist/smart.js +77 -0
- package/dist/smart.js.map +1 -0
- package/dist/spatial.d.ts +32 -16
- package/dist/spatial.js +234 -0
- package/dist/spatial.js.map +1 -0
- package/dist/spawning.d.ts +1 -0
- package/dist/spawning.js +224 -0
- package/dist/spawning.js.map +1 -0
- package/dist/stances.d.ts +6 -3
- package/dist/stances.js +169 -0
- package/dist/stances.js.map +1 -0
- package/dist/start.d.ts +10 -10
- package/dist/start.js +75 -0
- package/dist/start.js.map +1 -0
- package/dist/stats.d.ts +42 -16
- package/dist/stats.js +290 -0
- package/dist/stats.js.map +1 -0
- package/dist/summoned.d.ts +52 -0
- package/dist/summoned.js +38 -0
- package/dist/summoned.js.map +1 -0
- package/dist/summons.d.ts +10 -13
- package/dist/summons.js +271 -0
- package/dist/summons.js.map +1 -0
- package/dist/systems/abilities.js +224 -0
- package/dist/systems/abilities.js.map +1 -0
- package/dist/systems/combat.d.ts +35 -1
- package/dist/systems/combat.js +677 -0
- package/dist/systems/combat.js.map +1 -0
- package/dist/systems/combatTold.d.ts +3 -1
- package/dist/systems/combatTold.js +85 -0
- package/dist/systems/combatTold.js.map +1 -0
- package/dist/systems/construction.js +80 -0
- package/dist/systems/construction.js.map +1 -0
- package/dist/systems/economy.d.ts +0 -6
- package/dist/systems/economy.js +128 -0
- package/dist/systems/economy.js.map +1 -0
- package/dist/systems/fog.d.ts +1 -1
- package/dist/systems/fog.js +120 -0
- package/dist/systems/fog.js.map +1 -0
- package/dist/systems/life.js +32 -0
- package/dist/systems/life.js.map +1 -0
- package/dist/systems/movement.d.ts +24 -12
- package/dist/systems/movement.js +1247 -0
- package/dist/systems/movement.js.map +1 -0
- package/dist/systems/orders.js +64 -0
- package/dist/systems/orders.js.map +1 -0
- package/dist/systems/production.js +322 -0
- package/dist/systems/production.js.map +1 -0
- package/dist/systems/productionQueue.js +120 -0
- package/dist/systems/productionQueue.js.map +1 -0
- package/dist/systems/victory.d.ts +1 -1
- package/dist/systems/victory.js +56 -0
- package/dist/systems/victory.js.map +1 -0
- package/dist/talk.d.ts +6 -6
- package/dist/talk.js +153 -0
- package/dist/talk.js.map +1 -0
- package/dist/targeting.d.ts +142 -0
- package/dist/targeting.js +49 -0
- package/dist/targeting.js.map +1 -0
- package/dist/tech.d.ts +20 -3
- package/dist/tech.js +239 -0
- package/dist/tech.js.map +1 -0
- package/dist/techTree.d.ts +7 -0
- package/dist/techTree.js +90 -0
- package/dist/techTree.js.map +1 -0
- package/dist/terrain.d.ts +59 -7
- package/dist/terrain.js +389 -0
- package/dist/terrain.js.map +1 -0
- package/dist/terrainSave.d.ts +6 -0
- package/dist/terrainSave.js +74 -0
- package/dist/terrainSave.js.map +1 -0
- package/dist/testing.d.ts +8 -7
- package/dist/testing.js +13 -739
- package/dist/testing.js.map +1 -1
- package/dist/tiles.d.ts +1 -1
- package/dist/tiles.js +43 -0
- package/dist/tiles.js.map +1 -0
- package/dist/timers.d.ts +29 -4
- package/dist/timers.js +242 -0
- package/dist/timers.js.map +1 -0
- package/dist/tomes.d.ts +4 -4
- package/dist/tomes.js +94 -0
- package/dist/tomes.js.map +1 -0
- package/dist/trade.js +103 -0
- package/dist/trade.js.map +1 -0
- package/dist/transport.d.ts +6 -1
- package/dist/transport.js +281 -0
- package/dist/transport.js.map +1 -0
- package/dist/tunables.d.ts +10 -3
- package/dist/tunables.js +56 -0
- package/dist/tunables.js.map +1 -0
- package/dist/unitResources.d.ts +67 -0
- package/dist/unitResources.js +266 -0
- package/dist/unitResources.js.map +1 -0
- package/dist/upkeep.d.ts +6 -1
- package/dist/upkeep.js +26 -0
- package/dist/upkeep.js.map +1 -0
- package/dist/veterancy.d.ts +8 -3
- package/dist/veterancy.js +131 -0
- package/dist/veterancy.js.map +1 -0
- package/dist/vision.d.ts +36 -0
- package/dist/vision.js +133 -0
- package/dist/vision.js.map +1 -0
- package/dist/walls.d.ts +1 -1
- package/dist/walls.js +278 -0
- package/dist/walls.js.map +1 -0
- package/dist/world.d.ts +606 -88
- package/dist/world.js +1263 -0
- package/dist/world.js.map +1 -0
- package/package.json +2 -2
- package/dist/ai.js.map +0 -1
- package/dist/attributes.d.ts +0 -66
- package/dist/brain-BvVdUhX8.js +0 -7659
- package/dist/brain-BvVdUhX8.js.map +0 -1
- package/dist/builds-C6LfgvEU.js +0 -460
- package/dist/builds-C6LfgvEU.js.map +0 -1
- package/dist/coreComponents-syuh2fPG.js +0 -5149
- package/dist/coreComponents-syuh2fPG.js.map +0 -1
- package/dist/debugCommands-CzjrSm66.js +0 -14739
- package/dist/debugCommands-CzjrSm66.js.map +0 -1
- package/dist/determinism-BCymQwiE.js +0 -518
- package/dist/determinism-BCymQwiE.js.map +0 -1
- package/dist/game-DiJEN-Ks.js +0 -5800
- package/dist/game-DiJEN-Ks.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/inspect-D9dWHmZ0.js.map +0 -1
- package/dist/local-Dkovq42k.js +0 -1379
- package/dist/local-Dkovq42k.js.map +0 -1
- package/dist/missionRules-C-bGxm0Q.js.map +0 -1
- package/dist/navigation-worker.js.map +0 -1
- package/dist/packs-g5thvmGn.js +0 -3199
- package/dist/packs-g5thvmGn.js.map +0 -1
- package/dist/profiles-B3NS9jwk.js.map +0 -1
- package/dist/server.js.map +0 -1
- package/dist/simulate-oXBiw1Ff.js.map +0 -1
package/dist/generate.js
ADDED
|
@@ -0,0 +1,1062 @@
|
|
|
1
|
+
import { atan, atan2, cos, hypot, sin } from "./exactMath.js";
|
|
2
|
+
import { createMap } from "./map/types.js";
|
|
3
|
+
import { Rng } from "./rng.js";
|
|
4
|
+
import "./terrain.js";
|
|
5
|
+
import { mapTerrain } from "./map/terrain.js";
|
|
6
|
+
import { layeredNoise } from "./noise.js";
|
|
7
|
+
import { checkMap } from "./mapCheck.js";
|
|
8
|
+
//#region src/generate.ts
|
|
9
|
+
/**
|
|
10
|
+
* Maps made by a generator (world plan G1): a map from a seed and a few sliders, made of passes a game adds to,
|
|
11
|
+
* replaces or leaves out, each a function of a context that holds the map, the seed's numbers, noise that repeats
|
|
12
|
+
* across the map, the symmetry and what the passes before put down. Deterministic: the engine's `Rng`, nothing of
|
|
13
|
+
* the clock. The engine's own passes shape the ground (`terrainPass`), paint it (`tilesPass`), seat the players
|
|
14
|
+
* (`startsPass`), scatter things over it (`scatterPass`: trees now, rocks and houses the same way later), put
|
|
15
|
+
* resources near the starts (`resourcesPass`) and lay roads (`roadsPass`); `generateMap` runs them and checks the map
|
|
16
|
+
* (`checkMap`), trying the next seed where a start is cut off or blocked. A game declares its generator
|
|
17
|
+
* (`Rules.generator`), for the editor and the page to find; `presetGenerator` is the engine's to take whole
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* The map a generator makes of options: its passes run in order on a map of the size and players asked, with the
|
|
21
|
+
* game's tiles; then checked (`checkMap`). A map with a problem that keeps it from being played (a start cut off from
|
|
22
|
+
* the others, or where nothing walks) is thrown away and the next seed tried, `tries` times; the last is given with
|
|
23
|
+
* its problems. The map says how it was made (`GameMap.generated`)
|
|
24
|
+
*
|
|
25
|
+
* @beta
|
|
26
|
+
*/
|
|
27
|
+
function generateMap(generator, options, registry) {
|
|
28
|
+
const tries = Math.max(1, generator.tries ?? 4);
|
|
29
|
+
let last;
|
|
30
|
+
for (let attempt = 0; attempt < tries; attempt++) {
|
|
31
|
+
const seed = options.seed + attempt;
|
|
32
|
+
const map = createMap({
|
|
33
|
+
name: options.name ?? `Generated ${seed}`,
|
|
34
|
+
width: options.width,
|
|
35
|
+
depth: options.depth,
|
|
36
|
+
players: options.players,
|
|
37
|
+
game: registry.module?.id,
|
|
38
|
+
tileset: registry.tileIds
|
|
39
|
+
});
|
|
40
|
+
const ctx = createContext(map, {
|
|
41
|
+
...options,
|
|
42
|
+
seed
|
|
43
|
+
}, registry, generator);
|
|
44
|
+
for (const pass of generator.passes) pass.run(ctx);
|
|
45
|
+
map.generated = {
|
|
46
|
+
seed,
|
|
47
|
+
options: {
|
|
48
|
+
...options,
|
|
49
|
+
seed
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
const problems = checkMap(map, registry);
|
|
53
|
+
last = {
|
|
54
|
+
map,
|
|
55
|
+
problems,
|
|
56
|
+
seed
|
|
57
|
+
};
|
|
58
|
+
if (!problems.some(unplayable)) return last;
|
|
59
|
+
}
|
|
60
|
+
return last;
|
|
61
|
+
}
|
|
62
|
+
/** What keeps a map from being played, so that the next seed is tried: an error, or a start cut off from the others or blocked */
|
|
63
|
+
var unplayable = (problem) => problem.error || problem.rule === "starts-apart" || problem.rule === "start-blocked";
|
|
64
|
+
var SYMMETRIES = [
|
|
65
|
+
"none",
|
|
66
|
+
"x",
|
|
67
|
+
"z",
|
|
68
|
+
"both",
|
|
69
|
+
"half",
|
|
70
|
+
"quarter"
|
|
71
|
+
];
|
|
72
|
+
/**
|
|
73
|
+
* The places a point is mirrored or turned to, the point first (as the editor's `mirrors`)
|
|
74
|
+
*
|
|
75
|
+
* @beta
|
|
76
|
+
*/
|
|
77
|
+
function symmetricPlaces(symmetry, width, depth, x, z) {
|
|
78
|
+
const out = [{
|
|
79
|
+
x,
|
|
80
|
+
z
|
|
81
|
+
}];
|
|
82
|
+
const add = (px, pz) => {
|
|
83
|
+
if (!out.some((other) => Math.abs(other.x - px) < 1e-6 && Math.abs(other.z - pz) < 1e-6)) out.push({
|
|
84
|
+
x: px,
|
|
85
|
+
z: pz
|
|
86
|
+
});
|
|
87
|
+
};
|
|
88
|
+
switch (symmetry) {
|
|
89
|
+
case "x":
|
|
90
|
+
add(width - x, z);
|
|
91
|
+
break;
|
|
92
|
+
case "z":
|
|
93
|
+
add(x, depth - z);
|
|
94
|
+
break;
|
|
95
|
+
case "both":
|
|
96
|
+
add(width - x, z);
|
|
97
|
+
add(x, depth - z);
|
|
98
|
+
add(width - x, depth - z);
|
|
99
|
+
break;
|
|
100
|
+
case "half":
|
|
101
|
+
add(width - x, depth - z);
|
|
102
|
+
break;
|
|
103
|
+
case "quarter": {
|
|
104
|
+
const cx = width / 2;
|
|
105
|
+
const cz = depth / 2;
|
|
106
|
+
for (let k = 1; k < 4; k++) {
|
|
107
|
+
let px = x - cx;
|
|
108
|
+
let pz = z - cz;
|
|
109
|
+
for (let i = 0; i < k; i++) [px, pz] = [-pz, px];
|
|
110
|
+
add(cx + px, cz + pz);
|
|
111
|
+
}
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return out;
|
|
116
|
+
}
|
|
117
|
+
/** How many places a mirrored set has at most: four, for quarter turns and both ways */
|
|
118
|
+
var MIRRORS = 4;
|
|
119
|
+
/** The first of a point's mirrored set, by row then column: where a noise is read, so the noise is mirrored as the map is */
|
|
120
|
+
function firstPlace(symmetry, width, depth, x, z, out) {
|
|
121
|
+
out.x = x;
|
|
122
|
+
out.z = z;
|
|
123
|
+
const take = (px, pz) => takeFirst(out, px, pz);
|
|
124
|
+
switch (symmetry) {
|
|
125
|
+
case "x":
|
|
126
|
+
take(width - x, z);
|
|
127
|
+
break;
|
|
128
|
+
case "z":
|
|
129
|
+
take(x, depth - z);
|
|
130
|
+
break;
|
|
131
|
+
case "both":
|
|
132
|
+
take(width - x, z);
|
|
133
|
+
take(x, depth - z);
|
|
134
|
+
take(width - x, depth - z);
|
|
135
|
+
break;
|
|
136
|
+
case "half":
|
|
137
|
+
take(width - x, depth - z);
|
|
138
|
+
break;
|
|
139
|
+
case "quarter": {
|
|
140
|
+
const cx = width / 2;
|
|
141
|
+
const cz = depth / 2;
|
|
142
|
+
let px = x - cx;
|
|
143
|
+
let pz = z - cz;
|
|
144
|
+
for (let k = 1; k < 4; k++) {
|
|
145
|
+
[px, pz] = [-pz, px];
|
|
146
|
+
take(cx + px, cz + pz);
|
|
147
|
+
}
|
|
148
|
+
break;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/** The earlier of a place and another, by row then column, kept in `out` */
|
|
153
|
+
function takeFirst(out, px, pz) {
|
|
154
|
+
if (pz < out.z - 1e-6 || Math.abs(pz - out.z) < 1e-6 && px < out.x) {
|
|
155
|
+
out.x = px;
|
|
156
|
+
out.z = pz;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
function createContext(map, options, registry, generator) {
|
|
160
|
+
const { width, depth } = map;
|
|
161
|
+
const symmetry = options.symmetry ?? "none";
|
|
162
|
+
if (!SYMMETRIES.includes(symmetry)) throw new Error(`generateMap: there is no symmetry "${symmetry}": ${SYMMETRIES.join(", ")}`);
|
|
163
|
+
if (symmetry === "quarter" && (width !== depth || width % 2)) throw new Error("generateMap: quarter turns need a square map with even sides");
|
|
164
|
+
const rng = new Rng(options.seed);
|
|
165
|
+
const defaults = Object.fromEntries(generator.params.map((param) => [param.id, param.default]));
|
|
166
|
+
const given = options.params ?? {};
|
|
167
|
+
const noises = /* @__PURE__ */ new Map();
|
|
168
|
+
const placed = [];
|
|
169
|
+
let nextId = 1;
|
|
170
|
+
const mirrors = new Int32Array(width * depth * MIRRORS).fill(-1);
|
|
171
|
+
const canon = new Int32Array(width * depth);
|
|
172
|
+
for (let c = 0; c < canon.length; c++) {
|
|
173
|
+
const cx = c % width;
|
|
174
|
+
const cz = (c - cx) / width;
|
|
175
|
+
let first = c;
|
|
176
|
+
let n = 0;
|
|
177
|
+
for (const place of symmetricPlaces(symmetry, width, depth, cx + .5, cz + .5)) {
|
|
178
|
+
const mx = Math.floor(place.x);
|
|
179
|
+
const mz = Math.floor(place.z);
|
|
180
|
+
if (mx < 0 || mz < 0 || mx >= width || mz >= depth) continue;
|
|
181
|
+
const m = mz * width + mx;
|
|
182
|
+
mirrors[c * MIRRORS + n++] = m;
|
|
183
|
+
first = Math.min(first, m);
|
|
184
|
+
}
|
|
185
|
+
canon[c] = first;
|
|
186
|
+
}
|
|
187
|
+
const GRID = 8;
|
|
188
|
+
const cols = Math.ceil(width / GRID);
|
|
189
|
+
const rows = Math.ceil(depth / GRID);
|
|
190
|
+
const grid = Array.from({ length: cols * rows }, () => []);
|
|
191
|
+
let widest = 0;
|
|
192
|
+
const point = {
|
|
193
|
+
x: 0,
|
|
194
|
+
z: 0
|
|
195
|
+
};
|
|
196
|
+
const drawn = /* @__PURE__ */ new Map();
|
|
197
|
+
return {
|
|
198
|
+
map,
|
|
199
|
+
rng,
|
|
200
|
+
options,
|
|
201
|
+
registry,
|
|
202
|
+
param: (id, fallback) => given[id] ?? defaults[id] ?? fallback,
|
|
203
|
+
symmetric: (x, z) => symmetricPlaces(symmetry, width, depth, x, z),
|
|
204
|
+
canonical: (cx, cz) => canon[cz * width + cx] === cz * width + cx,
|
|
205
|
+
once: (x, z, draw) => {
|
|
206
|
+
const cx = Math.min(Math.max(Math.floor(x), 0), width - 1);
|
|
207
|
+
const cz = Math.min(Math.max(Math.floor(z), 0), depth - 1);
|
|
208
|
+
const key = canon[cz * width + cx];
|
|
209
|
+
if (drawn.has(key)) return drawn.get(key);
|
|
210
|
+
const value = draw();
|
|
211
|
+
drawn.set(key, value);
|
|
212
|
+
return value;
|
|
213
|
+
},
|
|
214
|
+
mirrorsOf: (c) => {
|
|
215
|
+
const out = [];
|
|
216
|
+
for (let i = 0; i < MIRRORS; i++) {
|
|
217
|
+
const m = mirrors[c * MIRRORS + i];
|
|
218
|
+
if (m >= 0) out.push(m);
|
|
219
|
+
}
|
|
220
|
+
return out;
|
|
221
|
+
},
|
|
222
|
+
setCell: (array, c, value) => {
|
|
223
|
+
for (let i = 0; i < MIRRORS; i++) {
|
|
224
|
+
const m = mirrors[c * MIRRORS + i];
|
|
225
|
+
if (m >= 0) array[m] = value;
|
|
226
|
+
}
|
|
227
|
+
},
|
|
228
|
+
noise(name, cells = [
|
|
229
|
+
32,
|
|
230
|
+
16,
|
|
231
|
+
8
|
|
232
|
+
]) {
|
|
233
|
+
let known = noises.get(name);
|
|
234
|
+
if (!known) {
|
|
235
|
+
let salt = 0;
|
|
236
|
+
for (const letter of name) salt = salt * 31 + letter.charCodeAt(0) >>> 0;
|
|
237
|
+
const size = Math.max(width, depth);
|
|
238
|
+
const noise = layeredNoise(options.seed + salt, cells.map((each) => Math.max(1, Math.round(size / each))));
|
|
239
|
+
known = symmetry === "none" ? (x, z) => noise(x / size, z / size) : (x, z) => {
|
|
240
|
+
firstPlace(symmetry, width, depth, x, z, point);
|
|
241
|
+
return noise(point.x / size, point.z / size);
|
|
242
|
+
};
|
|
243
|
+
noises.set(name, known);
|
|
244
|
+
}
|
|
245
|
+
return known;
|
|
246
|
+
},
|
|
247
|
+
placed,
|
|
248
|
+
mark: (kind, x, z, radius) => {
|
|
249
|
+
placed.push({
|
|
250
|
+
kind,
|
|
251
|
+
x,
|
|
252
|
+
z,
|
|
253
|
+
radius
|
|
254
|
+
});
|
|
255
|
+
widest = Math.max(widest, radius);
|
|
256
|
+
const gx = Math.min(Math.max(Math.floor(x / GRID), 0), cols - 1);
|
|
257
|
+
const gz = Math.min(Math.max(Math.floor(z / GRID), 0), rows - 1);
|
|
258
|
+
grid[gz * cols + gx].push(placed.length - 1);
|
|
259
|
+
},
|
|
260
|
+
free: (x, z, radius, kinds) => {
|
|
261
|
+
const reach = Math.ceil((radius + widest) / GRID);
|
|
262
|
+
const gx = Math.floor(x / GRID);
|
|
263
|
+
const gz = Math.floor(z / GRID);
|
|
264
|
+
for (let dz = -reach; dz <= reach; dz++) for (let dx = -reach; dx <= reach; dx++) {
|
|
265
|
+
const gxx = gx + dx;
|
|
266
|
+
const gzz = gz + dz;
|
|
267
|
+
if (gxx < 0 || gzz < 0 || gxx >= cols || gzz >= rows) continue;
|
|
268
|
+
for (const i of grid[gzz * cols + gxx]) {
|
|
269
|
+
const each = placed[i];
|
|
270
|
+
if (kinds && !kinds.includes(each.kind)) continue;
|
|
271
|
+
if (hypot(each.x - x, each.z - z) < radius + each.radius) return false;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
return true;
|
|
275
|
+
},
|
|
276
|
+
levelAt: (x, z) => {
|
|
277
|
+
const cx = Math.min(Math.max(Math.floor(x), 0), width - 1);
|
|
278
|
+
const cz = Math.min(Math.max(Math.floor(z), 0), depth - 1);
|
|
279
|
+
return map.levels[cz * width + cx];
|
|
280
|
+
},
|
|
281
|
+
walkable: (x, z) => {
|
|
282
|
+
if (x < 0 || z < 0 || x >= width || z >= depth) return false;
|
|
283
|
+
return map.water[Math.floor(z) * width + Math.floor(x)] !== 2;
|
|
284
|
+
},
|
|
285
|
+
addDoodad(doodad) {
|
|
286
|
+
const { scale = 1, yaw = 0, ...rest } = doodad;
|
|
287
|
+
const made = {
|
|
288
|
+
id: nextId++,
|
|
289
|
+
yaw,
|
|
290
|
+
scale: typeof scale === "number" ? [
|
|
291
|
+
scale,
|
|
292
|
+
scale,
|
|
293
|
+
scale
|
|
294
|
+
] : scale,
|
|
295
|
+
...rest
|
|
296
|
+
};
|
|
297
|
+
map.doodads.push(made);
|
|
298
|
+
return made;
|
|
299
|
+
},
|
|
300
|
+
addObject(type, owner, x, z, more = {}) {
|
|
301
|
+
const made = {
|
|
302
|
+
id: nextId++,
|
|
303
|
+
type,
|
|
304
|
+
owner,
|
|
305
|
+
x,
|
|
306
|
+
z,
|
|
307
|
+
facing: 0,
|
|
308
|
+
scale: 1,
|
|
309
|
+
...more
|
|
310
|
+
};
|
|
311
|
+
map.objects.push(made);
|
|
312
|
+
return made;
|
|
313
|
+
},
|
|
314
|
+
addCamp(x, z, units, more = {}) {
|
|
315
|
+
const made = {
|
|
316
|
+
id: nextId++,
|
|
317
|
+
x,
|
|
318
|
+
z,
|
|
319
|
+
units,
|
|
320
|
+
...more
|
|
321
|
+
};
|
|
322
|
+
map.camps.push(made);
|
|
323
|
+
return made;
|
|
324
|
+
},
|
|
325
|
+
addRegion(name, shape, more = {}) {
|
|
326
|
+
const made = {
|
|
327
|
+
id: nextId++,
|
|
328
|
+
name,
|
|
329
|
+
shape,
|
|
330
|
+
...more
|
|
331
|
+
};
|
|
332
|
+
map.regions.push(made);
|
|
333
|
+
return made;
|
|
334
|
+
}
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* The lie of a bay, for `terrainPass`'s `shape`: the corners high, the ground falling to a sea in the middle, an
|
|
339
|
+
* island in it. With `water` at 0.25–0.35 the sea takes the middle and the shore runs round it; the starts in the
|
|
340
|
+
* corners (`startsPass` with a spread of 0.4), the way between them along the shore
|
|
341
|
+
*
|
|
342
|
+
* @beta
|
|
343
|
+
*/
|
|
344
|
+
function basinShape(options = {}) {
|
|
345
|
+
const island = Math.min(Math.max(options.island ?? .14, 0), .5);
|
|
346
|
+
const roughness = Math.min(Math.max(options.roughness ?? .25, 0), 1);
|
|
347
|
+
const height = Math.min(Math.max(options.height ?? .4, 0), 1);
|
|
348
|
+
return (x, z, noise, map) => {
|
|
349
|
+
const d = hypot((x / map.width - .5) * 2, (z / map.depth - .5) * 2) / Math.SQRT2;
|
|
350
|
+
const r = island > 0 ? d / island : 1;
|
|
351
|
+
return d + (r < 1 ? (1 - r * r * r * r) * height : 0) + (noise - .5) * roughness;
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
/** Whether a cell is on the map */
|
|
355
|
+
var on = (map, cx, cz) => cx >= 0 && cz >= 0 && cx < map.width && cz < map.depth;
|
|
356
|
+
/** The four cells next to one */
|
|
357
|
+
var NEIGHBOURS = [
|
|
358
|
+
[-1, 0],
|
|
359
|
+
[1, 0],
|
|
360
|
+
[0, -1],
|
|
361
|
+
[0, 1]
|
|
362
|
+
];
|
|
363
|
+
/** How steep a cell is, in radians, from the heights at its corners: as `Terrain.slopeAt` has it, read straight off the terrain */
|
|
364
|
+
function cellSlope(terrain, cx, cz) {
|
|
365
|
+
const { heights, vertsX } = terrain;
|
|
366
|
+
const v = cz * vertsX + cx;
|
|
367
|
+
const dx = (heights[v + 1] + heights[v + vertsX + 1] - heights[v] - heights[v + vertsX]) / 2;
|
|
368
|
+
const dz = (heights[v + vertsX] + heights[v + vertsX + 1] - heights[v] - heights[v + 1]) / 2;
|
|
369
|
+
return atan(hypot(dx, dz));
|
|
370
|
+
}
|
|
371
|
+
/** The engine's passes reach the mirror table of the context they are given; a context of a game's own has none, and mirrors by `symmetric` */
|
|
372
|
+
function internals(ctx) {
|
|
373
|
+
const own = ctx;
|
|
374
|
+
if (own.mirrorsOf && own.setCell) return own;
|
|
375
|
+
const { width } = ctx.map;
|
|
376
|
+
const mirrorsOf = (c) => {
|
|
377
|
+
const cx = c % width;
|
|
378
|
+
const cz = (c - cx) / width;
|
|
379
|
+
return ctx.symmetric(cx + .5, cz + .5).flatMap((place) => {
|
|
380
|
+
const mx = Math.floor(place.x);
|
|
381
|
+
const mz = Math.floor(place.z);
|
|
382
|
+
return on(ctx.map, mx, mz) ? [mz * width + mx] : [];
|
|
383
|
+
});
|
|
384
|
+
};
|
|
385
|
+
return {
|
|
386
|
+
mirrorsOf,
|
|
387
|
+
setCell: (array, c, value) => mirrorsOf(c).forEach((m) => array[m] = value)
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* The ground: a height field of noise, mirrored as the map is, quantised into cliff levels with the ground rolling
|
|
392
|
+
* within each, water in the low ground, and ramps cut between the levels so that every part can be walked to
|
|
393
|
+
*
|
|
394
|
+
* @beta
|
|
395
|
+
*/
|
|
396
|
+
function terrainPass(options = {}) {
|
|
397
|
+
return {
|
|
398
|
+
id: "terrain",
|
|
399
|
+
name: "The ground",
|
|
400
|
+
run(ctx) {
|
|
401
|
+
const { map } = ctx;
|
|
402
|
+
const { width, depth } = map;
|
|
403
|
+
const levels = Math.min(Math.max(Math.round(options.levels ?? ctx.param("levels", 2)), 1), 4);
|
|
404
|
+
const waterShare = Math.min(Math.max(options.water ?? ctx.param("water", .15), 0), .6);
|
|
405
|
+
const roughness = Math.min(Math.max(options.roughness ?? ctx.param("roughness", .4), 0), 1);
|
|
406
|
+
const hills = Math.max(4, options.hills ?? ctx.param("hills", 24));
|
|
407
|
+
const plateau = ctx.noise("plateau", [hills * 2, hills]);
|
|
408
|
+
const roll = ctx.noise("roll", [
|
|
409
|
+
hills / 2,
|
|
410
|
+
hills / 4,
|
|
411
|
+
hills / 8
|
|
412
|
+
]);
|
|
413
|
+
const values = new Float32Array(width * depth);
|
|
414
|
+
for (let c = 0; c < values.length; c++) {
|
|
415
|
+
const x = c % width + .5;
|
|
416
|
+
const z = Math.floor(c / width) + .5;
|
|
417
|
+
values[c] = options.shape ? options.shape(x, z, plateau(x, z), map) : plateau(x, z);
|
|
418
|
+
}
|
|
419
|
+
const stride = Math.max(1, Math.floor(values.length / 16384));
|
|
420
|
+
const sorted = Float32Array.from({ length: Math.floor(values.length / stride) }, (_, i) => values[i * stride]).sort();
|
|
421
|
+
const quantile = (q) => sorted[Math.min(Math.max(Math.round(q * (sorted.length - 1)), 0), sorted.length - 1)];
|
|
422
|
+
const waterAt = quantile(waterShare);
|
|
423
|
+
const steps = Array.from({ length: levels - 1 }, (_, i) => quantile(waterShare + (1 - waterShare) * (i + 1) / levels));
|
|
424
|
+
for (let c = 0; c < values.length; c++) {
|
|
425
|
+
let level = 0;
|
|
426
|
+
for (const step of steps) if (values[c] >= step) level++;
|
|
427
|
+
map.levels[c] = level;
|
|
428
|
+
map.water[c] = values[c] < waterAt ? 2 : 0;
|
|
429
|
+
}
|
|
430
|
+
const { setCell } = internals(ctx);
|
|
431
|
+
const counts = /* @__PURE__ */ new Int32Array(5);
|
|
432
|
+
for (let round = 0; round < 2; round++) {
|
|
433
|
+
const before = map.levels.slice();
|
|
434
|
+
for (let c = 0; c < before.length; c++) {
|
|
435
|
+
const cx = c % width;
|
|
436
|
+
const cz = (c - cx) / width;
|
|
437
|
+
if (!ctx.canonical(cx, cz)) continue;
|
|
438
|
+
counts.fill(0);
|
|
439
|
+
for (let dz = -1; dz <= 1; dz++) for (let dx = -1; dx <= 1; dx++) if (on(map, cx + dx, cz + dz)) counts[before[(cz + dz) * width + cx + dx]]++;
|
|
440
|
+
let best = before[c];
|
|
441
|
+
let most = counts[best];
|
|
442
|
+
for (let level = 0; level < counts.length; level++) if (counts[level] > most) [best, most] = [level, counts[level]];
|
|
443
|
+
if (best !== before[c]) setCell(map.levels, c, best);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
for (let c = 0; c < values.length; c++) if (map.levels[c] > 0) map.water[c] = 0;
|
|
447
|
+
const deep = map.water.slice();
|
|
448
|
+
for (let c = 0; c < deep.length; c++) {
|
|
449
|
+
if (deep[c] !== 2) continue;
|
|
450
|
+
const cx = c % width;
|
|
451
|
+
const cz = (c - cx) / width;
|
|
452
|
+
let rim = false;
|
|
453
|
+
for (const [dx, dz] of NEIGHBOURS) if (on(map, cx + dx, cz + dz) && deep[(cz + dz) * width + cx + dx] !== 2) rim = true;
|
|
454
|
+
if (rim) map.water[c] = 1;
|
|
455
|
+
}
|
|
456
|
+
const vx = width + 1;
|
|
457
|
+
for (let iz = 0; iz <= depth; iz++) for (let ix = 0; ix <= width; ix++) {
|
|
458
|
+
const v = iz * vx + ix;
|
|
459
|
+
map.ground[v] = 1 + (roll(ix, iz) - .5) * roughness * 1.5;
|
|
460
|
+
}
|
|
461
|
+
if (options.ramps !== false) cutRamps(ctx, Math.max(2, Math.round(options.rampWidth ?? 3)));
|
|
462
|
+
}
|
|
463
|
+
};
|
|
464
|
+
}
|
|
465
|
+
/**
|
|
466
|
+
* Ramps between the levels, so that every part of the ground joins the rest: the parts of a level (a flood fill on the
|
|
467
|
+
* level map, water left out) joined by a ramp each across the straightest stretch of cliff between two of them, the
|
|
468
|
+
* nearest the middle of both first, until all are one; mirrored as the map is
|
|
469
|
+
*/
|
|
470
|
+
function cutRamps(ctx, rampWidth) {
|
|
471
|
+
const { map } = ctx;
|
|
472
|
+
const { width, depth, levels, water, ramps } = map;
|
|
473
|
+
const { setCell } = internals(ctx);
|
|
474
|
+
const part = new Int32Array(width * depth).fill(-1);
|
|
475
|
+
const parts = [];
|
|
476
|
+
const queue = new Int32Array(width * depth);
|
|
477
|
+
for (let start = 0; start < part.length; start++) {
|
|
478
|
+
if (part[start] >= 0 || water[start] === 2) continue;
|
|
479
|
+
const id = parts.length;
|
|
480
|
+
const sum = {
|
|
481
|
+
cells: 0,
|
|
482
|
+
x: 0,
|
|
483
|
+
z: 0
|
|
484
|
+
};
|
|
485
|
+
parts.push(sum);
|
|
486
|
+
let head = 0;
|
|
487
|
+
let tail = 0;
|
|
488
|
+
queue[tail++] = start;
|
|
489
|
+
part[start] = id;
|
|
490
|
+
while (head < tail) {
|
|
491
|
+
const c = queue[head++];
|
|
492
|
+
const cx = c % width;
|
|
493
|
+
const cz = (c - cx) / width;
|
|
494
|
+
sum.cells++;
|
|
495
|
+
sum.x += cx + .5;
|
|
496
|
+
sum.z += cz + .5;
|
|
497
|
+
for (const [dx, dz] of NEIGHBOURS) {
|
|
498
|
+
const nx = cx + dx;
|
|
499
|
+
const nz = cz + dz;
|
|
500
|
+
if (!on(map, nx, nz)) continue;
|
|
501
|
+
const n = nz * width + nx;
|
|
502
|
+
if (part[n] >= 0 || water[n] === 2 || levels[n] !== levels[c]) continue;
|
|
503
|
+
part[n] = id;
|
|
504
|
+
queue[tail++] = n;
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
for (const each of parts) {
|
|
509
|
+
each.x /= each.cells;
|
|
510
|
+
each.z /= each.cells;
|
|
511
|
+
}
|
|
512
|
+
if (parts.length < 2) return;
|
|
513
|
+
const half = Math.floor(rampWidth / 2);
|
|
514
|
+
const candidates = [];
|
|
515
|
+
const straight = (cx, cz, dx, dz) => {
|
|
516
|
+
const low = cz * width + cx;
|
|
517
|
+
const high = (cz + dz) * width + cx + dx;
|
|
518
|
+
if (Math.abs(levels[low] - levels[high]) !== 1) return void 0;
|
|
519
|
+
const cells = [];
|
|
520
|
+
for (let along = -half; along < rampWidth - half; along++) for (let deep = -1; deep <= 2; deep++) {
|
|
521
|
+
const x = cx + dz * along + dx * deep;
|
|
522
|
+
const z = cz + dx * along + dz * deep;
|
|
523
|
+
if (!on(map, x, z)) return void 0;
|
|
524
|
+
const c = z * width + x;
|
|
525
|
+
if (water[c] !== 0) return void 0;
|
|
526
|
+
if (levels[c] !== (deep <= 0 ? levels[low] : levels[high])) return void 0;
|
|
527
|
+
if (deep >= 0 && deep <= 1) cells.push(c);
|
|
528
|
+
}
|
|
529
|
+
return cells;
|
|
530
|
+
};
|
|
531
|
+
for (let cz = 0; cz < depth; cz++) for (let cx = 0; cx < width; cx++) {
|
|
532
|
+
if (!ctx.canonical(cx, cz)) continue;
|
|
533
|
+
for (const [dx, dz] of [[1, 0], [0, 1]]) {
|
|
534
|
+
if (!on(map, cx + dx, cz + dz)) continue;
|
|
535
|
+
const cells = straight(cx, cz, dx, dz);
|
|
536
|
+
if (!cells) continue;
|
|
537
|
+
const a = part[cz * width + cx];
|
|
538
|
+
const b = part[(cz + dz) * width + cx + dx];
|
|
539
|
+
if (a < 0 || b < 0 || a === b) continue;
|
|
540
|
+
const mx = (parts[a].x + parts[b].x) / 2;
|
|
541
|
+
const mz = (parts[a].z + parts[b].z) / 2;
|
|
542
|
+
candidates.push({
|
|
543
|
+
a,
|
|
544
|
+
b,
|
|
545
|
+
cells,
|
|
546
|
+
cost: hypot(cx + .5 - mx, cz + .5 - mz)
|
|
547
|
+
});
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
candidates.sort((p, q) => p.cost - q.cost);
|
|
551
|
+
const root = parts.map((_, i) => i);
|
|
552
|
+
const find = (i) => root[i] === i ? i : root[i] = find(root[i]);
|
|
553
|
+
for (const candidate of candidates) {
|
|
554
|
+
const a = find(candidate.a);
|
|
555
|
+
const b = find(candidate.b);
|
|
556
|
+
if (a === b) continue;
|
|
557
|
+
root[a] = b;
|
|
558
|
+
for (const c of candidate.cells) setCell(ramps, c, 1);
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
/**
|
|
562
|
+
* The paint: each cell a tile by what the ground is there, through the game's tiles by name
|
|
563
|
+
*
|
|
564
|
+
* @beta
|
|
565
|
+
*/
|
|
566
|
+
function tilesPass(options = {}) {
|
|
567
|
+
return {
|
|
568
|
+
id: "tiles",
|
|
569
|
+
name: "The paint",
|
|
570
|
+
run(ctx) {
|
|
571
|
+
const { map, registry } = ctx;
|
|
572
|
+
const { width, depth } = map;
|
|
573
|
+
const tiles = registry.tileIds;
|
|
574
|
+
if (!tiles.length) return;
|
|
575
|
+
const terrain = mapTerrain(map);
|
|
576
|
+
const moisture = ctx.noise("moisture", [20, 10]);
|
|
577
|
+
let top = 0;
|
|
578
|
+
for (const level of map.levels) top = Math.max(top, level);
|
|
579
|
+
const by = options.by ?? ((cell, ids) => {
|
|
580
|
+
const has = (id) => ids.includes(id) ? id : void 0;
|
|
581
|
+
if (cell.shore) return has("sand");
|
|
582
|
+
if (cell.slope > .5) return has("rock");
|
|
583
|
+
if (cell.level === top && top >= 3) return has("snow") ?? has("rock");
|
|
584
|
+
if (cell.moisture < .35) return has("dirt");
|
|
585
|
+
});
|
|
586
|
+
for (let cz = 0; cz < depth; cz++) for (let cx = 0; cx < width; cx++) {
|
|
587
|
+
const c = cz * width + cx;
|
|
588
|
+
if (map.water[c] === 2) continue;
|
|
589
|
+
let shore = map.water[c] === 1;
|
|
590
|
+
if (!shore) {
|
|
591
|
+
for (const [dx, dz] of NEIGHBOURS) if (on(map, cx + dx, cz + dz) && map.water[(cz + dz) * width + cx + dx] !== 0) shore = true;
|
|
592
|
+
}
|
|
593
|
+
const id = by({
|
|
594
|
+
x: cx,
|
|
595
|
+
z: cz,
|
|
596
|
+
level: map.levels[c],
|
|
597
|
+
slope: cellSlope(terrain, cx, cz),
|
|
598
|
+
moisture: moisture(cx + .5, cz + .5),
|
|
599
|
+
shore
|
|
600
|
+
}, tiles);
|
|
601
|
+
map.tiles[c] = id ? registry.tile(id) : 0;
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
};
|
|
605
|
+
}
|
|
606
|
+
/**
|
|
607
|
+
* The starts: as far apart as the symmetry allows (mirrored from one, or around the middle), each on flat, dry ground
|
|
608
|
+
* (a clearing made for it), the player's `start` set, and what the game puts there
|
|
609
|
+
*
|
|
610
|
+
* @beta
|
|
611
|
+
*/
|
|
612
|
+
function startsPass(options = {}) {
|
|
613
|
+
return {
|
|
614
|
+
id: "starts",
|
|
615
|
+
name: "The starts",
|
|
616
|
+
run(ctx) {
|
|
617
|
+
const { map, rng } = ctx;
|
|
618
|
+
const { width, depth } = map;
|
|
619
|
+
const players = map.players.filter((player) => player.id !== 0 && player.id !== 90);
|
|
620
|
+
if (!players.length) return;
|
|
621
|
+
const clearing = Math.max(2, options.clearing ?? 6);
|
|
622
|
+
const spread = Math.min(Math.max(options.spread ?? .36, .1), .48);
|
|
623
|
+
const symmetry = ctx.options.symmetry ?? "none";
|
|
624
|
+
const setSize = ctx.symmetric(width * .3, depth * .2).length;
|
|
625
|
+
const seeds = Math.ceil(players.length / setSize);
|
|
626
|
+
const places = [];
|
|
627
|
+
const angle0 = symmetry === "none" ? rng.next() * Math.PI * 2 : symmetry === "x" ? Math.PI : symmetry === "z" ? Math.PI / 2 : Math.PI * 1.25;
|
|
628
|
+
for (let i = 0; i < seeds + players.length && places.length < players.length; i++) {
|
|
629
|
+
const angle = angle0 + i * Math.PI * 2 / Math.max(seeds * setSize, 1);
|
|
630
|
+
const x = width / 2 + cos(angle) * width * spread;
|
|
631
|
+
const z = depth / 2 + sin(angle) * depth * spread;
|
|
632
|
+
for (const place of ctx.symmetric(x, z)) if (places.length < players.length) places.push(place);
|
|
633
|
+
}
|
|
634
|
+
players.forEach((player, i) => {
|
|
635
|
+
const at = dryGround(ctx, places[i], clearing);
|
|
636
|
+
clear(ctx, at, clearing);
|
|
637
|
+
player.start = {
|
|
638
|
+
x: at.x,
|
|
639
|
+
z: at.z
|
|
640
|
+
};
|
|
641
|
+
ctx.mark("start", at.x, at.z, clearing);
|
|
642
|
+
options.from?.(player, at, ctx);
|
|
643
|
+
});
|
|
644
|
+
}
|
|
645
|
+
};
|
|
646
|
+
}
|
|
647
|
+
/**
|
|
648
|
+
* The nearest place to one that is not in the water, at a cell's middle: for a pass of a game's own that puts something
|
|
649
|
+
* down where the ground may be wet
|
|
650
|
+
*
|
|
651
|
+
* @beta
|
|
652
|
+
*/
|
|
653
|
+
var nearestDryGround = (ctx, at, reach) => dryGround(ctx, at, reach);
|
|
654
|
+
/**
|
|
655
|
+
* The ground around a place made flat and dry: one level (the one there, or `level`), no water, no ramps, the ground at
|
|
656
|
+
* one height eased into what is around; mirrored as the map is, unless `alone`. What a start's clearing and a mine's
|
|
657
|
+
* are made with, for a pass of a game's own
|
|
658
|
+
*
|
|
659
|
+
* @beta
|
|
660
|
+
*/
|
|
661
|
+
var clearGround = (ctx, at, radius, alone = false, level) => clear(ctx, at, radius, alone, level ?? ctx.levelAt(at.x, at.z));
|
|
662
|
+
/** The nearest place to one that is not in the water, at a cell's middle */
|
|
663
|
+
function dryGround(ctx, at, reach) {
|
|
664
|
+
const { map } = ctx;
|
|
665
|
+
const { width, depth } = map;
|
|
666
|
+
const cx = Math.min(Math.max(Math.floor(at.x), 1), width - 2);
|
|
667
|
+
const cz = Math.min(Math.max(Math.floor(at.z), 1), depth - 2);
|
|
668
|
+
for (let r = 0; r <= reach * 3; r++) for (let dz = -r; dz <= r; dz++) for (let dx = -r; dx <= r; dx++) {
|
|
669
|
+
if (Math.max(Math.abs(dx), Math.abs(dz)) !== r) continue;
|
|
670
|
+
const x = cx + dx;
|
|
671
|
+
const z = cz + dz;
|
|
672
|
+
if (x < 1 || z < 1 || x >= width - 1 || z >= depth - 1) continue;
|
|
673
|
+
if (map.water[z * width + x] === 0) return {
|
|
674
|
+
x: x + .5,
|
|
675
|
+
z: z + .5
|
|
676
|
+
};
|
|
677
|
+
}
|
|
678
|
+
return {
|
|
679
|
+
x: cx + .5,
|
|
680
|
+
z: cz + .5
|
|
681
|
+
};
|
|
682
|
+
}
|
|
683
|
+
/** The ground around a place made flat and dry: one level, no water, no ramps, the ground at one height. Mirrored, unless `alone` */
|
|
684
|
+
function clear(ctx, at, radius, alone = false, level = ctx.levelAt(at.x, at.z)) {
|
|
685
|
+
const { map } = ctx;
|
|
686
|
+
const { width, depth } = map;
|
|
687
|
+
const vx = width + 1;
|
|
688
|
+
let height = 0;
|
|
689
|
+
let count = 0;
|
|
690
|
+
for (let iz = Math.max(Math.floor(at.z - radius), 0); iz <= Math.min(Math.ceil(at.z + radius), depth); iz++) for (let ix = Math.max(Math.floor(at.x - radius), 0); ix <= Math.min(Math.ceil(at.x + radius), width); ix++) {
|
|
691
|
+
height += map.ground[iz * vx + ix];
|
|
692
|
+
count++;
|
|
693
|
+
}
|
|
694
|
+
height /= Math.max(count, 1);
|
|
695
|
+
for (const place of alone ? [at] : ctx.symmetric(at.x, at.z)) {
|
|
696
|
+
for (let cz = Math.max(Math.floor(place.z - radius), 0); cz < Math.min(Math.ceil(place.z + radius), depth); cz++) for (let cx = Math.max(Math.floor(place.x - radius), 0); cx < Math.min(Math.ceil(place.x + radius), width); cx++) {
|
|
697
|
+
if (hypot(cx + .5 - place.x, cz + .5 - place.z) > radius) continue;
|
|
698
|
+
const c = cz * width + cx;
|
|
699
|
+
map.levels[c] = level;
|
|
700
|
+
map.water[c] = 0;
|
|
701
|
+
map.ramps[c] = 0;
|
|
702
|
+
}
|
|
703
|
+
for (let iz = Math.max(Math.floor(place.z - radius), 0); iz <= Math.min(Math.ceil(place.z + radius), depth); iz++) for (let ix = Math.max(Math.floor(place.x - radius), 0); ix <= Math.min(Math.ceil(place.x + radius), width); ix++) {
|
|
704
|
+
const d = hypot(ix - place.x, iz - place.z);
|
|
705
|
+
if (d > radius) continue;
|
|
706
|
+
const t = Math.min(Math.max((d - radius * .6) / (radius * .4), 0), 1);
|
|
707
|
+
const v = iz * vx + ix;
|
|
708
|
+
map.ground[v] = height + (map.ground[v] - height) * t * t * (3 - 2 * t);
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
/**
|
|
713
|
+
* Things scattered over the map: as many as the density says, in patches of a noise, at least `spacing` apart, off
|
|
714
|
+
* the starts and what else they avoid, where they may go; each put down by `what`, mirrored as the map is. Trees now;
|
|
715
|
+
* rocks, houses, ruins and the rest the same way, with another `what`
|
|
716
|
+
*
|
|
717
|
+
* @beta
|
|
718
|
+
*/
|
|
719
|
+
function scatterPass(options) {
|
|
720
|
+
return {
|
|
721
|
+
id: `scatter:${options.kind}`,
|
|
722
|
+
name: `Scattered: ${options.kind}`,
|
|
723
|
+
run(ctx) {
|
|
724
|
+
const { map, rng } = ctx;
|
|
725
|
+
const { width, depth } = map;
|
|
726
|
+
const density = Math.min(Math.max(options.density ?? ctx.param(options.kind, .12), 0), 1);
|
|
727
|
+
if (density <= 0) return;
|
|
728
|
+
const spacing = Math.max(.5, options.spacing ?? 1.5);
|
|
729
|
+
const radius = options.radius ?? spacing / 2;
|
|
730
|
+
const avoid = options.avoid ?? 10;
|
|
731
|
+
const patches = Math.min(Math.max(options.patches ?? .6, 0), 1);
|
|
732
|
+
const noise = ctx.noise(`scatter:${options.kind}`, [
|
|
733
|
+
24,
|
|
734
|
+
12,
|
|
735
|
+
6
|
|
736
|
+
]);
|
|
737
|
+
let made;
|
|
738
|
+
const terrain = () => made ??= mapTerrain(map);
|
|
739
|
+
const cell = spacing;
|
|
740
|
+
const cols = Math.ceil(width / cell);
|
|
741
|
+
const rows = Math.ceil(depth / cell);
|
|
742
|
+
const grid = Array.from({ length: cols * rows }, () => []);
|
|
743
|
+
const tooClose = (x, z) => {
|
|
744
|
+
const gx = Math.floor(x / cell);
|
|
745
|
+
const gz = Math.floor(z / cell);
|
|
746
|
+
for (let dz = -1; dz <= 1; dz++) for (let dx = -1; dx <= 1; dx++) {
|
|
747
|
+
const gxx = gx + dx;
|
|
748
|
+
const gzz = gz + dz;
|
|
749
|
+
if (gxx < 0 || gzz < 0 || gxx >= cols || gzz >= rows) continue;
|
|
750
|
+
for (const other of grid[gzz * cols + gxx]) if (hypot(other.x - x, other.z - z) < spacing) return true;
|
|
751
|
+
}
|
|
752
|
+
return false;
|
|
753
|
+
};
|
|
754
|
+
const put = (x, z) => {
|
|
755
|
+
grid[Math.floor(z / cell) * cols + Math.floor(x / cell)].push({
|
|
756
|
+
x,
|
|
757
|
+
z
|
|
758
|
+
});
|
|
759
|
+
ctx.mark(options.kind, x, z, radius);
|
|
760
|
+
options.what(ctx, {
|
|
761
|
+
x,
|
|
762
|
+
z
|
|
763
|
+
});
|
|
764
|
+
};
|
|
765
|
+
for (let cz = 0; cz < depth; cz++) for (let cx = 0; cx < width; cx++) {
|
|
766
|
+
if (!ctx.canonical(cx, cz)) continue;
|
|
767
|
+
const c = cz * width + cx;
|
|
768
|
+
const x = cx + rng.next();
|
|
769
|
+
const z = cz + rng.next();
|
|
770
|
+
const n = noise(x, z);
|
|
771
|
+
const chance = density * (1 - patches + patches * Math.min(Math.max((n - .35) / .3, 0), 1) * 2);
|
|
772
|
+
if (rng.next() >= chance) continue;
|
|
773
|
+
if (map.water[c] !== 0) continue;
|
|
774
|
+
if (options.where) {
|
|
775
|
+
const shore = NEIGHBOURS.some(([dx, dz]) => on(map, cx + dx, cz + dz) && map.water[(cz + dz) * width + cx + dx] !== 0);
|
|
776
|
+
if (!options.where({
|
|
777
|
+
x,
|
|
778
|
+
z,
|
|
779
|
+
level: map.levels[c],
|
|
780
|
+
slope: cellSlope(terrain(), cx, cz),
|
|
781
|
+
noise: n,
|
|
782
|
+
shore
|
|
783
|
+
})) continue;
|
|
784
|
+
}
|
|
785
|
+
if (map.ramps[c]) continue;
|
|
786
|
+
if (!ctx.free(x, z, avoid, ["start"])) continue;
|
|
787
|
+
if (options.avoidKinds && Object.entries(options.avoidKinds).some(([kind, far]) => !ctx.free(x, z, far, [kind]))) continue;
|
|
788
|
+
const places = ctx.symmetric(x, z).filter((place) => place.x >= 0 && place.z >= 0 && place.x < width && place.z < depth);
|
|
789
|
+
if (places.some((place) => tooClose(place.x, place.z))) continue;
|
|
790
|
+
for (const place of places) put(place.x, place.z);
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
};
|
|
794
|
+
}
|
|
795
|
+
/**
|
|
796
|
+
* Resources: one near each start (towards the map's middle, as far as `main` says), and more spread over the map,
|
|
797
|
+
* mirrored as the map is, each put down by the game
|
|
798
|
+
*
|
|
799
|
+
* @beta
|
|
800
|
+
*/
|
|
801
|
+
function resourcesPass(options) {
|
|
802
|
+
return {
|
|
803
|
+
id: "resources",
|
|
804
|
+
name: "The resources",
|
|
805
|
+
run(ctx) {
|
|
806
|
+
const { map, rng } = ctx;
|
|
807
|
+
const { width, depth } = map;
|
|
808
|
+
const main = options.main ?? 8;
|
|
809
|
+
const spacing = options.spacing ?? 20;
|
|
810
|
+
const clearing = options.clearing ?? 3;
|
|
811
|
+
for (const player of map.players) {
|
|
812
|
+
if (!player.start || main === false) continue;
|
|
813
|
+
const toward = atan2(depth / 2 - player.start.z, width / 2 - player.start.x) + (rng.next() - .5) * .8;
|
|
814
|
+
const at = dryGround(ctx, {
|
|
815
|
+
x: player.start.x + cos(toward) * main,
|
|
816
|
+
z: player.start.z + sin(toward) * main
|
|
817
|
+
}, 4);
|
|
818
|
+
if (clearing > 0) clear(ctx, at, clearing, true, ctx.levelAt(player.start.x, player.start.z));
|
|
819
|
+
ctx.mark("resource", at.x, at.z, 3);
|
|
820
|
+
options.from(ctx, at, player);
|
|
821
|
+
}
|
|
822
|
+
const extra = Math.max(0, Math.round(options.extra ?? 2));
|
|
823
|
+
let placed = 0;
|
|
824
|
+
for (let attempt = 0; attempt < extra * 40 && placed < extra; attempt++) {
|
|
825
|
+
const x = 4 + rng.next() * (width - 8);
|
|
826
|
+
const z = 4 + rng.next() * (depth - 8);
|
|
827
|
+
if (!ctx.canonical(Math.floor(x), Math.floor(z))) continue;
|
|
828
|
+
const places = ctx.symmetric(x, z);
|
|
829
|
+
if (!places.every((place) => ctx.walkable(place.x, place.z) && ctx.free(place.x, place.z, spacing, ["start", "resource"]))) continue;
|
|
830
|
+
for (const place of places) {
|
|
831
|
+
const at = dryGround(ctx, place, 4);
|
|
832
|
+
if (clearing > 0) clear(ctx, at, clearing, true);
|
|
833
|
+
ctx.mark("resource", at.x, at.z, 3);
|
|
834
|
+
options.from(ctx, at);
|
|
835
|
+
}
|
|
836
|
+
placed++;
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
};
|
|
840
|
+
}
|
|
841
|
+
/**
|
|
842
|
+
* Roads between the starts (or places given), the way something on foot would go (over the level map, by ramps, around
|
|
843
|
+
* water; the gentlest ground preferred), painted with a tile
|
|
844
|
+
*
|
|
845
|
+
* @beta
|
|
846
|
+
*/
|
|
847
|
+
function roadsPass(options) {
|
|
848
|
+
return {
|
|
849
|
+
id: "roads",
|
|
850
|
+
name: "The roads",
|
|
851
|
+
run(ctx) {
|
|
852
|
+
const { map, registry } = ctx;
|
|
853
|
+
if (!registry.tileIds.includes(options.tile)) return;
|
|
854
|
+
const tile = registry.tile(options.tile);
|
|
855
|
+
const wide = Math.max(1, Math.round(options.width ?? 2));
|
|
856
|
+
const places = options.between ?? map.players.flatMap((player) => player.start ? [player.start] : []);
|
|
857
|
+
const terrain = mapTerrain(map);
|
|
858
|
+
for (let i = 0; i < places.length; i++) for (let j = i + 1; j < places.length; j++) {
|
|
859
|
+
const path = findPath(map, terrain, places[i], places[j]);
|
|
860
|
+
for (const c of path) {
|
|
861
|
+
const cx = c % map.width;
|
|
862
|
+
const cz = (c - cx) / map.width;
|
|
863
|
+
for (let dz = 0; dz < wide; dz++) for (let dx = 0; dx < wide; dx++) {
|
|
864
|
+
const x = cx + dx - Math.floor(wide / 2);
|
|
865
|
+
const z = cz + dz - Math.floor(wide / 2);
|
|
866
|
+
if (on(map, x, z) && map.water[z * map.width + x] === 0) map.tiles[z * map.width + x] = tile;
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
};
|
|
872
|
+
}
|
|
873
|
+
/** The cells of the way from one place to another over the level map: A* with the gentlest ground preferred; nothing where there is none */
|
|
874
|
+
function findPath(map, terrain, from, to) {
|
|
875
|
+
const { width, depth, levels, ramps, water } = map;
|
|
876
|
+
const start = Math.floor(from.z) * width + Math.floor(from.x);
|
|
877
|
+
const goal = Math.floor(to.z) * width + Math.floor(to.x);
|
|
878
|
+
const passable = (a, b) => levels[a] === levels[b] || ramps[a] > 0 || ramps[b] > 0;
|
|
879
|
+
const cost = new Float32Array(width * depth).fill(Infinity);
|
|
880
|
+
const came = new Int32Array(width * depth).fill(-1);
|
|
881
|
+
const closed = new Uint8Array(width * depth);
|
|
882
|
+
const heapCells = [];
|
|
883
|
+
const heapCosts = [];
|
|
884
|
+
const push = (estimate, c) => {
|
|
885
|
+
heapCells.push(c);
|
|
886
|
+
heapCosts.push(estimate);
|
|
887
|
+
let i = heapCells.length - 1;
|
|
888
|
+
while (i > 0) {
|
|
889
|
+
const parent = i - 1 >> 1;
|
|
890
|
+
if (heapCosts[parent] <= heapCosts[i]) break;
|
|
891
|
+
[heapCosts[parent], heapCosts[i]] = [heapCosts[i], heapCosts[parent]];
|
|
892
|
+
[heapCells[parent], heapCells[i]] = [heapCells[i], heapCells[parent]];
|
|
893
|
+
i = parent;
|
|
894
|
+
}
|
|
895
|
+
};
|
|
896
|
+
const pop = () => {
|
|
897
|
+
const top = heapCells[0];
|
|
898
|
+
const lastCell = heapCells.pop();
|
|
899
|
+
const lastCost = heapCosts.pop();
|
|
900
|
+
if (heapCells.length) {
|
|
901
|
+
heapCells[0] = lastCell;
|
|
902
|
+
heapCosts[0] = lastCost;
|
|
903
|
+
let i = 0;
|
|
904
|
+
for (;;) {
|
|
905
|
+
const l = i * 2 + 1;
|
|
906
|
+
const r = l + 1;
|
|
907
|
+
let best = i;
|
|
908
|
+
if (l < heapCells.length && heapCosts[l] < heapCosts[best]) best = l;
|
|
909
|
+
if (r < heapCells.length && heapCosts[r] < heapCosts[best]) best = r;
|
|
910
|
+
if (best === i) break;
|
|
911
|
+
[heapCosts[best], heapCosts[i]] = [heapCosts[i], heapCosts[best]];
|
|
912
|
+
[heapCells[best], heapCells[i]] = [heapCells[i], heapCells[best]];
|
|
913
|
+
i = best;
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
return top;
|
|
917
|
+
};
|
|
918
|
+
const h = (c) => hypot(c % width - goal % width, Math.floor(c / width) - Math.floor(goal / width));
|
|
919
|
+
cost[start] = 0;
|
|
920
|
+
push(h(start), start);
|
|
921
|
+
while (heapCells.length) {
|
|
922
|
+
const c = pop();
|
|
923
|
+
if (closed[c]) continue;
|
|
924
|
+
closed[c] = 1;
|
|
925
|
+
if (c === goal) break;
|
|
926
|
+
const cx = c % width;
|
|
927
|
+
const cz = (c - cx) / width;
|
|
928
|
+
for (const [dx, dz] of NEIGHBOURS) {
|
|
929
|
+
const nx = cx + dx;
|
|
930
|
+
const nz = cz + dz;
|
|
931
|
+
if (!on(map, nx, nz)) continue;
|
|
932
|
+
const n = nz * width + nx;
|
|
933
|
+
if (closed[n] || water[n] === 2 || !passable(c, n)) continue;
|
|
934
|
+
const step = 1 + terrain.slopeAt(nx + .5, nz + .5) * 4 + (water[n] ? 2 : 0);
|
|
935
|
+
const next = cost[c] + step;
|
|
936
|
+
if (next >= cost[n]) continue;
|
|
937
|
+
cost[n] = next;
|
|
938
|
+
came[n] = c;
|
|
939
|
+
push(next + h(n), n);
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
if (came[goal] < 0 && goal !== start) return [];
|
|
943
|
+
const path = [];
|
|
944
|
+
for (let c = goal; c >= 0; c = came[c]) {
|
|
945
|
+
path.push(c);
|
|
946
|
+
if (c === start) break;
|
|
947
|
+
}
|
|
948
|
+
return path.reverse();
|
|
949
|
+
}
|
|
950
|
+
/**
|
|
951
|
+
* A generator to take whole: hills and water, the paint, the starts, trees in patches and rocks about, with the
|
|
952
|
+
* parameters `levels`, `water`, `roughness`, `hills`, `trees` and `rocks`; what the trees and rocks are is the game's
|
|
953
|
+
* to say
|
|
954
|
+
*
|
|
955
|
+
* @beta
|
|
956
|
+
*/
|
|
957
|
+
function presetGenerator(options = {}) {
|
|
958
|
+
const { trees = [], rocks = [], treeScale = {} } = options;
|
|
959
|
+
const scale = treeScale.scale ?? 1;
|
|
960
|
+
const vary = treeScale.vary ?? .2;
|
|
961
|
+
return {
|
|
962
|
+
params: [
|
|
963
|
+
{
|
|
964
|
+
id: "levels",
|
|
965
|
+
name: "Cliff levels",
|
|
966
|
+
description: "How many levels the ground rises through",
|
|
967
|
+
default: 2,
|
|
968
|
+
min: 1,
|
|
969
|
+
max: 4,
|
|
970
|
+
step: 1
|
|
971
|
+
},
|
|
972
|
+
{
|
|
973
|
+
id: "water",
|
|
974
|
+
name: "Water",
|
|
975
|
+
description: "How much of the map is under water",
|
|
976
|
+
default: .15,
|
|
977
|
+
min: 0,
|
|
978
|
+
max: .5,
|
|
979
|
+
step: .05
|
|
980
|
+
},
|
|
981
|
+
{
|
|
982
|
+
id: "roughness",
|
|
983
|
+
name: "Roughness",
|
|
984
|
+
description: "How much the ground rolls",
|
|
985
|
+
default: .4,
|
|
986
|
+
min: 0,
|
|
987
|
+
max: 1,
|
|
988
|
+
step: .05
|
|
989
|
+
},
|
|
990
|
+
{
|
|
991
|
+
id: "hills",
|
|
992
|
+
name: "Hills",
|
|
993
|
+
description: "How many cells a hill is across",
|
|
994
|
+
default: 24,
|
|
995
|
+
min: 8,
|
|
996
|
+
max: 64,
|
|
997
|
+
step: 4
|
|
998
|
+
},
|
|
999
|
+
{
|
|
1000
|
+
id: "trees",
|
|
1001
|
+
name: "Trees",
|
|
1002
|
+
description: "How much of the map is woods",
|
|
1003
|
+
default: trees.length ? .12 : 0,
|
|
1004
|
+
min: 0,
|
|
1005
|
+
max: .5,
|
|
1006
|
+
step: .02
|
|
1007
|
+
},
|
|
1008
|
+
{
|
|
1009
|
+
id: "rocks",
|
|
1010
|
+
name: "Rocks",
|
|
1011
|
+
description: "How many rocks lie about",
|
|
1012
|
+
default: rocks.length ? .02 : 0,
|
|
1013
|
+
min: 0,
|
|
1014
|
+
max: .2,
|
|
1015
|
+
step: .01
|
|
1016
|
+
}
|
|
1017
|
+
],
|
|
1018
|
+
passes: [
|
|
1019
|
+
terrainPass(),
|
|
1020
|
+
tilesPass(),
|
|
1021
|
+
startsPass({ from: options.start }),
|
|
1022
|
+
...trees.length ? [scatterPass({
|
|
1023
|
+
kind: "trees",
|
|
1024
|
+
spacing: 1.6,
|
|
1025
|
+
what: (ctx, at) => {
|
|
1026
|
+
const size = scale * (1 + (ctx.rng.next() - .5) * 2 * vary);
|
|
1027
|
+
ctx.addDoodad({
|
|
1028
|
+
model: trees[ctx.rng.int(0, trees.length - 1)],
|
|
1029
|
+
x: at.x,
|
|
1030
|
+
z: at.z,
|
|
1031
|
+
yaw: ctx.rng.next() * Math.PI * 2,
|
|
1032
|
+
scale: size,
|
|
1033
|
+
blocks: "walk",
|
|
1034
|
+
radius: .5
|
|
1035
|
+
});
|
|
1036
|
+
}
|
|
1037
|
+
})] : [],
|
|
1038
|
+
...rocks.length ? [scatterPass({
|
|
1039
|
+
kind: "rocks",
|
|
1040
|
+
spacing: 3,
|
|
1041
|
+
patches: .3,
|
|
1042
|
+
avoidKinds: { trees: 1 },
|
|
1043
|
+
what: (ctx, at) => {
|
|
1044
|
+
const size = scale * (.8 + ctx.rng.next() * .6);
|
|
1045
|
+
ctx.addDoodad({
|
|
1046
|
+
model: rocks[ctx.rng.int(0, rocks.length - 1)],
|
|
1047
|
+
x: at.x,
|
|
1048
|
+
z: at.z,
|
|
1049
|
+
yaw: ctx.rng.next() * Math.PI * 2,
|
|
1050
|
+
scale: size,
|
|
1051
|
+
blocks: "walk",
|
|
1052
|
+
radius: .6
|
|
1053
|
+
});
|
|
1054
|
+
}
|
|
1055
|
+
})] : []
|
|
1056
|
+
]
|
|
1057
|
+
};
|
|
1058
|
+
}
|
|
1059
|
+
//#endregion
|
|
1060
|
+
export { basinShape, clearGround, generateMap, nearestDryGround, presetGenerator, resourcesPass, roadsPass, scatterPass, startsPass, symmetricPlaces, terrainPass, tilesPass };
|
|
1061
|
+
|
|
1062
|
+
//# sourceMappingURL=generate.js.map
|