@jgengine/core 0.10.0 → 0.12.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/CHANGELOG.md +39 -2
- package/LICENSE +203 -661
- package/README.md +1 -1
- package/dist/ai/crowd.d.ts +55 -0
- package/dist/ai/crowd.js +114 -0
- package/dist/ai/flock.d.ts +5 -2
- package/dist/ai/flock.js +5 -2
- package/dist/ai/groupAssist.d.ts +1 -0
- package/dist/ai/groupAssist.js +1 -0
- package/dist/ai/heatSystem.d.ts +76 -0
- package/dist/ai/heatSystem.js +97 -0
- package/dist/ai/interestScheduler.d.ts +107 -0
- package/dist/ai/interestScheduler.js +118 -0
- package/dist/ai/jobBoard.d.ts +1 -0
- package/dist/ai/jobBoard.js +1 -0
- package/dist/ai/laneSelect.d.ts +5 -2
- package/dist/ai/laneSelect.js +5 -2
- package/dist/ai/mobBrain.d.ts +1 -0
- package/dist/ai/mobBrain.js +1 -0
- package/dist/ai/populationDirector.d.ts +103 -0
- package/dist/ai/populationDirector.js +190 -0
- package/dist/ai/pursuit.d.ts +56 -0
- package/dist/ai/pursuit.js +53 -0
- package/dist/ai/spawnDirector.d.ts +7 -2
- package/dist/ai/spawnDirector.js +18 -15
- package/dist/ai/spawnPoint.d.ts +3 -1
- package/dist/ai/spawnPoint.js +3 -1
- package/dist/ai/targetAcquisition.d.ts +84 -0
- package/dist/ai/targetAcquisition.js +92 -0
- package/dist/anim/easing.d.ts +19 -0
- package/dist/anim/easing.js +19 -0
- package/dist/anim/oscillator.d.ts +12 -0
- package/dist/anim/oscillator.js +25 -0
- package/dist/area/areaEffectField.d.ts +127 -0
- package/dist/area/areaEffectField.js +175 -0
- package/dist/area/stackPolicy.d.ts +47 -0
- package/dist/area/stackPolicy.js +99 -0
- package/dist/authoring.d.ts +2 -1
- package/dist/authoring.js +2 -1
- package/dist/board/laneBoard.d.ts +13 -0
- package/dist/board/laneBoard.js +13 -0
- package/dist/board/timelineBoard.d.ts +10 -0
- package/dist/board/timelineBoard.js +10 -0
- package/dist/combat/abilityKit.d.ts +18 -0
- package/dist/combat/abilityKit.js +24 -9
- package/dist/combat/animationState.d.ts +5 -0
- package/dist/combat/animationState.js +5 -0
- package/dist/combat/breakMeters.d.ts +10 -0
- package/dist/combat/breakMeters.js +10 -0
- package/dist/combat/castRunner.d.ts +5 -0
- package/dist/combat/castRunner.js +5 -0
- package/dist/combat/comboPoints.d.ts +5 -0
- package/dist/combat/comboPoints.js +5 -0
- package/dist/combat/comboString.d.ts +5 -0
- package/dist/combat/comboString.js +5 -0
- package/dist/combat/damageInterceptors.d.ts +192 -0
- package/dist/combat/damageInterceptors.js +251 -0
- package/dist/combat/damageMatchup.d.ts +68 -0
- package/dist/combat/damageMatchup.js +42 -0
- package/dist/combat/damageResolution.d.ts +63 -0
- package/dist/combat/damageResolution.js +50 -0
- package/dist/combat/death.d.ts +7 -1
- package/dist/combat/death.js +5 -0
- package/dist/combat/deathReason.d.ts +14 -0
- package/dist/combat/deathReason.js +1 -0
- package/dist/combat/defensiveWindow.d.ts +5 -0
- package/dist/combat/defensiveWindow.js +5 -0
- package/dist/combat/dotField.d.ts +5 -1
- package/dist/combat/dotField.js +5 -1
- package/dist/combat/downed.d.ts +5 -0
- package/dist/combat/downed.js +5 -0
- package/dist/combat/effects.d.ts +5 -0
- package/dist/combat/effects.js +5 -0
- package/dist/combat/encounterSequence.d.ts +258 -0
- package/dist/combat/encounterSequence.js +426 -0
- package/dist/combat/hitReaction.d.ts +57 -1
- package/dist/combat/hitReaction.js +45 -5
- package/dist/combat/magazine.d.ts +54 -0
- package/dist/combat/magazine.js +96 -0
- package/dist/combat/projectiles.d.ts +5 -0
- package/dist/combat/projectiles.js +32 -14
- package/dist/combat/receivedDamage.d.ts +117 -0
- package/dist/combat/receivedDamage.js +92 -0
- package/dist/combat/regenShield.d.ts +5 -1
- package/dist/combat/regenShield.js +5 -1
- package/dist/combat/renderCues.d.ts +51 -0
- package/dist/combat/renderCues.js +44 -0
- package/dist/combat/resourcePool.d.ts +5 -0
- package/dist/combat/resourcePool.js +5 -0
- package/dist/combat/rewardAllocation.d.ts +121 -0
- package/dist/combat/rewardAllocation.js +251 -0
- package/dist/combat/shotOrigin.d.ts +18 -1
- package/dist/combat/shotOrigin.js +39 -0
- package/dist/combat/statusApplication.d.ts +96 -0
- package/dist/combat/statusApplication.js +81 -0
- package/dist/combat/telegraph.d.ts +11 -2
- package/dist/combat/telegraph.js +11 -2
- package/dist/combat/thresholdCrossings.d.ts +85 -0
- package/dist/combat/thresholdCrossings.js +116 -0
- package/dist/combat.d.ts +35 -0
- package/dist/combat.js +35 -0
- package/dist/commands/commandRegistry.d.ts +11 -0
- package/dist/commands/commandRegistry.js +9 -2
- package/dist/crafting/crop.d.ts +18 -0
- package/dist/crafting/crop.js +18 -0
- package/dist/crafting/production.d.ts +5 -0
- package/dist/crafting/production.js +5 -0
- package/dist/devtools/controls.d.ts +38 -0
- package/dist/devtools/controls.js +181 -0
- package/dist/devtools/devtools.d.ts +5 -197
- package/dist/devtools/devtools.js +38 -774
- package/dist/devtools/discover.d.ts +32 -0
- package/dist/devtools/discover.js +240 -0
- package/dist/devtools/fallbackSeams.d.ts +50 -0
- package/dist/devtools/fallbackSeams.js +111 -0
- package/dist/devtools/frame.d.ts +15 -0
- package/dist/devtools/frame.js +247 -0
- package/dist/devtools/logs.d.ts +15 -0
- package/dist/devtools/logs.js +86 -0
- package/dist/devtools/overrides.d.ts +16 -0
- package/dist/devtools/overrides.js +66 -0
- package/dist/devtools/rewriteTunables.d.ts +17 -0
- package/dist/devtools/rewriteTunables.js +276 -0
- package/dist/devtools/saveEndpoint.d.ts +46 -0
- package/dist/devtools/saveEndpoint.js +48 -0
- package/dist/devtools/transformTunables.d.ts +3 -0
- package/dist/devtools/transformTunables.js +3 -0
- package/dist/devtools/tunableSchema.d.ts +31 -0
- package/dist/devtools/tunableSchema.js +31 -0
- package/dist/devtools/types.d.ts +212 -0
- package/dist/devtools/types.js +1 -0
- package/dist/economy/auctionBook.d.ts +122 -0
- package/dist/economy/auctionBook.js +213 -0
- package/dist/economy/currency.d.ts +12 -1
- package/dist/economy/currency.js +12 -1
- package/dist/economy/listingBook.d.ts +91 -0
- package/dist/economy/listingBook.js +144 -0
- package/dist/economy/priceHistory.d.ts +44 -0
- package/dist/economy/priceHistory.js +89 -0
- package/dist/economy/resourceLedger.d.ts +222 -0
- package/dist/economy/resourceLedger.js +353 -0
- package/dist/economy/sharedWallet.d.ts +14 -0
- package/dist/economy/sharedWallet.js +14 -0
- package/dist/economy/techTree.d.ts +12 -0
- package/dist/economy/techTree.js +12 -0
- package/dist/economy/unlockPoints.d.ts +92 -0
- package/dist/economy/unlockPoints.js +103 -0
- package/dist/economy/wallet.d.ts +26 -2
- package/dist/economy/wallet.js +35 -6
- package/dist/editor/commandApply.d.ts +5 -0
- package/dist/editor/commandApply.js +755 -0
- package/dist/editor/commands.d.ts +235 -7
- package/dist/editor/commands.js +82 -124
- package/dist/editor/directives.d.ts +94 -0
- package/dist/editor/directives.js +206 -0
- package/dist/editor/document.d.ts +194 -13
- package/dist/editor/document.js +1166 -19
- package/dist/editor/entityCatalog.d.ts +42 -0
- package/dist/editor/entityCatalog.js +101 -0
- package/dist/editor/environment.d.ts +74 -0
- package/dist/editor/environment.js +169 -0
- package/dist/editor/grid.d.ts +229 -0
- package/dist/editor/grid.js +366 -0
- package/dist/editor/gridAdapters.d.ts +80 -0
- package/dist/editor/gridAdapters.js +134 -0
- package/dist/editor/index.d.ts +98 -6
- package/dist/editor/index.js +13 -2
- package/dist/editor/liveSync.d.ts +127 -0
- package/dist/editor/liveSync.js +249 -0
- package/dist/editor/minimap.d.ts +31 -0
- package/dist/editor/minimap.js +73 -0
- package/dist/editor/runtimeInspector.d.ts +88 -0
- package/dist/editor/runtimeInspector.js +239 -0
- package/dist/editor/streamer.d.ts +66 -0
- package/dist/editor/streamer.js +68 -0
- package/dist/editor/types.d.ts +250 -1
- package/dist/editor/world.d.ts +136 -0
- package/dist/editor/world.js +303 -0
- package/dist/faction/reputation.d.ts +5 -0
- package/dist/faction/reputation.js +5 -0
- package/dist/format/distance.d.ts +17 -0
- package/dist/format/distance.js +18 -0
- package/dist/format/duration.d.ts +27 -0
- package/dist/format/duration.js +45 -0
- package/dist/format/speed.d.ts +17 -0
- package/dist/format/speed.js +25 -0
- package/dist/game/breeding.d.ts +161 -0
- package/dist/game/breeding.js +181 -0
- package/dist/game/cameraConfig.d.ts +451 -0
- package/dist/game/cameraConfig.js +1 -0
- package/dist/game/connectedPlayers.d.ts +6 -4
- package/dist/game/connectedPlayers.js +2 -2
- package/dist/game/cosmetics.d.ts +9 -0
- package/dist/game/cosmetics.js +16 -0
- package/dist/game/defineGame.d.ts +110 -5
- package/dist/game/defineGame.js +49 -4
- package/dist/game/defineSystem.d.ts +90 -0
- package/dist/game/defineSystem.js +47 -0
- package/dist/game/dialogue.d.ts +33 -0
- package/dist/game/dialogue.js +21 -0
- package/dist/game/events.d.ts +63 -13
- package/dist/game/events.js +5 -0
- package/dist/game/feed.d.ts +33 -0
- package/dist/game/feed.js +35 -2
- package/dist/game/gamePhase.d.ts +11 -0
- package/dist/game/gamePhase.js +16 -0
- package/dist/game/leaderboard.d.ts +5 -0
- package/dist/game/leaderboard.js +5 -0
- package/dist/game/loadout.d.ts +5 -0
- package/dist/game/loadout.js +5 -0
- package/dist/game/lootFilter.d.ts +2 -0
- package/dist/game/lootFilter.js +2 -0
- package/dist/game/lootPipeline.d.ts +164 -0
- package/dist/game/lootPipeline.js +216 -0
- package/dist/game/lootTable.d.ts +19 -2
- package/dist/game/lootTable.js +15 -5
- package/dist/game/objectives.d.ts +43 -0
- package/dist/game/objectives.js +36 -0
- package/dist/game/paramLayers.d.ts +148 -0
- package/dist/game/paramLayers.js +185 -0
- package/dist/game/ping.d.ts +5 -0
- package/dist/game/ping.js +5 -0
- package/dist/game/playableGame.d.ts +116 -432
- package/dist/game/playableGame.js +1 -1
- package/dist/game/progression.d.ts +35 -0
- package/dist/game/progression.js +19 -0
- package/dist/game/quest.d.ts +8 -0
- package/dist/game/quest.js +30 -3
- package/dist/game/race.d.ts +141 -0
- package/dist/game/race.js +169 -0
- package/dist/game/recordBook.d.ts +3 -1
- package/dist/game/recordBook.js +4 -1
- package/dist/game/ruleSelection.d.ts +75 -0
- package/dist/game/ruleSelection.js +127 -0
- package/dist/game/runDraft.d.ts +5 -0
- package/dist/game/runDraft.js +5 -0
- package/dist/game/saveStore.d.ts +111 -0
- package/dist/game/saveStore.js +312 -0
- package/dist/game/snapshotHistory.d.ts +67 -0
- package/dist/game/snapshotHistory.js +95 -0
- package/dist/game/social.d.ts +38 -1
- package/dist/game/social.js +71 -0
- package/dist/game/spawnPoints.d.ts +5 -0
- package/dist/game/spawnPoints.js +5 -0
- package/dist/game/systemRuntime.d.ts +50 -0
- package/dist/game/systemRuntime.js +157 -0
- package/dist/game/systemSchedule.d.ts +72 -0
- package/dist/game/systemSchedule.js +242 -0
- package/dist/game/toasts.d.ts +43 -0
- package/dist/game/toasts.js +44 -0
- package/dist/game/trade.d.ts +10 -0
- package/dist/game/trade.js +10 -0
- package/dist/game/tribe.d.ts +184 -0
- package/dist/game/tribe.js +432 -0
- package/dist/game/unlocks.d.ts +8 -0
- package/dist/game/unlocks.js +16 -0
- package/dist/game/vfxInstance.d.ts +138 -0
- package/dist/game/vfxInstance.js +96 -0
- package/dist/game/worldItem.d.ts +17 -4
- package/dist/game/worldItem.js +17 -4
- package/dist/gameplay.d.ts +93 -0
- package/dist/gameplay.js +93 -0
- package/dist/index.d.ts +5 -14
- package/dist/index.js +5 -14
- package/dist/input/actionBindings.d.ts +23 -6
- package/dist/input/actionBindings.js +23 -6
- package/dist/input/axisInput.d.ts +7 -2
- package/dist/input/axisInput.js +7 -2
- package/dist/input/controlGroups.d.ts +67 -0
- package/dist/input/controlGroups.js +41 -0
- package/dist/input/touchScheme.d.ts +82 -6
- package/dist/input/touchScheme.js +123 -10
- package/dist/interaction/lockpick.d.ts +61 -0
- package/dist/interaction/lockpick.js +168 -0
- package/dist/interaction/proximityPrompt.d.ts +2 -0
- package/dist/interaction/proximityPrompt.js +2 -0
- package/dist/interaction/qte.d.ts +5 -0
- package/dist/interaction/qte.js +5 -0
- package/dist/interaction/skillCheck.d.ts +5 -0
- package/dist/interaction/skillCheck.js +5 -0
- package/dist/inventory/encumbrance.d.ts +69 -0
- package/dist/inventory/encumbrance.js +68 -0
- package/dist/inventory/inventoryModel.d.ts +12 -0
- package/dist/inventory/inventoryModel.js +12 -0
- package/dist/inventory/shapedGrid.d.ts +16 -0
- package/dist/inventory/shapedGrid.js +16 -0
- package/dist/inventory/slotModel.d.ts +10 -0
- package/dist/inventory/slotModel.js +10 -0
- package/dist/item/durability.d.ts +5 -0
- package/dist/item/durability.js +6 -3
- package/dist/item/itemIdentity.d.ts +171 -0
- package/dist/item/itemIdentity.js +138 -0
- package/dist/item/itemInstanceRegistry.d.ts +32 -0
- package/dist/item/itemInstanceRegistry.js +34 -0
- package/dist/item/itemgen.d.ts +163 -0
- package/dist/item/itemgen.js +151 -0
- package/dist/item/modularItem.d.ts +5 -0
- package/dist/item/modularItem.js +5 -0
- package/dist/item/use.d.ts +5 -0
- package/dist/item/use.js +5 -0
- package/dist/item/useBehavior.d.ts +142 -0
- package/dist/item/useBehavior.js +105 -0
- package/dist/item/weapon.d.ts +5 -0
- package/dist/item/weapon.js +5 -0
- package/dist/math/scalar.d.ts +25 -0
- package/dist/math/scalar.js +47 -0
- package/dist/meta/changelog.d.ts +4 -1
- package/dist/meta/changelog.js +39 -2
- package/dist/movement/avoidance.d.ts +45 -0
- package/dist/movement/avoidance.js +123 -0
- package/dist/movement/cameraRig.d.ts +8 -0
- package/dist/movement/cameraRig.js +8 -0
- package/dist/movement/dash.d.ts +11 -0
- package/dist/movement/dash.js +11 -0
- package/dist/movement/formation.d.ts +135 -0
- package/dist/movement/formation.js +194 -0
- package/dist/movement/glideModel.d.ts +5 -0
- package/dist/movement/glideModel.js +5 -0
- package/dist/movement/grappleSwing.d.ts +5 -0
- package/dist/movement/grappleSwing.js +5 -0
- package/dist/movement/leaderTrail.d.ts +5 -0
- package/dist/movement/leaderTrail.js +5 -0
- package/dist/movement/movementModel.d.ts +50 -9
- package/dist/movement/movementModel.js +75 -29
- package/dist/movement/playerMovement.js +167 -12
- package/dist/movement/poseState.d.ts +13 -0
- package/dist/movement/poseState.js +16 -0
- package/dist/movement/steering.d.ts +8 -0
- package/dist/movement/steering.js +18 -0
- package/dist/multiplayer/combatSnapshot.d.ts +3 -0
- package/dist/multiplayer/combatSnapshot.js +16 -8
- package/dist/multiplayer/lagCompensation.d.ts +5 -0
- package/dist/multiplayer/lagCompensation.js +5 -0
- package/dist/multiplayer/presenceModel.d.ts +11 -1
- package/dist/multiplayer/presenceModel.js +17 -1
- package/dist/multiplayer/simultaneousCommit.d.ts +3 -0
- package/dist/multiplayer/simultaneousCommit.js +3 -0
- package/dist/multiplayer.d.ts +11 -0
- package/dist/multiplayer.js +11 -0
- package/dist/nav/pathFollow.d.ts +57 -0
- package/dist/nav/pathFollow.js +109 -0
- package/dist/orders/orderKinds.d.ts +156 -0
- package/dist/orders/orderKinds.js +197 -0
- package/dist/orders/orderQueue.d.ts +208 -0
- package/dist/orders/orderQueue.js +211 -0
- package/dist/physics/drivableVehicle.d.ts +31 -0
- package/dist/physics/drivableVehicle.js +16 -0
- package/dist/physics/flightDynamics.d.ts +82 -0
- package/dist/physics/flightDynamics.js +165 -0
- package/dist/physics/gravityField.d.ts +25 -0
- package/dist/physics/gravityField.js +41 -0
- package/dist/physics/kinematicVehicle.d.ts +108 -1
- package/dist/physics/kinematicVehicle.js +212 -15
- package/dist/physics/physicsWorld.d.ts +50 -12
- package/dist/physics/physicsWorld.js +120 -122
- package/dist/physics/radialImpulse.d.ts +25 -0
- package/dist/physics/radialImpulse.js +27 -0
- package/dist/physics/vehicleObstacles.d.ts +44 -0
- package/dist/physics/vehicleObstacles.js +115 -0
- package/dist/procedural.d.ts +3 -0
- package/dist/procedural.js +3 -0
- package/dist/progression/statGraph.d.ts +116 -0
- package/dist/progression/statGraph.js +318 -0
- package/dist/puzzle/cellGrid.d.ts +9 -0
- package/dist/puzzle/cellGrid.js +9 -0
- package/dist/puzzle/fallingPiece.d.ts +9 -0
- package/dist/puzzle/fallingPiece.js +9 -0
- package/dist/puzzle/nonogram.d.ts +39 -0
- package/dist/puzzle/nonogram.js +136 -0
- package/dist/random/nameGen.d.ts +5 -0
- package/dist/random/nameGen.js +5 -0
- package/dist/random/pick.d.ts +8 -0
- package/dist/random/pick.js +31 -0
- package/dist/random/rng.d.ts +26 -1
- package/dist/random/rng.js +32 -9
- package/dist/random/seedLink.d.ts +4 -0
- package/dist/random/seedLink.js +4 -0
- package/dist/relation/keyedValues.d.ts +54 -0
- package/dist/relation/keyedValues.js +115 -0
- package/dist/relation/thresholds.d.ts +62 -0
- package/dist/relation/thresholds.js +62 -0
- package/dist/render/color.d.ts +12 -0
- package/dist/render/color.js +26 -0
- package/dist/render/lookPreset.d.ts +41 -0
- package/dist/render/lookPreset.js +29 -0
- package/dist/render/postProcessing.d.ts +20 -0
- package/dist/render/postProcessing.js +21 -1
- package/dist/rules/predicate.d.ts +53 -0
- package/dist/rules/predicate.js +64 -0
- package/dist/rules/ruleEffects.d.ts +38 -0
- package/dist/rules/ruleEffects.js +37 -0
- package/dist/rules/triggeredRules.d.ts +160 -0
- package/dist/rules/triggeredRules.js +241 -0
- package/dist/runtime/adapter.d.ts +55 -3
- package/dist/runtime/adapter.js +57 -1
- package/dist/runtime/cameraDirector.d.ts +1 -0
- package/dist/runtime/cameraDirector.js +1 -0
- package/dist/runtime/commandRunner.d.ts +1 -0
- package/dist/runtime/commandRunner.js +1 -0
- package/dist/runtime/context/combat.d.ts +51 -0
- package/dist/runtime/context/combat.js +130 -0
- package/dist/runtime/context/combatFx.d.ts +23 -0
- package/dist/runtime/context/combatFx.js +161 -0
- package/dist/runtime/context/deathLoot.d.ts +30 -0
- package/dist/runtime/context/deathLoot.js +39 -0
- package/dist/runtime/context/player.d.ts +48 -0
- package/dist/runtime/context/player.js +125 -0
- package/dist/runtime/context/registries.d.ts +13 -0
- package/dist/runtime/context/registries.js +84 -0
- package/dist/runtime/context/scene.d.ts +59 -0
- package/dist/runtime/context/scene.js +291 -0
- package/dist/runtime/context/snapshotCodecs.d.ts +12 -0
- package/dist/runtime/context/snapshotCodecs.js +26 -0
- package/dist/runtime/context/worldItems.d.ts +21 -0
- package/dist/runtime/context/worldItems.js +37 -0
- package/dist/runtime/descriptors/baseline.d.ts +48 -0
- package/dist/runtime/descriptors/baseline.js +157 -0
- package/dist/runtime/descriptors/features.d.ts +79 -0
- package/dist/runtime/descriptors/features.js +299 -0
- package/dist/runtime/gameContext.d.ts +2 -327
- package/dist/runtime/gameContext.js +273 -778
- package/dist/runtime/gameContextTypes.d.ts +467 -0
- package/dist/runtime/gameContextTypes.js +1 -0
- package/dist/runtime/gameRuntime.d.ts +1 -0
- package/dist/runtime/gameRuntime.js +1 -0
- package/dist/runtime/headlessRunner.d.ts +62 -0
- package/dist/runtime/headlessRunner.js +45 -0
- package/dist/runtime/hostPersistence.d.ts +12 -0
- package/dist/runtime/hostPersistence.js +12 -0
- package/dist/runtime/hostPolicy.d.ts +51 -0
- package/dist/runtime/hostPolicy.js +68 -0
- package/dist/runtime/hostedGameRunner.d.ts +11 -4
- package/dist/runtime/hostedGameRunner.js +27 -3
- package/dist/runtime/hostedWorldSession.d.ts +15 -5
- package/dist/runtime/hostedWorldSession.js +12 -4
- package/dist/runtime/inputSnapshot.d.ts +8 -3
- package/dist/runtime/inputSnapshot.js +6 -2
- package/dist/runtime/motionIntents.d.ts +11 -2
- package/dist/runtime/motionIntents.js +16 -2
- package/dist/runtime/perContext.d.ts +15 -0
- package/dist/runtime/perContext.js +21 -0
- package/dist/runtime/runtimeSave.d.ts +79 -0
- package/dist/runtime/runtimeSave.js +105 -0
- package/dist/runtime/save.d.ts +4 -0
- package/dist/runtime/save.js +4 -0
- package/dist/runtime/snapshot.d.ts +7 -0
- package/dist/runtime/snapshot.js +7 -0
- package/dist/runtime/visibility.d.ts +2 -1
- package/dist/runtime/visibility.js +2 -1
- package/dist/runtime/worldChannel.d.ts +7 -3
- package/dist/runtime/worldChannel.js +51 -6
- package/dist/runtime/worldMirror.d.ts +14 -2
- package/dist/runtime/worldMirror.js +15 -2
- package/dist/runtime/worldProjection.d.ts +47 -0
- package/dist/runtime/worldProjection.js +52 -0
- package/dist/runtime/worldReplication.d.ts +30 -7
- package/dist/runtime/worldReplication.js +41 -9
- package/dist/runtime/worldSnapshot.d.ts +42 -3
- package/dist/runtime/worldSnapshot.js +34 -7
- package/dist/scene/assetCatalog.d.ts +26 -0
- package/dist/scene/assetCatalog.js +4 -0
- package/dist/scene/assetDiagnostics.d.ts +69 -0
- package/dist/scene/assetDiagnostics.js +110 -0
- package/dist/scene/assetGenerator.d.ts +65 -0
- package/dist/scene/assetGenerator.js +64 -0
- package/dist/scene/assetSpace.d.ts +137 -0
- package/dist/scene/assetSpace.js +257 -0
- package/dist/scene/authoredTriggers.d.ts +219 -0
- package/dist/scene/authoredTriggers.js +454 -0
- package/dist/scene/behaviorRuntime.d.ts +75 -0
- package/dist/scene/behaviorRuntime.js +217 -0
- package/dist/scene/behaviors.d.ts +14 -2
- package/dist/scene/behaviors.js +7 -2
- package/dist/scene/bodyBind.d.ts +60 -0
- package/dist/scene/bodyBind.js +51 -0
- package/dist/scene/builtinSceneKinds.d.ts +5 -0
- package/dist/scene/builtinSceneKinds.js +67 -0
- package/dist/scene/colliders.d.ts +71 -1
- package/dist/scene/colliders.js +145 -1
- package/dist/scene/collisionMesh.d.ts +94 -0
- package/dist/scene/collisionMesh.js +699 -0
- package/dist/scene/companion.d.ts +147 -0
- package/dist/scene/companion.js +193 -0
- package/dist/scene/entityStats.d.ts +18 -11
- package/dist/scene/entityStats.js +21 -16
- package/dist/scene/entityStore.d.ts +12 -1
- package/dist/scene/entityStore.js +15 -0
- package/dist/scene/facing.d.ts +18 -0
- package/dist/scene/facing.js +26 -0
- package/dist/scene/modelSockets.d.ts +33 -0
- package/dist/scene/modelSockets.js +29 -0
- package/dist/scene/objectQuery.d.ts +2 -0
- package/dist/scene/objectQuery.js +2 -0
- package/dist/scene/objectStore.d.ts +4 -0
- package/dist/scene/objectStore.js +6 -0
- package/dist/scene/possession.d.ts +8 -0
- package/dist/scene/possession.js +14 -0
- package/dist/scene/roster.d.ts +3 -0
- package/dist/scene/roster.js +12 -0
- package/dist/scene/sceneKinds.d.ts +256 -0
- package/dist/scene/sceneKinds.js +218 -0
- package/dist/scene/sceneOwnership.d.ts +169 -0
- package/dist/scene/sceneOwnership.js +179 -0
- package/dist/scene/sceneRaycast.js +15 -0
- package/dist/scene/selectionBookmarks.d.ts +93 -0
- package/dist/scene/selectionBookmarks.js +122 -0
- package/dist/scene/vehicleSeat.d.ts +68 -0
- package/dist/scene/vehicleSeat.js +59 -0
- package/dist/sensor/concealment.d.ts +3 -0
- package/dist/sensor/concealment.js +3 -0
- package/dist/sensor/freezeMonitor.d.ts +1 -0
- package/dist/sensor/freezeMonitor.js +1 -0
- package/dist/sensor/frustumSensor.d.ts +7 -3
- package/dist/sensor/frustumSensor.js +7 -3
- package/dist/sensor/hiddenStateProbe.d.ts +5 -2
- package/dist/sensor/hiddenStateProbe.js +5 -2
- package/dist/sensor/recordingBuffer.d.ts +2 -1
- package/dist/sensor/recordingBuffer.js +2 -1
- package/dist/sensor/replayLoop.d.ts +6 -2
- package/dist/sensor/replayLoop.js +6 -2
- package/dist/sensor/revealQuery.d.ts +2 -1
- package/dist/sensor/revealQuery.js +2 -1
- package/dist/sensor/visionCone.d.ts +10 -3
- package/dist/sensor/visionCone.js +10 -3
- package/dist/session/contestedChannel.d.ts +1 -0
- package/dist/session/contestedChannel.js +1 -0
- package/dist/session/extraction.d.ts +1 -0
- package/dist/session/extraction.js +1 -0
- package/dist/session/roles.d.ts +6 -0
- package/dist/session/roles.js +6 -0
- package/dist/session/roundState.d.ts +8 -0
- package/dist/session/roundState.js +2 -0
- package/dist/settings/settingsModel.d.ts +1 -0
- package/dist/settings/settingsModel.js +1 -0
- package/dist/stats/accumulatorMeter.d.ts +6 -0
- package/dist/stats/accumulatorMeter.js +6 -0
- package/dist/stats/eventMeter.d.ts +5 -0
- package/dist/stats/eventMeter.js +5 -0
- package/dist/stats/rollCheck.d.ts +5 -0
- package/dist/stats/rollCheck.js +5 -0
- package/dist/stats/spawnLevelStats.d.ts +110 -0
- package/dist/stats/spawnLevelStats.js +140 -0
- package/dist/stats/statModifiers.d.ts +5 -0
- package/dist/stats/statModifiers.js +5 -0
- package/dist/stats/statPool.d.ts +70 -0
- package/dist/stats/statPool.js +59 -0
- package/dist/store/changeSignal.d.ts +3 -0
- package/dist/store/changeSignal.js +2 -0
- package/dist/store/defineKeyedStore.d.ts +38 -0
- package/dist/store/defineKeyedStore.js +42 -0
- package/dist/store/defineStore.d.ts +33 -0
- package/dist/store/defineStore.js +35 -0
- package/dist/store/observableKeyedStore.d.ts +7 -0
- package/dist/store/observableKeyedStore.js +35 -2
- package/dist/survival/decayMeter.d.ts +55 -0
- package/dist/survival/decayMeter.js +130 -57
- package/dist/survival/moodle.d.ts +2 -0
- package/dist/survival/regionHealth.d.ts +6 -0
- package/dist/survival/regionHealth.js +6 -3
- package/dist/tactics/fallingGrid.d.ts +4 -2
- package/dist/tactics/fallingGrid.js +4 -2
- package/dist/tactics/predictiveQuery.d.ts +3 -0
- package/dist/tactics/predictiveQuery.js +3 -0
- package/dist/tactics/snapshot.d.ts +2 -0
- package/dist/tactics/snapshot.js +2 -0
- package/dist/tactics/surface.d.ts +1 -0
- package/dist/tactics/surface.js +1 -0
- package/dist/tactics/tacticalGrid.d.ts +1 -0
- package/dist/tactics/tacticalGrid.js +1 -0
- package/dist/time/beatClock.d.ts +14 -4
- package/dist/time/beatClock.js +14 -4
- package/dist/time/calendarClock.d.ts +3 -0
- package/dist/time/calendarClock.js +3 -0
- package/dist/time/idleProgress.d.ts +4 -0
- package/dist/time/idleProgress.js +4 -0
- package/dist/time/simClock.d.ts +2 -0
- package/dist/time/simClock.js +20 -5
- package/dist/ui/actionModel.d.ts +110 -0
- package/dist/ui/actionModel.js +159 -0
- package/dist/ui/gameLayout.d.ts +30 -11
- package/dist/ui/gameLayout.js +30 -11
- package/dist/ui/hudDocument.d.ts +114 -0
- package/dist/ui/hudDocument.js +220 -0
- package/dist/ui/hudLayout.d.ts +38 -1
- package/dist/ui/hudLayout.js +220 -17
- package/dist/ui/selectionModel.d.ts +92 -0
- package/dist/ui/selectionModel.js +88 -0
- package/dist/ui/tooltipModel.d.ts +63 -0
- package/dist/ui/tooltipModel.js +82 -0
- package/dist/ui.d.ts +15 -0
- package/dist/ui.js +15 -0
- package/dist/visibility/bounds.d.ts +8 -1
- package/dist/visibility/bounds.js +8 -1
- package/dist/visibility/frustum.d.ts +12 -3
- package/dist/visibility/frustum.js +12 -3
- package/dist/work/jobQueue.d.ts +201 -0
- package/dist/work/jobQueue.js +253 -0
- package/dist/work/unitTraining.d.ts +58 -0
- package/dist/work/unitTraining.js +52 -0
- package/dist/world/authoredEntities.d.ts +29 -0
- package/dist/world/authoredEntities.js +29 -0
- package/dist/world/authoredObjects.d.ts +72 -0
- package/dist/world/authoredObjects.js +81 -0
- package/dist/world/authoredSpawn.d.ts +39 -0
- package/dist/world/authoredSpawn.js +37 -0
- package/dist/world/buildSockets.d.ts +152 -0
- package/dist/world/buildSockets.js +188 -0
- package/dist/world/buildingGenerator.d.ts +18 -0
- package/dist/world/buildingGenerator.js +62 -0
- package/dist/world/buildings.d.ts +5 -0
- package/dist/world/buildings.js +5 -0
- package/dist/world/catenary.d.ts +22 -0
- package/dist/world/catenary.js +69 -0
- package/dist/world/cityBlocks.d.ts +152 -0
- package/dist/world/cityBlocks.js +670 -0
- package/dist/world/cityContent.d.ts +77 -0
- package/dist/world/cityContent.js +261 -0
- package/dist/world/cityGeometry.d.ts +114 -0
- package/dist/world/cityGeometry.js +573 -0
- package/dist/world/cityKind.d.ts +314 -0
- package/dist/world/cityKind.js +1578 -0
- package/dist/world/features.d.ts +133 -10
- package/dist/world/features.js +66 -6
- package/dist/world/footprintGrid.d.ts +59 -0
- package/dist/world/footprintGrid.js +141 -0
- package/dist/world/geometry.d.ts +64 -0
- package/dist/world/geometry.js +94 -0
- package/dist/world/grassKind.d.ts +51 -0
- package/dist/world/grassKind.js +101 -0
- package/dist/world/markers.d.ts +50 -4
- package/dist/world/markers.js +49 -0
- package/dist/world/massing.js +1 -1
- package/dist/world/minimapBake.d.ts +78 -0
- package/dist/world/minimapBake.js +208 -0
- package/dist/world/minimapTrack.d.ts +17 -0
- package/dist/world/minimapTrack.js +22 -0
- package/dist/world/pathInstances.d.ts +27 -0
- package/dist/world/pathInstances.js +27 -0
- package/dist/world/pathNetwork.d.ts +159 -0
- package/dist/world/pathNetwork.js +684 -0
- package/dist/world/pathTerrain.d.ts +80 -0
- package/dist/world/pathTerrain.js +142 -0
- package/dist/world/place.d.ts +166 -0
- package/dist/world/place.js +96 -0
- package/dist/world/placeAsset.d.ts +81 -0
- package/dist/world/placeAsset.js +79 -0
- package/dist/world/placement.d.ts +4 -0
- package/dist/world/placement.js +4 -0
- package/dist/world/placementController.d.ts +6 -0
- package/dist/world/placementController.js +6 -0
- package/dist/world/poleLineKind.d.ts +40 -0
- package/dist/world/poleLineKind.js +97 -0
- package/dist/world/polyline.d.ts +34 -0
- package/dist/world/polyline.js +88 -0
- package/dist/world/resourceNode.d.ts +109 -0
- package/dist/world/resourceNode.js +140 -0
- package/dist/world/roads.d.ts +8 -0
- package/dist/world/roads.js +38 -0
- package/dist/world/scatter.js +2 -20
- package/dist/world/scatterRegion.d.ts +164 -0
- package/dist/world/scatterRegion.js +409 -0
- package/dist/world/sceneShapes.d.ts +43 -0
- package/dist/world/sceneShapes.js +1 -0
- package/dist/world/segment.d.ts +27 -0
- package/dist/world/segment.js +43 -0
- package/dist/world/soilKind.d.ts +48 -0
- package/dist/world/soilKind.js +92 -0
- package/dist/world/spatialSample.d.ts +241 -0
- package/dist/world/spatialSample.js +465 -0
- package/dist/world/streets.d.ts +29 -0
- package/dist/world/streets.js +55 -0
- package/dist/world/terraform.d.ts +213 -1
- package/dist/world/terraform.js +627 -22
- package/dist/world/terrain.d.ts +164 -20
- package/dist/world/terrain.js +325 -41
- package/dist/world/terrainGuides.d.ts +182 -0
- package/dist/world/terrainGuides.js +343 -0
- package/dist/world/vec2.d.ts +81 -0
- package/dist/world/vec2.js +128 -0
- package/dist/world/vec3.d.ts +49 -0
- package/dist/world/vec3.js +76 -0
- package/dist/world/vegetation.d.ts +71 -0
- package/dist/world/vegetation.js +151 -0
- package/dist/world/visibilityField.d.ts +154 -0
- package/dist/world/visibilityField.js +271 -0
- package/dist/world/volumetricClouds.d.ts +52 -0
- package/dist/world/volumetricClouds.js +43 -0
- package/dist/world/walls.d.ts +9 -0
- package/dist/world/walls.js +9 -0
- package/dist/world/waterKind.d.ts +55 -0
- package/dist/world/waterKind.js +99 -0
- package/dist/world.d.ts +141 -0
- package/dist/world.js +141 -0
- package/package.json +32 -8
- package/skills/game-design/SKILL.md +28 -0
- package/skills/game-design/agents/openai.yaml +4 -0
- package/skills/game-design/references/application-playbook.md +170 -0
- package/skills/game-design/references/field-guide.md +288 -0
- package/skills/jgengine/SKILL.md +54 -0
- package/skills/jgengine/api.md +527 -0
- package/skills/jgengine/capabilities.md +131 -0
- package/skills/jgengine/recipes/minimal-game.md +88 -0
- package/skills/jgengine-combat/SKILL.md +38 -0
- package/skills/jgengine-combat/api.md +585 -0
- package/skills/jgengine-combat/capabilities.md +213 -0
- package/skills/jgengine-combat/recipes/portable-stat-pools.md +122 -0
- package/skills/jgengine-combat/reference.md +108 -0
- package/skills/jgengine-gameplay/SKILL.md +39 -0
- package/skills/jgengine-gameplay/api.md +1920 -0
- package/skills/jgengine-gameplay/capabilities.md +454 -0
- package/skills/jgengine-gameplay/reference-systems.md +56 -0
- package/skills/jgengine-world/SKILL.md +51 -0
- package/skills/jgengine-world/api.md +3056 -0
- package/skills/jgengine-world/capabilities.md +476 -0
- package/skills/jgengine-world/recipes/commanding-entities.md +128 -0
- package/skills/jgengine-world/reference.md +261 -0
- package/dist/cartridge/runtime.d.ts +0 -15
- package/dist/cartridge/runtime.js +0 -556
- package/dist/cartridge/spec.d.ts +0 -188
- package/dist/cartridge/spec.js +0 -19
- package/dist/cartridge/validate.d.ts +0 -2
- package/dist/cartridge/validate.js +0 -78
- package/dist/store/engineStore.d.ts +0 -22
- package/dist/store/engineStore.js +0 -50
- package/dist/store/features.d.ts +0 -10
- package/dist/store/features.js +0 -23
- package/llms.txt +0 -5389
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { seededRng } from "../random/rng.js";
|
|
2
|
+
/** Vertical row delta applied to the pick for each action. Row 0 is the shallow/top row. */
|
|
3
|
+
export const LOCK_ACTION_DELTA = {
|
|
4
|
+
hardSet: -2,
|
|
5
|
+
set: -1,
|
|
6
|
+
steady: 0,
|
|
7
|
+
ease: 1,
|
|
8
|
+
drop: 2,
|
|
9
|
+
};
|
|
10
|
+
/** The five pick actions, in display order (shallow → deep). */
|
|
11
|
+
export const LOCK_ACTIONS = ["hardSet", "set", "steady", "ease", "drop"];
|
|
12
|
+
function randInt(rng, min, max) {
|
|
13
|
+
return min + Math.floor(rng() * (max - min + 1));
|
|
14
|
+
}
|
|
15
|
+
function legalDeltas(tier) {
|
|
16
|
+
return tier.allowedActions.map((action) => LOCK_ACTION_DELTA[action]);
|
|
17
|
+
}
|
|
18
|
+
function sampleGateColumns(rng, cols, count) {
|
|
19
|
+
const candidates = [];
|
|
20
|
+
for (let c = 1; c <= cols - 2; c += 1)
|
|
21
|
+
candidates.push(c);
|
|
22
|
+
for (let i = candidates.length - 1; i > 0; i -= 1) {
|
|
23
|
+
const j = randInt(rng, 0, i);
|
|
24
|
+
const tmp = candidates[i];
|
|
25
|
+
candidates[i] = candidates[j];
|
|
26
|
+
candidates[j] = tmp;
|
|
27
|
+
}
|
|
28
|
+
return candidates.slice(0, Math.max(0, Math.min(count, candidates.length))).sort((a, b) => a - b);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Generate a solvable depth-puzzle lock: a "Tumbler's Path" board with a guaranteed solution
|
|
32
|
+
* path carved first, an open-row forgiveness band wrapped around it, tumbler gate columns that
|
|
33
|
+
* pinch to a single exact row, and optional ward-traps that look open but jam on contact.
|
|
34
|
+
* Deterministic: the same (seed, tier) always yields the same board.
|
|
35
|
+
*
|
|
36
|
+
* @capability lockpick a solvable grid depth-puzzle with fog-of-war, gates, and hidden traps
|
|
37
|
+
*/
|
|
38
|
+
export function generateLock(seed, tier) {
|
|
39
|
+
const rng = seededRng(seed);
|
|
40
|
+
const rows = tier.rows;
|
|
41
|
+
const cols = tier.cols;
|
|
42
|
+
const deltas = legalDeltas(tier);
|
|
43
|
+
const path = new Array(cols);
|
|
44
|
+
path[0] = randInt(rng, 0, rows - 1);
|
|
45
|
+
for (let c = 1; c < cols; c += 1) {
|
|
46
|
+
const legal = deltas.filter((d) => path[c - 1] + d >= 0 && path[c - 1] + d <= rows - 1);
|
|
47
|
+
path[c] = path[c - 1] + (legal.length > 0 ? legal[randInt(rng, 0, legal.length - 1)] : 0);
|
|
48
|
+
}
|
|
49
|
+
const gates = sampleGateColumns(rng, cols, tier.gateCount);
|
|
50
|
+
const gateSet = new Set(gates);
|
|
51
|
+
const open = new Array(cols);
|
|
52
|
+
for (let c = 0; c < cols; c += 1) {
|
|
53
|
+
if (c === cols - 1 || gateSet.has(c)) {
|
|
54
|
+
open[c] = [path[c]];
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
const band = [];
|
|
58
|
+
for (let r = path[c] - tier.width; r <= path[c] + tier.width; r += 1) {
|
|
59
|
+
if (r >= 0 && r <= rows - 1)
|
|
60
|
+
band.push(r);
|
|
61
|
+
}
|
|
62
|
+
open[c] = band;
|
|
63
|
+
}
|
|
64
|
+
for (let c = 1; c < cols; c += 1) {
|
|
65
|
+
const prev = open[c - 1];
|
|
66
|
+
open[c] = open[c].filter((r) => prev.some((pr) => deltas.includes(r - pr)));
|
|
67
|
+
}
|
|
68
|
+
for (let c = cols - 2; c >= 0; c -= 1) {
|
|
69
|
+
const next = open[c + 1];
|
|
70
|
+
open[c] = open[c].filter((r) => next.some((nr) => deltas.includes(nr - r)));
|
|
71
|
+
}
|
|
72
|
+
const traps = open.map(() => []);
|
|
73
|
+
const trapBudget = Math.max(0, tier.trapCount ?? 0);
|
|
74
|
+
if (trapBudget > 0) {
|
|
75
|
+
const candidates = [];
|
|
76
|
+
for (let c = 1; c < cols - 1; c += 1) {
|
|
77
|
+
if (gateSet.has(c))
|
|
78
|
+
continue;
|
|
79
|
+
for (const r of open[c])
|
|
80
|
+
if (r !== path[c])
|
|
81
|
+
candidates.push([c, r]);
|
|
82
|
+
}
|
|
83
|
+
for (let i = candidates.length - 1; i > 0; i -= 1) {
|
|
84
|
+
const j = randInt(rng, 0, i);
|
|
85
|
+
const tmp = candidates[i];
|
|
86
|
+
candidates[i] = candidates[j];
|
|
87
|
+
candidates[j] = tmp;
|
|
88
|
+
}
|
|
89
|
+
for (const [c, r] of candidates.slice(0, Math.min(trapBudget, candidates.length)))
|
|
90
|
+
traps[c].push(r);
|
|
91
|
+
for (const t of traps)
|
|
92
|
+
t.sort((a, b) => a - b);
|
|
93
|
+
}
|
|
94
|
+
return { seed, tier, open, gates, traps, startRow: path[0], seatRow: path[cols - 1] };
|
|
95
|
+
}
|
|
96
|
+
/** Return a concrete row-per-column solution, or null if the board is unsolvable. */
|
|
97
|
+
export function solveLockPath(spec) {
|
|
98
|
+
const deltas = legalDeltas(spec.tier);
|
|
99
|
+
const cols = spec.open.length;
|
|
100
|
+
const safe = (c, r) => spec.open[c].includes(r) && !spec.traps[c]?.includes(r);
|
|
101
|
+
if (!safe(0, spec.startRow))
|
|
102
|
+
return null;
|
|
103
|
+
const parents = [];
|
|
104
|
+
let reach = new Set([spec.startRow]);
|
|
105
|
+
parents[0] = new Map();
|
|
106
|
+
for (let c = 1; c < cols; c += 1) {
|
|
107
|
+
const next = new Set();
|
|
108
|
+
const par = new Map();
|
|
109
|
+
for (const r of reach) {
|
|
110
|
+
for (const d of deltas) {
|
|
111
|
+
const nr = r + d;
|
|
112
|
+
if (safe(c, nr) && !par.has(nr)) {
|
|
113
|
+
par.set(nr, r);
|
|
114
|
+
next.add(nr);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
parents[c] = par;
|
|
119
|
+
reach = next;
|
|
120
|
+
if (reach.size === 0)
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
if (!reach.has(spec.seatRow))
|
|
124
|
+
return null;
|
|
125
|
+
const path = new Array(cols);
|
|
126
|
+
path[cols - 1] = spec.seatRow;
|
|
127
|
+
for (let c = cols - 1; c > 0; c -= 1)
|
|
128
|
+
path[c - 1] = parents[c].get(path[c]);
|
|
129
|
+
return path;
|
|
130
|
+
}
|
|
131
|
+
/** Whether the board has a path from the start row to the bolt seat at all. */
|
|
132
|
+
export function solveLock(spec) {
|
|
133
|
+
return solveLockPath(spec) !== null;
|
|
134
|
+
}
|
|
135
|
+
/** Authoritative single step. The caller owns the lives economy: a slip/bind/trap does not
|
|
136
|
+
* advance the pick and should cost a life; advanced/success move the pick. */
|
|
137
|
+
export function stepLock(spec, col, row, action) {
|
|
138
|
+
const rows = spec.tier.rows;
|
|
139
|
+
const newRow = Math.max(0, Math.min(rows - 1, row + LOCK_ACTION_DELTA[action]));
|
|
140
|
+
const newCol = col + 1;
|
|
141
|
+
const colOpen = spec.open[newCol];
|
|
142
|
+
if (colOpen === undefined || !colOpen.includes(newRow)) {
|
|
143
|
+
const isGate = spec.gates.includes(newCol);
|
|
144
|
+
return { result: isGate ? "bind" : "slip", col, row };
|
|
145
|
+
}
|
|
146
|
+
if (spec.traps[newCol]?.includes(newRow) === true) {
|
|
147
|
+
return { result: "trap", col, row };
|
|
148
|
+
}
|
|
149
|
+
if (newCol === spec.open.length - 1 && newRow === spec.seatRow) {
|
|
150
|
+
return { result: "success", col: newCol, row: newRow };
|
|
151
|
+
}
|
|
152
|
+
return { result: "advanced", col: newCol, row: newRow };
|
|
153
|
+
}
|
|
154
|
+
/** The render-safe slice: every open cell in columns [0, col + window]. The single source of
|
|
155
|
+
* truth for fog and the anti-cheat boundary — never serialize the full spec to a client. */
|
|
156
|
+
export function visibleCells(spec, col, window) {
|
|
157
|
+
const last = spec.open.length - 1;
|
|
158
|
+
const maxCol = window >= spec.tier.cols ? last : Math.min(last, col + window);
|
|
159
|
+
const cells = [];
|
|
160
|
+
for (let c = 0; c <= maxCol; c += 1) {
|
|
161
|
+
const trapRows = spec.traps[c];
|
|
162
|
+
for (const r of spec.open[c]) {
|
|
163
|
+
const kind = c === last ? "seat" : spec.gates.includes(c) ? "gate" : trapRows?.includes(r) === true ? "trap" : "open";
|
|
164
|
+
cells.push({ col: c, row: r, kind });
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return cells;
|
|
168
|
+
}
|
|
@@ -46,6 +46,8 @@ export interface PositionedPrompt {
|
|
|
46
46
|
* Nearest prompt strictly within its radius wins; a higher-priority prompt in
|
|
47
47
|
* range beats any lower-priority one regardless of distance; equal priority
|
|
48
48
|
* and distance keep the earliest prompt in the list.
|
|
49
|
+
*
|
|
50
|
+
* @capability proximity-prompt a "press E" contextual prompt shown near an interactable
|
|
49
51
|
*/
|
|
50
52
|
export declare function resolveActivePrompt<T extends PositionedPrompt>(playerPosition: PromptPoint, prompts: readonly T[]): T | null;
|
|
51
53
|
export declare function promptDisplaysEqual(a: ProximityPromptDisplay, b: ProximityPromptDisplay): boolean;
|
|
@@ -17,6 +17,8 @@ export function proximityPrompt({ radius, display, invoke = null }) {
|
|
|
17
17
|
* Nearest prompt strictly within its radius wins; a higher-priority prompt in
|
|
18
18
|
* range beats any lower-priority one regardless of distance; equal priority
|
|
19
19
|
* and distance keep the earliest prompt in the list.
|
|
20
|
+
*
|
|
21
|
+
* @capability proximity-prompt a "press E" contextual prompt shown near an interactable
|
|
20
22
|
*/
|
|
21
23
|
export function resolveActivePrompt(playerPosition, prompts) {
|
|
22
24
|
let active = null;
|
|
@@ -15,6 +15,11 @@ export type QteOutcome = {
|
|
|
15
15
|
atStep: string;
|
|
16
16
|
reason: "missed-window" | "wrong-action" | "too-early";
|
|
17
17
|
};
|
|
18
|
+
/**
|
|
19
|
+
* Evaluate a quick-time-event input sequence against timed hit windows.
|
|
20
|
+
*
|
|
21
|
+
* @capability qte a quick-time-event timed input sequence with hit windows
|
|
22
|
+
*/
|
|
18
23
|
export declare function evaluateQteSequence(steps: readonly QteStep[], inputs: readonly QteInputEvent[]): QteOutcome;
|
|
19
24
|
export declare function pendingQteStep(steps: readonly QteStep[], elapsedSeconds: number): QteStep | null;
|
|
20
25
|
export declare function qteProgress(steps: readonly QteStep[], elapsedSeconds: number): number;
|
package/dist/interaction/qte.js
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Evaluate a quick-time-event input sequence against timed hit windows.
|
|
3
|
+
*
|
|
4
|
+
* @capability qte a quick-time-event timed input sequence with hit windows
|
|
5
|
+
*/
|
|
1
6
|
export function evaluateQteSequence(steps, inputs) {
|
|
2
7
|
for (let index = 0; index < steps.length; index += 1) {
|
|
3
8
|
const step = steps[index];
|
|
@@ -16,5 +16,10 @@ export interface SkillCheckResult {
|
|
|
16
16
|
zone: SkillCheckZone;
|
|
17
17
|
}
|
|
18
18
|
export declare function skillCheckMarkerPosition(config: SkillCheckConfig, elapsedSeconds: number): number;
|
|
19
|
+
/**
|
|
20
|
+
* A timing-bar skill check that succeeds when the moving marker is released inside the target zone.
|
|
21
|
+
*
|
|
22
|
+
* @capability skill-check a timing-bar skill check where you release inside a zone
|
|
23
|
+
*/
|
|
19
24
|
export declare function skillCheckZoneAt(config: SkillCheckConfig, elapsedSeconds: number): SkillCheckZone;
|
|
20
25
|
export declare function evaluateSkillCheck(config: SkillCheckConfig, elapsedSeconds: number): SkillCheckResult;
|
|
@@ -8,6 +8,11 @@ function bounce(t, period, max) {
|
|
|
8
8
|
export function skillCheckMarkerPosition(config, elapsedSeconds) {
|
|
9
9
|
return bounce(Math.max(0, elapsedSeconds), config.markerPeriod, config.trackWidth);
|
|
10
10
|
}
|
|
11
|
+
/**
|
|
12
|
+
* A timing-bar skill check that succeeds when the moving marker is released inside the target zone.
|
|
13
|
+
*
|
|
14
|
+
* @capability skill-check a timing-bar skill check where you release inside a zone
|
|
15
|
+
*/
|
|
11
16
|
export function skillCheckZoneAt(config, elapsedSeconds) {
|
|
12
17
|
const drift = config.zoneDriftPerSecond ?? 0;
|
|
13
18
|
if (drift === 0)
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/** One carried stack: an item id and how many of it the carrier holds. */
|
|
2
|
+
export interface LoadEntry {
|
|
3
|
+
itemId: string;
|
|
4
|
+
quantity: number;
|
|
5
|
+
}
|
|
6
|
+
/** Resolves the per-unit mass of an item id. Injected so mass tables stay decoupled from this module. */
|
|
7
|
+
export type MassResolver = (itemId: string) => number;
|
|
8
|
+
/**
|
|
9
|
+
* Tuning for where the encumbrance bands sit and how hard the carrier is slowed.
|
|
10
|
+
* Both fields are load *fractions* / multipliers in `0..1`, never absolute mass.
|
|
11
|
+
*/
|
|
12
|
+
export interface EncumbranceConfig {
|
|
13
|
+
/**
|
|
14
|
+
* Load fraction at/above which the carrier becomes encumbered (loses sprint & jump and
|
|
15
|
+
* starts slowing). Below it the carrier is unencumbered. Default `0.85`.
|
|
16
|
+
*/
|
|
17
|
+
soft?: number;
|
|
18
|
+
/**
|
|
19
|
+
* Move-speed multiplier reached as load approaches full capacity (fraction → 1), the floor
|
|
20
|
+
* the progressive slow curve bottoms out at just before immobility. Default `0.5`.
|
|
21
|
+
*/
|
|
22
|
+
floor?: number;
|
|
23
|
+
}
|
|
24
|
+
/** Coarse carry state: free-moving, slowed, or pinned in place. */
|
|
25
|
+
export type EncumbranceTier = "unencumbered" | "encumbered" | "immobile";
|
|
26
|
+
/** Serializable snapshot of a carrier's load versus capacity and the movement consequences. */
|
|
27
|
+
export interface EncumbranceState {
|
|
28
|
+
/** Total carried mass (never negative). */
|
|
29
|
+
mass: number;
|
|
30
|
+
/** Carrying capacity this load was measured against. */
|
|
31
|
+
capacity: number;
|
|
32
|
+
/** `mass / capacity`, clamped to be finite and non-negative; may exceed 1 when overloaded. */
|
|
33
|
+
fraction: number;
|
|
34
|
+
tier: EncumbranceTier;
|
|
35
|
+
/** Movement speed scalar in `0..1`: 1 when unencumbered, decays toward `floor`, 0 when immobile. */
|
|
36
|
+
moveMultiplier: number;
|
|
37
|
+
canSprint: boolean;
|
|
38
|
+
canJump: boolean;
|
|
39
|
+
immobile: boolean;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Sum the mass of every carried stack using an injected per-unit mass resolver. Bounded by the
|
|
43
|
+
* number of entries; allocates nothing. Missing or negative unit masses are treated as 0.
|
|
44
|
+
*
|
|
45
|
+
* @param entries carried stacks (`{ itemId, quantity }`, compatible with any inventory listing).
|
|
46
|
+
* @param massOf per-unit mass lookup for an item id.
|
|
47
|
+
* @capability carry-load sum carried mass from item stacks via an injected mass resolver
|
|
48
|
+
*/
|
|
49
|
+
export declare function totalLoad(entries: readonly LoadEntry[], massOf: MassResolver): number;
|
|
50
|
+
/**
|
|
51
|
+
* Progressive move-speed multiplier for a raw load fraction: 1 while at/below `soft`, a linear
|
|
52
|
+
* decay from 1 down toward `floor` across the `soft..1` band, and 0 once at/over capacity.
|
|
53
|
+
* Pure and side-effect free — the curve `resolveEncumbrance` reads for `moveMultiplier`.
|
|
54
|
+
*
|
|
55
|
+
* @capability encumbrance-move-curve progressive move-speed multiplier from a carry-load fraction
|
|
56
|
+
*/
|
|
57
|
+
export declare function encumbranceMoveMultiplier(fraction: number, config?: EncumbranceConfig): number;
|
|
58
|
+
/**
|
|
59
|
+
* Resolve carried mass against carrying capacity into a serializable encumbrance state: load
|
|
60
|
+
* fraction, tier, and the movement consequences (`canSprint`/`canJump`/`immobile` gates plus a
|
|
61
|
+
* progressive `moveMultiplier`). Below `soft` the carrier is unencumbered and unhindered; from
|
|
62
|
+
* `soft` up to capacity it is encumbered — no sprint or jump, and speed decays from 1 toward
|
|
63
|
+
* `floor`; at or above capacity it is immobile (multiplier 0). Deterministic and allocation-light;
|
|
64
|
+
* pair with {@link totalLoad} to derive `mass` from an inventory and a mass table. A capacity of 0
|
|
65
|
+
* or less pins any positive load as immobile (`fraction` 1) so the state stays finite/serializable.
|
|
66
|
+
*
|
|
67
|
+
* @capability carry-encumbrance carried mass vs capacity into movement penalty tiers and a speed multiplier
|
|
68
|
+
*/
|
|
69
|
+
export declare function resolveEncumbrance(mass: number, capacity: number, config?: EncumbranceConfig): EncumbranceState;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
const DEFAULT_SOFT = 0.85;
|
|
2
|
+
const DEFAULT_FLOOR = 0.5;
|
|
3
|
+
/**
|
|
4
|
+
* Sum the mass of every carried stack using an injected per-unit mass resolver. Bounded by the
|
|
5
|
+
* number of entries; allocates nothing. Missing or negative unit masses are treated as 0.
|
|
6
|
+
*
|
|
7
|
+
* @param entries carried stacks (`{ itemId, quantity }`, compatible with any inventory listing).
|
|
8
|
+
* @param massOf per-unit mass lookup for an item id.
|
|
9
|
+
* @capability carry-load sum carried mass from item stacks via an injected mass resolver
|
|
10
|
+
*/
|
|
11
|
+
export function totalLoad(entries, massOf) {
|
|
12
|
+
let total = 0;
|
|
13
|
+
for (const entry of entries) {
|
|
14
|
+
if (entry.quantity <= 0)
|
|
15
|
+
continue;
|
|
16
|
+
const unit = massOf(entry.itemId);
|
|
17
|
+
if (unit > 0)
|
|
18
|
+
total += unit * entry.quantity;
|
|
19
|
+
}
|
|
20
|
+
return total;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Progressive move-speed multiplier for a raw load fraction: 1 while at/below `soft`, a linear
|
|
24
|
+
* decay from 1 down toward `floor` across the `soft..1` band, and 0 once at/over capacity.
|
|
25
|
+
* Pure and side-effect free — the curve `resolveEncumbrance` reads for `moveMultiplier`.
|
|
26
|
+
*
|
|
27
|
+
* @capability encumbrance-move-curve progressive move-speed multiplier from a carry-load fraction
|
|
28
|
+
*/
|
|
29
|
+
export function encumbranceMoveMultiplier(fraction, config) {
|
|
30
|
+
const soft = config?.soft ?? DEFAULT_SOFT;
|
|
31
|
+
const floor = config?.floor ?? DEFAULT_FLOOR;
|
|
32
|
+
if (fraction >= 1)
|
|
33
|
+
return 0;
|
|
34
|
+
if (fraction <= soft)
|
|
35
|
+
return 1;
|
|
36
|
+
const span = 1 - soft;
|
|
37
|
+
const t = span > 0 ? (fraction - soft) / span : 1;
|
|
38
|
+
return 1 - (1 - floor) * t;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Resolve carried mass against carrying capacity into a serializable encumbrance state: load
|
|
42
|
+
* fraction, tier, and the movement consequences (`canSprint`/`canJump`/`immobile` gates plus a
|
|
43
|
+
* progressive `moveMultiplier`). Below `soft` the carrier is unencumbered and unhindered; from
|
|
44
|
+
* `soft` up to capacity it is encumbered — no sprint or jump, and speed decays from 1 toward
|
|
45
|
+
* `floor`; at or above capacity it is immobile (multiplier 0). Deterministic and allocation-light;
|
|
46
|
+
* pair with {@link totalLoad} to derive `mass` from an inventory and a mass table. A capacity of 0
|
|
47
|
+
* or less pins any positive load as immobile (`fraction` 1) so the state stays finite/serializable.
|
|
48
|
+
*
|
|
49
|
+
* @capability carry-encumbrance carried mass vs capacity into movement penalty tiers and a speed multiplier
|
|
50
|
+
*/
|
|
51
|
+
export function resolveEncumbrance(mass, capacity, config) {
|
|
52
|
+
const soft = config?.soft ?? DEFAULT_SOFT;
|
|
53
|
+
const safeMass = mass > 0 ? mass : 0;
|
|
54
|
+
const fraction = capacity > 0 ? safeMass / capacity : safeMass > 0 ? 1 : 0;
|
|
55
|
+
const immobile = fraction >= 1;
|
|
56
|
+
const tier = immobile ? "immobile" : fraction >= soft ? "encumbered" : "unencumbered";
|
|
57
|
+
const unencumbered = tier === "unencumbered";
|
|
58
|
+
return {
|
|
59
|
+
mass: safeMass,
|
|
60
|
+
capacity,
|
|
61
|
+
fraction,
|
|
62
|
+
tier,
|
|
63
|
+
moveMultiplier: encumbranceMoveMultiplier(fraction, config),
|
|
64
|
+
canSprint: unencumbered,
|
|
65
|
+
canJump: unencumbered,
|
|
66
|
+
immobile,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
@@ -35,13 +35,24 @@ export type MoveResult = {
|
|
|
35
35
|
status: "rejected";
|
|
36
36
|
reason: "invalid-slot" | "empty-slot" | "wrong-kind" | "no-space";
|
|
37
37
|
};
|
|
38
|
+
/**
|
|
39
|
+
* A bag of stackable items supporting add, remove, count, and move — the base inventory model.
|
|
40
|
+
*
|
|
41
|
+
* @capability inventory-grid a bag of stackable items with add, remove, and move
|
|
42
|
+
* @internal
|
|
43
|
+
*/
|
|
38
44
|
export declare function createEmptyInventory(layout: InventoryLayout): InventoryState;
|
|
45
|
+
/** @internal */
|
|
39
46
|
export declare function putItem(state: InventoryState, layout: InventoryLayout, traits: ItemTraits, itemId: string, count: number, options?: {
|
|
40
47
|
slot?: number;
|
|
41
48
|
}): PutResult;
|
|
49
|
+
/** @internal */
|
|
42
50
|
export declare function takeItem(state: InventoryState, itemId: string, count: number): TakeResult;
|
|
51
|
+
/** @internal */
|
|
43
52
|
export declare function countItem(state: InventoryState, itemId: string): number;
|
|
53
|
+
/** @internal */
|
|
44
54
|
export declare function hasItem(state: InventoryState, itemId: string, count: number): boolean;
|
|
55
|
+
/** @internal */
|
|
45
56
|
export declare function moveItem(from: InventoryState, fromSlot: number, to: InventoryState, toLayout: InventoryLayout, traits: ItemTraits, toSlot?: number): MoveResult;
|
|
46
57
|
export interface InventorySet<TId extends string> {
|
|
47
58
|
put(id: TId, itemId: string, count: number, options?: {
|
|
@@ -54,4 +65,5 @@ export interface InventorySet<TId extends string> {
|
|
|
54
65
|
state(id: TId): InventoryState;
|
|
55
66
|
replaceState(id: TId, state: InventoryState): void;
|
|
56
67
|
}
|
|
68
|
+
/** @internal */
|
|
57
69
|
export declare function createInventorySet<TId extends string>(layouts: Record<TId, InventoryLayout>, traits: ItemTraits): InventorySet<TId>;
|
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A bag of stackable items supporting add, remove, count, and move — the base inventory model.
|
|
3
|
+
*
|
|
4
|
+
* @capability inventory-grid a bag of stackable items with add, remove, and move
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
1
7
|
export function createEmptyInventory(layout) {
|
|
2
8
|
return { slots: new Array(layout.slots).fill(null) };
|
|
3
9
|
}
|
|
@@ -76,11 +82,13 @@ function explicitPut(state, layout, traits, itemId, count, slot) {
|
|
|
76
82
|
slots[slot] = { itemId, count: newCount };
|
|
77
83
|
return { status: "ok", state: { slots } };
|
|
78
84
|
}
|
|
85
|
+
/** @internal */
|
|
79
86
|
export function putItem(state, layout, traits, itemId, count, options) {
|
|
80
87
|
if (options?.slot !== undefined)
|
|
81
88
|
return explicitPut(state, layout, traits, itemId, count, options.slot);
|
|
82
89
|
return autoPut(state, layout, traits, itemId, count);
|
|
83
90
|
}
|
|
91
|
+
/** @internal */
|
|
84
92
|
export function takeItem(state, itemId, count) {
|
|
85
93
|
if (count <= 0)
|
|
86
94
|
return { status: "ok", state };
|
|
@@ -99,6 +107,7 @@ export function takeItem(state, itemId, count) {
|
|
|
99
107
|
}
|
|
100
108
|
return { status: "ok", state: { slots } };
|
|
101
109
|
}
|
|
110
|
+
/** @internal */
|
|
102
111
|
export function countItem(state, itemId) {
|
|
103
112
|
let total = 0;
|
|
104
113
|
for (const slot of state.slots)
|
|
@@ -106,9 +115,11 @@ export function countItem(state, itemId) {
|
|
|
106
115
|
total += slot.count;
|
|
107
116
|
return total;
|
|
108
117
|
}
|
|
118
|
+
/** @internal */
|
|
109
119
|
export function hasItem(state, itemId, count) {
|
|
110
120
|
return countItem(state, itemId) >= count;
|
|
111
121
|
}
|
|
122
|
+
/** @internal */
|
|
112
123
|
export function moveItem(from, fromSlot, to, toLayout, traits, toSlot) {
|
|
113
124
|
if (fromSlot < 0 || fromSlot >= from.slots.length)
|
|
114
125
|
return { status: "rejected", reason: "invalid-slot" };
|
|
@@ -160,6 +171,7 @@ export function moveItem(from, fromSlot, to, toLayout, traits, toSlot) {
|
|
|
160
171
|
to: sameInventory ? { slots: fromSlots } : { slots: toSlots },
|
|
161
172
|
};
|
|
162
173
|
}
|
|
174
|
+
/** @internal */
|
|
163
175
|
export function createInventorySet(layouts, traits) {
|
|
164
176
|
const states = new Map();
|
|
165
177
|
for (const id of Object.keys(layouts)) {
|
|
@@ -29,14 +29,28 @@ export interface ShapedRejected {
|
|
|
29
29
|
detail?: string;
|
|
30
30
|
}
|
|
31
31
|
export type ShapedResult<T> = ShapedPlaceResult<T> | ShapedRejected;
|
|
32
|
+
/** @internal */
|
|
32
33
|
export declare function normalizeFootprint(footprint: Footprint): Footprint;
|
|
34
|
+
/** @internal */
|
|
33
35
|
export declare function rotateFootprint(footprint: Footprint, rotation: Rotation): Footprint;
|
|
36
|
+
/** @internal */
|
|
34
37
|
export declare function occupiedCells(footprint: Footprint, origin: Cell, rotation: Rotation): Cell[];
|
|
38
|
+
/**
|
|
39
|
+
* A spatial grid inventory that holds shaped multi-cell items, Resident-Evil/Tarkov style.
|
|
40
|
+
*
|
|
41
|
+
* @capability tetris-inventory a spatial grid inventory holding shaped multi-cell items
|
|
42
|
+
* @internal
|
|
43
|
+
*/
|
|
35
44
|
export declare function createShapedGrid<T>(width: number, height: number): ShapedGrid<T>;
|
|
45
|
+
/** @internal */
|
|
36
46
|
export declare function canPlace<T>(grid: ShapedGrid<T>, footprint: Footprint, origin: Cell, rotation: Rotation, ignoreId?: string): ShapedRejection | null;
|
|
47
|
+
/** @internal */
|
|
37
48
|
export declare function placeShaped<T>(grid: ShapedGrid<T>, item: ShapedItem<T>, origin: Cell, rotation?: Rotation): ShapedResult<T>;
|
|
49
|
+
/** @internal */
|
|
38
50
|
export declare function removeShaped<T>(grid: ShapedGrid<T>, id: string): ShapedResult<T>;
|
|
51
|
+
/** @internal */
|
|
39
52
|
export declare function moveShaped<T>(grid: ShapedGrid<T>, id: string, origin: Cell, rotation?: Rotation): ShapedResult<T>;
|
|
53
|
+
/** @internal */
|
|
40
54
|
export declare function cellOccupant<T>(grid: ShapedGrid<T>, cell: Cell): string | null;
|
|
41
55
|
export interface GridAdjacencyQuery {
|
|
42
56
|
cellsOf(id: string): readonly Cell[];
|
|
@@ -44,9 +58,11 @@ export interface GridAdjacencyQuery {
|
|
|
44
58
|
touching(idA: string, idB: string): boolean;
|
|
45
59
|
adjacentCells(cells: readonly Cell[]): readonly Cell[];
|
|
46
60
|
}
|
|
61
|
+
/** @internal */
|
|
47
62
|
export declare function gridAdjacencyQuery<T>(grid: ShapedGrid<T>, options?: {
|
|
48
63
|
diagonal?: boolean;
|
|
49
64
|
}): GridAdjacencyQuery;
|
|
65
|
+
/** @internal */
|
|
50
66
|
export declare function cellFromPoint(point: {
|
|
51
67
|
x: number;
|
|
52
68
|
y: number;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
function cellKey(cell) {
|
|
2
2
|
return `${cell[0]},${cell[1]}`;
|
|
3
3
|
}
|
|
4
|
+
/** @internal */
|
|
4
5
|
export function normalizeFootprint(footprint) {
|
|
5
6
|
if (footprint.length === 0)
|
|
6
7
|
return [];
|
|
@@ -25,6 +26,7 @@ export function normalizeFootprint(footprint) {
|
|
|
25
26
|
}
|
|
26
27
|
return out;
|
|
27
28
|
}
|
|
29
|
+
/** @internal */
|
|
28
30
|
export function rotateFootprint(footprint, rotation) {
|
|
29
31
|
const turns = ((rotation % 4) + 4) % 4;
|
|
30
32
|
let cells = footprint.map(([c, r]) => [c, r]);
|
|
@@ -33,10 +35,17 @@ export function rotateFootprint(footprint, rotation) {
|
|
|
33
35
|
}
|
|
34
36
|
return normalizeFootprint(cells);
|
|
35
37
|
}
|
|
38
|
+
/** @internal */
|
|
36
39
|
export function occupiedCells(footprint, origin, rotation) {
|
|
37
40
|
const rotated = rotateFootprint(footprint, rotation);
|
|
38
41
|
return rotated.map(([c, r]) => [c + origin[0], r + origin[1]]);
|
|
39
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* A spatial grid inventory that holds shaped multi-cell items, Resident-Evil/Tarkov style.
|
|
45
|
+
*
|
|
46
|
+
* @capability tetris-inventory a spatial grid inventory holding shaped multi-cell items
|
|
47
|
+
* @internal
|
|
48
|
+
*/
|
|
40
49
|
export function createShapedGrid(width, height) {
|
|
41
50
|
if (width <= 0 || height <= 0)
|
|
42
51
|
throw new Error("shaped grid needs positive dimensions");
|
|
@@ -56,6 +65,7 @@ function occupancyMap(grid, ignoreId) {
|
|
|
56
65
|
}
|
|
57
66
|
return map;
|
|
58
67
|
}
|
|
68
|
+
/** @internal */
|
|
59
69
|
export function canPlace(grid, footprint, origin, rotation, ignoreId) {
|
|
60
70
|
const cells = occupiedCells(footprint, origin, rotation);
|
|
61
71
|
if (!inBounds(grid, cells))
|
|
@@ -67,6 +77,7 @@ export function canPlace(grid, footprint, origin, rotation, ignoreId) {
|
|
|
67
77
|
}
|
|
68
78
|
return null;
|
|
69
79
|
}
|
|
80
|
+
/** @internal */
|
|
70
81
|
export function placeShaped(grid, item, origin, rotation = 0) {
|
|
71
82
|
if (grid.placements.some((p) => p.id === item.id)) {
|
|
72
83
|
return { status: "rejected", reason: "duplicate-id", detail: item.id };
|
|
@@ -83,12 +94,14 @@ export function placeShaped(grid, item, origin, rotation = 0) {
|
|
|
83
94
|
};
|
|
84
95
|
return { status: "ok", grid: { ...grid, placements: [...grid.placements, placement] } };
|
|
85
96
|
}
|
|
97
|
+
/** @internal */
|
|
86
98
|
export function removeShaped(grid, id) {
|
|
87
99
|
if (!grid.placements.some((p) => p.id === id)) {
|
|
88
100
|
return { status: "rejected", reason: "unknown-id", detail: id };
|
|
89
101
|
}
|
|
90
102
|
return { status: "ok", grid: { ...grid, placements: grid.placements.filter((p) => p.id !== id) } };
|
|
91
103
|
}
|
|
104
|
+
/** @internal */
|
|
92
105
|
export function moveShaped(grid, id, origin, rotation) {
|
|
93
106
|
const existing = grid.placements.find((p) => p.id === id);
|
|
94
107
|
if (existing === undefined)
|
|
@@ -105,6 +118,7 @@ export function moveShaped(grid, id, origin, rotation) {
|
|
|
105
118
|
},
|
|
106
119
|
};
|
|
107
120
|
}
|
|
121
|
+
/** @internal */
|
|
108
122
|
export function cellOccupant(grid, cell) {
|
|
109
123
|
return occupancyMap(grid).get(cellKey(cell)) ?? null;
|
|
110
124
|
}
|
|
@@ -120,6 +134,7 @@ const DIAGONAL = [
|
|
|
120
134
|
[-1, 1],
|
|
121
135
|
[-1, -1],
|
|
122
136
|
];
|
|
137
|
+
/** @internal */
|
|
123
138
|
export function gridAdjacencyQuery(grid, options = {}) {
|
|
124
139
|
const directions = options.diagonal ? [...ORTHOGONAL, ...DIAGONAL] : ORTHOGONAL;
|
|
125
140
|
const cellsById = new Map();
|
|
@@ -168,6 +183,7 @@ export function gridAdjacencyQuery(grid, options = {}) {
|
|
|
168
183
|
},
|
|
169
184
|
};
|
|
170
185
|
}
|
|
186
|
+
/** @internal */
|
|
171
187
|
export function cellFromPoint(point, cellSize, gridOrigin = { x: 0, y: 0 }) {
|
|
172
188
|
return [
|
|
173
189
|
Math.floor((point.x - gridOrigin.x) / cellSize),
|
|
@@ -7,13 +7,23 @@ export type SlotResult<T> = {
|
|
|
7
7
|
status: "rejected";
|
|
8
8
|
reason: "invalid-slot" | "slot-occupied" | "empty-slot";
|
|
9
9
|
};
|
|
10
|
+
/** @internal */
|
|
10
11
|
export declare function createSlots<T>(size: number): Slot<T>[];
|
|
12
|
+
/** @internal */
|
|
11
13
|
export declare function normalizeSlots<T>(values: SlotGrid<T>, size: number): Slot<T>[];
|
|
14
|
+
/** @internal */
|
|
12
15
|
export declare function placeAt<T>(grid: SlotGrid<T>, index: number, value: T): SlotResult<T>;
|
|
16
|
+
/** @internal */
|
|
13
17
|
export declare function removeAt<T>(grid: SlotGrid<T>, index: number): SlotResult<T>;
|
|
18
|
+
/** @internal */
|
|
14
19
|
export declare function moveSlot<T>(grid: SlotGrid<T>, from: number, to: number): SlotResult<T>;
|
|
20
|
+
/** @internal */
|
|
15
21
|
export declare function firstEmpty<T>(grid: SlotGrid<T>): number | null;
|
|
22
|
+
/** @internal */
|
|
16
23
|
export declare function insertFirst<T>(grid: SlotGrid<T>, value: T): SlotResult<T>;
|
|
24
|
+
/** @internal */
|
|
17
25
|
export declare function compactSlots<T>(grid: SlotGrid<T>): Slot<T>[];
|
|
26
|
+
/** @internal */
|
|
18
27
|
export declare function countFilled<T>(grid: SlotGrid<T>): number;
|
|
28
|
+
/** @internal */
|
|
19
29
|
export declare function indexOfSlot<T>(grid: SlotGrid<T>, match: (value: T, index: number) => boolean): number | null;
|