@alife-sdk/core 0.1.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/LICENSE +21 -0
- package/README.md +283 -0
- package/dist/ai/DangerManager.d.ts +71 -0
- package/dist/ai/DangerManager.d.ts.map +1 -0
- package/dist/ai/DangerManager.js +176 -0
- package/dist/ai/DangerManager.js.map +1 -0
- package/dist/ai/GOAPAction.d.ts +45 -0
- package/dist/ai/GOAPAction.d.ts.map +1 -0
- package/dist/ai/GOAPAction.js +32 -0
- package/dist/ai/GOAPAction.js.map +1 -0
- package/dist/ai/GOAPPlanner.d.ts +80 -0
- package/dist/ai/GOAPPlanner.d.ts.map +1 -0
- package/dist/ai/GOAPPlanner.js +259 -0
- package/dist/ai/GOAPPlanner.js.map +1 -0
- package/dist/ai/IStateHandler.d.ts +8 -0
- package/dist/ai/IStateHandler.d.ts.map +1 -0
- package/dist/ai/IStateHandler.js +8 -0
- package/dist/ai/IStateHandler.js.map +1 -0
- package/dist/ai/MemorySystem.d.ts +94 -0
- package/dist/ai/MemorySystem.d.ts.map +1 -0
- package/dist/ai/MemorySystem.js +207 -0
- package/dist/ai/MemorySystem.js.map +1 -0
- package/dist/ai/StateMachine.d.ts +49 -0
- package/dist/ai/StateMachine.d.ts.map +1 -0
- package/dist/ai/StateMachine.js +83 -0
- package/dist/ai/StateMachine.js.map +1 -0
- package/dist/ai/WorldState.d.ts +48 -0
- package/dist/ai/WorldState.d.ts.map +1 -0
- package/dist/ai/WorldState.js +93 -0
- package/dist/ai/WorldState.js.map +1 -0
- package/dist/ai/index.d.ts +10 -0
- package/dist/ai/index.d.ts.map +1 -0
- package/dist/ai/index.js +8 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/combat/DamageInstance.d.ts +26 -0
- package/dist/combat/DamageInstance.d.ts.map +1 -0
- package/dist/combat/DamageInstance.js +25 -0
- package/dist/combat/DamageInstance.js.map +1 -0
- package/dist/combat/MoraleStateMachine.d.ts +53 -0
- package/dist/combat/MoraleStateMachine.d.ts.map +1 -0
- package/dist/combat/MoraleStateMachine.js +84 -0
- package/dist/combat/MoraleStateMachine.js.map +1 -0
- package/dist/combat/index.d.ts +5 -0
- package/dist/combat/index.d.ts.map +1 -0
- package/dist/combat/index.js +3 -0
- package/dist/combat/index.js.map +1 -0
- package/dist/config/ALifeConfig.d.ts +131 -0
- package/dist/config/ALifeConfig.d.ts.map +1 -0
- package/dist/config/ALifeConfig.js +82 -0
- package/dist/config/ALifeConfig.js.map +1 -0
- package/dist/config/index.d.ts +3 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +2 -0
- package/dist/config/index.js.map +1 -0
- package/dist/core/ALifeKernel.d.ts +163 -0
- package/dist/core/ALifeKernel.d.ts.map +1 -0
- package/dist/core/ALifeKernel.js +542 -0
- package/dist/core/ALifeKernel.js.map +1 -0
- package/dist/core/Clock.d.ts +123 -0
- package/dist/core/Clock.d.ts.map +1 -0
- package/dist/core/Clock.js +228 -0
- package/dist/core/Clock.js.map +1 -0
- package/dist/core/DevToolsInspector.d.ts +53 -0
- package/dist/core/DevToolsInspector.d.ts.map +1 -0
- package/dist/core/DevToolsInspector.js +8 -0
- package/dist/core/DevToolsInspector.js.map +1 -0
- package/dist/core/Diagnostics.d.ts +64 -0
- package/dist/core/Diagnostics.d.ts.map +1 -0
- package/dist/core/Diagnostics.js +107 -0
- package/dist/core/Diagnostics.js.map +1 -0
- package/dist/core/ISerializable.d.ts +12 -0
- package/dist/core/ISerializable.d.ts.map +1 -0
- package/dist/core/ISerializable.js +2 -0
- package/dist/core/ISerializable.js.map +1 -0
- package/dist/core/PortRegistry.d.ts +57 -0
- package/dist/core/PortRegistry.d.ts.map +1 -0
- package/dist/core/PortRegistry.js +72 -0
- package/dist/core/PortRegistry.js.map +1 -0
- package/dist/core/PortTokens.d.ts +39 -0
- package/dist/core/PortTokens.d.ts.map +1 -0
- package/dist/core/PortTokens.js +39 -0
- package/dist/core/PortTokens.js.map +1 -0
- package/dist/core/SpatialGrid.d.ts +114 -0
- package/dist/core/SpatialGrid.d.ts.map +1 -0
- package/dist/core/SpatialGrid.js +258 -0
- package/dist/core/SpatialGrid.js.map +1 -0
- package/dist/core/Vec2.d.ts +34 -0
- package/dist/core/Vec2.d.ts.map +1 -0
- package/dist/core/Vec2.js +52 -0
- package/dist/core/Vec2.js.map +1 -0
- package/dist/core/math/CatmullRom.d.ts +20 -0
- package/dist/core/math/CatmullRom.d.ts.map +1 -0
- package/dist/core/math/CatmullRom.js +37 -0
- package/dist/core/math/CatmullRom.js.map +1 -0
- package/dist/core/math/index.d.ts +6 -0
- package/dist/core/math/index.d.ts.map +1 -0
- package/dist/core/math/index.js +5 -0
- package/dist/core/math/index.js.map +1 -0
- package/dist/core/math/intersects.d.ts +32 -0
- package/dist/core/math/intersects.d.ts.map +1 -0
- package/dist/core/math/intersects.js +92 -0
- package/dist/core/math/intersects.js.map +1 -0
- package/dist/core/math/utils.d.ts +5 -0
- package/dist/core/math/utils.d.ts.map +1 -0
- package/dist/core/math/utils.js +13 -0
- package/dist/core/math/utils.js.map +1 -0
- package/dist/entity/IComponent.d.ts +17 -0
- package/dist/entity/IComponent.d.ts.map +1 -0
- package/dist/entity/IComponent.js +2 -0
- package/dist/entity/IComponent.js.map +1 -0
- package/dist/entity/IEntity.d.ts +33 -0
- package/dist/entity/IEntity.d.ts.map +1 -0
- package/dist/entity/IEntity.js +2 -0
- package/dist/entity/IEntity.js.map +1 -0
- package/dist/entity/index.d.ts +3 -0
- package/dist/entity/index.d.ts.map +1 -0
- package/dist/entity/index.js +2 -0
- package/dist/entity/index.js.map +1 -0
- package/dist/events/ALifeEvents.d.ts +241 -0
- package/dist/events/ALifeEvents.d.ts.map +1 -0
- package/dist/events/ALifeEvents.js +53 -0
- package/dist/events/ALifeEvents.js.map +1 -0
- package/dist/events/EventBus.d.ts +52 -0
- package/dist/events/EventBus.d.ts.map +1 -0
- package/dist/events/EventBus.js +129 -0
- package/dist/events/EventBus.js.map +1 -0
- package/dist/events/index.d.ts +4 -0
- package/dist/events/index.d.ts.map +1 -0
- package/dist/events/index.js +4 -0
- package/dist/events/index.js.map +1 -0
- package/dist/faction/Faction.d.ts +53 -0
- package/dist/faction/Faction.d.ts.map +1 -0
- package/dist/faction/Faction.js +101 -0
- package/dist/faction/Faction.js.map +1 -0
- package/dist/faction/FactionBuilder.d.ts +32 -0
- package/dist/faction/FactionBuilder.d.ts.map +1 -0
- package/dist/faction/FactionBuilder.js +80 -0
- package/dist/faction/FactionBuilder.js.map +1 -0
- package/dist/faction/ImmunityProfile.d.ts +24 -0
- package/dist/faction/ImmunityProfile.d.ts.map +1 -0
- package/dist/faction/ImmunityProfile.js +43 -0
- package/dist/faction/ImmunityProfile.js.map +1 -0
- package/dist/faction/index.d.ts +6 -0
- package/dist/faction/index.d.ts.map +1 -0
- package/dist/faction/index.js +5 -0
- package/dist/faction/index.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -0
- package/dist/logger/ILogEntry.d.ts +16 -0
- package/dist/logger/ILogEntry.d.ts.map +1 -0
- package/dist/logger/ILogEntry.js +2 -0
- package/dist/logger/ILogEntry.js.map +1 -0
- package/dist/logger/LogChannel.d.ts +27 -0
- package/dist/logger/LogChannel.d.ts.map +1 -0
- package/dist/logger/LogChannel.js +26 -0
- package/dist/logger/LogChannel.js.map +1 -0
- package/dist/logger/LogLevel.d.ts +10 -0
- package/dist/logger/LogLevel.d.ts.map +1 -0
- package/dist/logger/LogLevel.js +9 -0
- package/dist/logger/LogLevel.js.map +1 -0
- package/dist/logger/Logger.d.ts +56 -0
- package/dist/logger/Logger.d.ts.map +1 -0
- package/dist/logger/Logger.js +106 -0
- package/dist/logger/Logger.js.map +1 -0
- package/dist/logger/index.d.ts +8 -0
- package/dist/logger/index.d.ts.map +1 -0
- package/dist/logger/index.js +5 -0
- package/dist/logger/index.js.map +1 -0
- package/dist/movement/MonsterHome.d.ts +49 -0
- package/dist/movement/MonsterHome.d.ts.map +1 -0
- package/dist/movement/MonsterHome.js +75 -0
- package/dist/movement/MonsterHome.js.map +1 -0
- package/dist/movement/PatrolRoute.d.ts +99 -0
- package/dist/movement/PatrolRoute.d.ts.map +1 -0
- package/dist/movement/PatrolRoute.js +141 -0
- package/dist/movement/PatrolRoute.js.map +1 -0
- package/dist/movement/index.d.ts +5 -0
- package/dist/movement/index.d.ts.map +1 -0
- package/dist/movement/index.js +4 -0
- package/dist/movement/index.js.map +1 -0
- package/dist/navigation/LevelGraph.d.ts +78 -0
- package/dist/navigation/LevelGraph.d.ts.map +1 -0
- package/dist/navigation/LevelGraph.js +268 -0
- package/dist/navigation/LevelGraph.js.map +1 -0
- package/dist/navigation/NPCGraphMover.d.ts +87 -0
- package/dist/navigation/NPCGraphMover.d.ts.map +1 -0
- package/dist/navigation/NPCGraphMover.js +193 -0
- package/dist/navigation/NPCGraphMover.js.map +1 -0
- package/dist/navigation/index.d.ts +5 -0
- package/dist/navigation/index.d.ts.map +1 -0
- package/dist/navigation/index.js +4 -0
- package/dist/navigation/index.js.map +1 -0
- package/dist/plugins/AnomaliesPlugin.d.ts +26 -0
- package/dist/plugins/AnomaliesPlugin.d.ts.map +1 -0
- package/dist/plugins/AnomaliesPlugin.js +30 -0
- package/dist/plugins/AnomaliesPlugin.js.map +1 -0
- package/dist/plugins/CombatSchemaPlugin.d.ts +35 -0
- package/dist/plugins/CombatSchemaPlugin.d.ts.map +1 -0
- package/dist/plugins/CombatSchemaPlugin.js +44 -0
- package/dist/plugins/CombatSchemaPlugin.js.map +1 -0
- package/dist/plugins/FactionsPlugin.d.ts +26 -0
- package/dist/plugins/FactionsPlugin.d.ts.map +1 -0
- package/dist/plugins/FactionsPlugin.js +30 -0
- package/dist/plugins/FactionsPlugin.js.map +1 -0
- package/dist/plugins/IALifePlugin.d.ts +91 -0
- package/dist/plugins/IALifePlugin.d.ts.map +1 -0
- package/dist/plugins/IALifePlugin.js +2 -0
- package/dist/plugins/IALifePlugin.js.map +1 -0
- package/dist/plugins/MonstersPlugin.d.ts +26 -0
- package/dist/plugins/MonstersPlugin.d.ts.map +1 -0
- package/dist/plugins/MonstersPlugin.js +30 -0
- package/dist/plugins/MonstersPlugin.js.map +1 -0
- package/dist/plugins/NPCTypesPlugin.d.ts +26 -0
- package/dist/plugins/NPCTypesPlugin.d.ts.map +1 -0
- package/dist/plugins/NPCTypesPlugin.js +30 -0
- package/dist/plugins/NPCTypesPlugin.js.map +1 -0
- package/dist/plugins/PluginToken.d.ts +26 -0
- package/dist/plugins/PluginToken.d.ts.map +1 -0
- package/dist/plugins/PluginToken.js +22 -0
- package/dist/plugins/PluginToken.js.map +1 -0
- package/dist/plugins/SocialPlugin.d.ts +14 -0
- package/dist/plugins/SocialPlugin.d.ts.map +1 -0
- package/dist/plugins/SocialPlugin.js +16 -0
- package/dist/plugins/SocialPlugin.js.map +1 -0
- package/dist/plugins/SpawnPlugin.d.ts +15 -0
- package/dist/plugins/SpawnPlugin.d.ts.map +1 -0
- package/dist/plugins/SpawnPlugin.js +26 -0
- package/dist/plugins/SpawnPlugin.js.map +1 -0
- package/dist/plugins/SquadPlugin.d.ts +14 -0
- package/dist/plugins/SquadPlugin.d.ts.map +1 -0
- package/dist/plugins/SquadPlugin.js +16 -0
- package/dist/plugins/SquadPlugin.js.map +1 -0
- package/dist/plugins/SurgePlugin.d.ts +20 -0
- package/dist/plugins/SurgePlugin.d.ts.map +1 -0
- package/dist/plugins/SurgePlugin.js +22 -0
- package/dist/plugins/SurgePlugin.js.map +1 -0
- package/dist/plugins/TradePlugin.d.ts +16 -0
- package/dist/plugins/TradePlugin.d.ts.map +1 -0
- package/dist/plugins/TradePlugin.js +18 -0
- package/dist/plugins/TradePlugin.js.map +1 -0
- package/dist/plugins/index.d.ts +11 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +10 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins/pluginNames.d.ts +37 -0
- package/dist/plugins/pluginNames.d.ts.map +1 -0
- package/dist/plugins/pluginNames.js +28 -0
- package/dist/plugins/pluginNames.js.map +1 -0
- package/dist/plugins/presets.d.ts +31 -0
- package/dist/plugins/presets.d.ts.map +1 -0
- package/dist/plugins/presets.js +50 -0
- package/dist/plugins/presets.js.map +1 -0
- package/dist/ports/IDataLoader.d.ts +38 -0
- package/dist/ports/IDataLoader.d.ts.map +1 -0
- package/dist/ports/IDataLoader.js +12 -0
- package/dist/ports/IDataLoader.js.map +1 -0
- package/dist/ports/IEntityAdapter.d.ts +73 -0
- package/dist/ports/IEntityAdapter.d.ts.map +1 -0
- package/dist/ports/IEntityAdapter.js +36 -0
- package/dist/ports/IEntityAdapter.js.map +1 -0
- package/dist/ports/IEntityFactory.d.ts +66 -0
- package/dist/ports/IEntityFactory.d.ts.map +1 -0
- package/dist/ports/IEntityFactory.js +21 -0
- package/dist/ports/IEntityFactory.js.map +1 -0
- package/dist/ports/ILogger.d.ts +29 -0
- package/dist/ports/ILogger.d.ts.map +1 -0
- package/dist/ports/ILogger.js +2 -0
- package/dist/ports/ILogger.js.map +1 -0
- package/dist/ports/IPlayerPositionProvider.d.ts +20 -0
- package/dist/ports/IPlayerPositionProvider.d.ts.map +1 -0
- package/dist/ports/IPlayerPositionProvider.js +11 -0
- package/dist/ports/IPlayerPositionProvider.js.map +1 -0
- package/dist/ports/IRandom.d.ts +25 -0
- package/dist/ports/IRandom.d.ts.map +1 -0
- package/dist/ports/IRandom.js +39 -0
- package/dist/ports/IRandom.js.map +1 -0
- package/dist/ports/IRuntimeClock.d.ts +18 -0
- package/dist/ports/IRuntimeClock.d.ts.map +1 -0
- package/dist/ports/IRuntimeClock.js +2 -0
- package/dist/ports/IRuntimeClock.js.map +1 -0
- package/dist/ports/index.d.ts +12 -0
- package/dist/ports/index.d.ts.map +1 -0
- package/dist/ports/index.js +5 -0
- package/dist/ports/index.js.map +1 -0
- package/dist/registry/AIStateRegistry.d.ts +42 -0
- package/dist/registry/AIStateRegistry.d.ts.map +1 -0
- package/dist/registry/AIStateRegistry.js +27 -0
- package/dist/registry/AIStateRegistry.js.map +1 -0
- package/dist/registry/AnomalyTypeRegistry.d.ts +21 -0
- package/dist/registry/AnomalyTypeRegistry.d.ts.map +1 -0
- package/dist/registry/AnomalyTypeRegistry.js +20 -0
- package/dist/registry/AnomalyTypeRegistry.js.map +1 -0
- package/dist/registry/BehaviorSchemeRegistry.d.ts +21 -0
- package/dist/registry/BehaviorSchemeRegistry.d.ts.map +1 -0
- package/dist/registry/BehaviorSchemeRegistry.js +24 -0
- package/dist/registry/BehaviorSchemeRegistry.js.map +1 -0
- package/dist/registry/DamageTypeRegistry.d.ts +17 -0
- package/dist/registry/DamageTypeRegistry.d.ts.map +1 -0
- package/dist/registry/DamageTypeRegistry.js +24 -0
- package/dist/registry/DamageTypeRegistry.js.map +1 -0
- package/dist/registry/FactionRegistry.d.ts +41 -0
- package/dist/registry/FactionRegistry.d.ts.map +1 -0
- package/dist/registry/FactionRegistry.js +29 -0
- package/dist/registry/FactionRegistry.js.map +1 -0
- package/dist/registry/MonsterRegistry.d.ts +44 -0
- package/dist/registry/MonsterRegistry.d.ts.map +1 -0
- package/dist/registry/MonsterRegistry.js +43 -0
- package/dist/registry/MonsterRegistry.js.map +1 -0
- package/dist/registry/NPCTypeRegistry.d.ts +34 -0
- package/dist/registry/NPCTypeRegistry.d.ts.map +1 -0
- package/dist/registry/NPCTypeRegistry.js +20 -0
- package/dist/registry/NPCTypeRegistry.js.map +1 -0
- package/dist/registry/Registry.d.ts +44 -0
- package/dist/registry/Registry.d.ts.map +1 -0
- package/dist/registry/Registry.js +80 -0
- package/dist/registry/Registry.js.map +1 -0
- package/dist/registry/TaskTypeRegistry.d.ts +17 -0
- package/dist/registry/TaskTypeRegistry.d.ts.map +1 -0
- package/dist/registry/TaskTypeRegistry.js +16 -0
- package/dist/registry/TaskTypeRegistry.js.map +1 -0
- package/dist/registry/index.d.ts +19 -0
- package/dist/registry/index.d.ts.map +1 -0
- package/dist/registry/index.js +11 -0
- package/dist/registry/index.js.map +1 -0
- package/dist/schema/index.d.ts +3 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +3 -0
- package/dist/schema/index.js.map +1 -0
- package/dist/schema/validators.d.ts +32 -0
- package/dist/schema/validators.d.ts.map +1 -0
- package/dist/schema/validators.js +249 -0
- package/dist/schema/validators.js.map +1 -0
- package/dist/spawn/SpawnRegistry.d.ts +48 -0
- package/dist/spawn/SpawnRegistry.d.ts.map +1 -0
- package/dist/spawn/SpawnRegistry.js +141 -0
- package/dist/spawn/SpawnRegistry.js.map +1 -0
- package/dist/spawn/index.d.ts +3 -0
- package/dist/spawn/index.d.ts.map +1 -0
- package/dist/spawn/index.js +3 -0
- package/dist/spawn/index.js.map +1 -0
- package/dist/terrain/SmartTerrain.d.ts +119 -0
- package/dist/terrain/SmartTerrain.d.ts.map +1 -0
- package/dist/terrain/SmartTerrain.js +124 -0
- package/dist/terrain/SmartTerrain.js.map +1 -0
- package/dist/terrain/TerrainBuilder.d.ts +44 -0
- package/dist/terrain/TerrainBuilder.d.ts.map +1 -0
- package/dist/terrain/TerrainBuilder.js +112 -0
- package/dist/terrain/TerrainBuilder.js.map +1 -0
- package/dist/terrain/Zone.d.ts +25 -0
- package/dist/terrain/Zone.d.ts.map +1 -0
- package/dist/terrain/Zone.js +29 -0
- package/dist/terrain/Zone.js.map +1 -0
- package/dist/terrain/index.d.ts +6 -0
- package/dist/terrain/index.d.ts.map +1 -0
- package/dist/terrain/index.js +5 -0
- package/dist/terrain/index.js.map +1 -0
- package/dist/time/TimeManager.d.ts +21 -0
- package/dist/time/TimeManager.d.ts.map +1 -0
- package/dist/time/TimeManager.js +41 -0
- package/dist/time/TimeManager.js.map +1 -0
- package/dist/time/index.d.ts +3 -0
- package/dist/time/index.d.ts.map +1 -0
- package/dist/time/index.js +2 -0
- package/dist/time/index.js.map +1 -0
- package/package.json +119 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Route types and tracker for NPC patrol movement.
|
|
3
|
+
*
|
|
4
|
+
* Three route types are supported:
|
|
5
|
+
* LOOP -- A->B->C->A->B->C->... (cyclic, infinite)
|
|
6
|
+
* PING_PONG -- A->B->C->B->A->B->... (reverse at each end, infinite)
|
|
7
|
+
* ONE_WAY -- A->B->C (stop at final waypoint, finite)
|
|
8
|
+
*
|
|
9
|
+
* PatrolRoute is a plain data object with zero runtime dependencies.
|
|
10
|
+
* PatrolRouteTracker is a lightweight stateful cursor over a PatrolRoute.
|
|
11
|
+
*/
|
|
12
|
+
export declare const RouteType: {
|
|
13
|
+
readonly LOOP: "loop";
|
|
14
|
+
readonly PING_PONG: "ping_pong";
|
|
15
|
+
readonly ONE_WAY: "one_way";
|
|
16
|
+
};
|
|
17
|
+
export type RouteType = (typeof RouteType)[keyof typeof RouteType] | (string & {});
|
|
18
|
+
/** A single world-space position in a patrol route. */
|
|
19
|
+
export interface IPatrolWaypoint {
|
|
20
|
+
readonly x: number;
|
|
21
|
+
readonly y: number;
|
|
22
|
+
/** Milliseconds to pause at this waypoint before advancing. */
|
|
23
|
+
readonly waitTime?: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* An ordered sequence of waypoints defining a patrol path.
|
|
27
|
+
*
|
|
28
|
+
* PatrolRoute instances are stored on SmartTerrain and shared among all
|
|
29
|
+
* NPCs assigned to that terrain -- they are treated as immutable. Each NPC
|
|
30
|
+
* holds its own PatrolRouteTracker (a mutable cursor over the shared route).
|
|
31
|
+
*/
|
|
32
|
+
export interface PatrolRoute {
|
|
33
|
+
/** Unique route identifier within the terrain. */
|
|
34
|
+
readonly id: string;
|
|
35
|
+
/** ID of the SmartTerrain this route belongs to. */
|
|
36
|
+
readonly terrainId: string;
|
|
37
|
+
/** Ordered list of world-space positions. Must have at least 1 entry. */
|
|
38
|
+
readonly waypoints: readonly IPatrolWaypoint[];
|
|
39
|
+
/** How the NPC cycles through the waypoints. */
|
|
40
|
+
readonly routeType: RouteType;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Custom route advancement function.
|
|
44
|
+
*
|
|
45
|
+
* Called by PatrolRouteTracker.advance() when a custom advancer is provided.
|
|
46
|
+
* Should return the new index, direction, and whether the route is completed.
|
|
47
|
+
*/
|
|
48
|
+
export type RouteAdvancer = (currentIndex: number, waypointCount: number, direction: 1 | -1) => {
|
|
49
|
+
index: number;
|
|
50
|
+
direction: 1 | -1;
|
|
51
|
+
completed: boolean;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Tracks an NPC's position along a PatrolRoute.
|
|
55
|
+
*
|
|
56
|
+
* One tracker is created per (NPC, route) pair. The tracker is stored on
|
|
57
|
+
* the entity in online AI and in offline data structures. Memory footprint
|
|
58
|
+
* is minimal: three primitive fields plus one object reference.
|
|
59
|
+
*/
|
|
60
|
+
export declare class PatrolRouteTracker {
|
|
61
|
+
private readonly route;
|
|
62
|
+
private currentIndex;
|
|
63
|
+
/** +1 = forward, -1 = backward (used by PING_PONG). */
|
|
64
|
+
private direction;
|
|
65
|
+
/** Remaining wait time at current waypoint in milliseconds. */
|
|
66
|
+
private waitRemaining;
|
|
67
|
+
/** True when a ONE_WAY route has delivered its final waypoint. */
|
|
68
|
+
private completed;
|
|
69
|
+
/** Optional custom advancer that overrides built-in route type logic. */
|
|
70
|
+
private readonly customAdvancer?;
|
|
71
|
+
constructor(route: PatrolRoute, customAdvancer?: RouteAdvancer);
|
|
72
|
+
/** The waypoint the NPC is currently heading toward. */
|
|
73
|
+
get currentWaypoint(): IPatrolWaypoint;
|
|
74
|
+
/**
|
|
75
|
+
* True only for ONE_WAY routes once the final waypoint has been delivered.
|
|
76
|
+
* Always false for LOOP and PING_PONG routes.
|
|
77
|
+
*/
|
|
78
|
+
get isComplete(): boolean;
|
|
79
|
+
/** Total number of waypoints in the underlying route. */
|
|
80
|
+
get waypointCount(): number;
|
|
81
|
+
/**
|
|
82
|
+
* Advance to the next waypoint. Handles LOOP / PING_PONG / ONE_WAY.
|
|
83
|
+
*
|
|
84
|
+
* If the current waypoint has a waitTime, the wait timer is initialised.
|
|
85
|
+
* For ONE_WAY routes that have already completed, this is a no-op.
|
|
86
|
+
*/
|
|
87
|
+
advance(): void;
|
|
88
|
+
/**
|
|
89
|
+
* Tick the wait timer. Returns true when the wait is over (or if there
|
|
90
|
+
* was no wait to begin with), signalling that the NPC may start moving
|
|
91
|
+
* to the next waypoint.
|
|
92
|
+
*
|
|
93
|
+
* @param deltaMs - Milliseconds elapsed since the last tick.
|
|
94
|
+
*/
|
|
95
|
+
tickWait(deltaMs: number): boolean;
|
|
96
|
+
/** Reset the tracker to the first waypoint and clear completion state. */
|
|
97
|
+
reset(): void;
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=PatrolRoute.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PatrolRoute.d.ts","sourceRoot":"","sources":["../../src/movement/PatrolRoute.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,eAAO,MAAM,SAAS;;;;CAIZ,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,OAAO,SAAS,CAAC,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAMnF,uDAAuD;AACvD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,+DAA+D;IAC/D,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAMD;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,kDAAkD;IAClD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,oDAAoD;IACpD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,yEAAyE;IACzE,QAAQ,CAAC,SAAS,EAAE,SAAS,eAAe,EAAE,CAAC;IAC/C,gDAAgD;IAChD,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;CAC/B;AAMD;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,CAC1B,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,CAAC,GAAG,CAAC,CAAC,KACd;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC;AAM9D;;;;;;GAMG;AACH,qBAAa,kBAAkB;IAYjB,OAAO,CAAC,QAAQ,CAAC,KAAK;IAXlC,OAAO,CAAC,YAAY,CAAS;IAC7B,uDAAuD;IACvD,OAAO,CAAC,SAAS,CAAa;IAC9B,+DAA+D;IAC/D,OAAO,CAAC,aAAa,CAAK;IAC1B,kEAAkE;IAClE,OAAO,CAAC,SAAS,CAAS;IAC1B,yEAAyE;IACzE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAgB;gBAEpC,KAAK,EAAE,WAAW,EAAE,cAAc,CAAC,EAAE,aAAa;IAU9D,wDAAwD;IACxD,IAAI,eAAe,IAAI,eAAe,CAErC;IAED;;;OAGG;IACH,IAAI,UAAU,IAAI,OAAO,CAExB;IAED,yDAAyD;IACzD,IAAI,aAAa,IAAI,MAAM,CAE1B;IAMD;;;;;OAKG;IACH,OAAO,IAAI,IAAI;IAqDf;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAOlC,0EAA0E;IAC1E,KAAK,IAAI,IAAI;CAMd"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Route types and tracker for NPC patrol movement.
|
|
3
|
+
*
|
|
4
|
+
* Three route types are supported:
|
|
5
|
+
* LOOP -- A->B->C->A->B->C->... (cyclic, infinite)
|
|
6
|
+
* PING_PONG -- A->B->C->B->A->B->... (reverse at each end, infinite)
|
|
7
|
+
* ONE_WAY -- A->B->C (stop at final waypoint, finite)
|
|
8
|
+
*
|
|
9
|
+
* PatrolRoute is a plain data object with zero runtime dependencies.
|
|
10
|
+
* PatrolRouteTracker is a lightweight stateful cursor over a PatrolRoute.
|
|
11
|
+
*/
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
// Route type
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
export const RouteType = {
|
|
16
|
+
LOOP: 'loop',
|
|
17
|
+
PING_PONG: 'ping_pong',
|
|
18
|
+
ONE_WAY: 'one_way',
|
|
19
|
+
};
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
// PatrolRouteTracker (stateful cursor)
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
/**
|
|
24
|
+
* Tracks an NPC's position along a PatrolRoute.
|
|
25
|
+
*
|
|
26
|
+
* One tracker is created per (NPC, route) pair. The tracker is stored on
|
|
27
|
+
* the entity in online AI and in offline data structures. Memory footprint
|
|
28
|
+
* is minimal: three primitive fields plus one object reference.
|
|
29
|
+
*/
|
|
30
|
+
export class PatrolRouteTracker {
|
|
31
|
+
constructor(route, customAdvancer) {
|
|
32
|
+
this.route = route;
|
|
33
|
+
/** +1 = forward, -1 = backward (used by PING_PONG). */
|
|
34
|
+
this.direction = 1;
|
|
35
|
+
/** Remaining wait time at current waypoint in milliseconds. */
|
|
36
|
+
this.waitRemaining = 0;
|
|
37
|
+
/** True when a ONE_WAY route has delivered its final waypoint. */
|
|
38
|
+
this.completed = false;
|
|
39
|
+
this.currentIndex = 0;
|
|
40
|
+
this.customAdvancer = customAdvancer;
|
|
41
|
+
}
|
|
42
|
+
// -----------------------------------------------------------------------
|
|
43
|
+
// Accessors
|
|
44
|
+
// -----------------------------------------------------------------------
|
|
45
|
+
/** The waypoint the NPC is currently heading toward. */
|
|
46
|
+
get currentWaypoint() {
|
|
47
|
+
return this.route.waypoints[this.currentIndex];
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* True only for ONE_WAY routes once the final waypoint has been delivered.
|
|
51
|
+
* Always false for LOOP and PING_PONG routes.
|
|
52
|
+
*/
|
|
53
|
+
get isComplete() {
|
|
54
|
+
return this.completed;
|
|
55
|
+
}
|
|
56
|
+
/** Total number of waypoints in the underlying route. */
|
|
57
|
+
get waypointCount() {
|
|
58
|
+
return this.route.waypoints.length;
|
|
59
|
+
}
|
|
60
|
+
// -----------------------------------------------------------------------
|
|
61
|
+
// Mutation API
|
|
62
|
+
// -----------------------------------------------------------------------
|
|
63
|
+
/**
|
|
64
|
+
* Advance to the next waypoint. Handles LOOP / PING_PONG / ONE_WAY.
|
|
65
|
+
*
|
|
66
|
+
* If the current waypoint has a waitTime, the wait timer is initialised.
|
|
67
|
+
* For ONE_WAY routes that have already completed, this is a no-op.
|
|
68
|
+
*/
|
|
69
|
+
advance() {
|
|
70
|
+
if (this.completed)
|
|
71
|
+
return;
|
|
72
|
+
const len = this.route.waypoints.length;
|
|
73
|
+
if (len <= 1) {
|
|
74
|
+
if (this.route.routeType === RouteType.ONE_WAY) {
|
|
75
|
+
this.completed = true;
|
|
76
|
+
}
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
if (this.customAdvancer) {
|
|
80
|
+
const result = this.customAdvancer(this.currentIndex, len, this.direction);
|
|
81
|
+
this.currentIndex = Math.max(0, Math.min(result.index, len - 1));
|
|
82
|
+
this.direction = result.direction;
|
|
83
|
+
this.completed = result.completed;
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
switch (this.route.routeType) {
|
|
87
|
+
case RouteType.LOOP:
|
|
88
|
+
this.currentIndex = (this.currentIndex + 1) % len;
|
|
89
|
+
break;
|
|
90
|
+
case RouteType.PING_PONG: {
|
|
91
|
+
const next = this.currentIndex + this.direction;
|
|
92
|
+
if (next >= len) {
|
|
93
|
+
this.direction = -1;
|
|
94
|
+
this.currentIndex = len - 2;
|
|
95
|
+
}
|
|
96
|
+
else if (next < 0) {
|
|
97
|
+
this.direction = 1;
|
|
98
|
+
this.currentIndex = 1;
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
this.currentIndex = next;
|
|
102
|
+
}
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
case RouteType.ONE_WAY:
|
|
106
|
+
if (this.currentIndex < len - 1) {
|
|
107
|
+
this.currentIndex += 1;
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
this.completed = true;
|
|
111
|
+
}
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
const wp = this.route.waypoints[this.currentIndex];
|
|
116
|
+
if (wp.waitTime !== undefined && wp.waitTime > 0) {
|
|
117
|
+
this.waitRemaining = wp.waitTime;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Tick the wait timer. Returns true when the wait is over (or if there
|
|
122
|
+
* was no wait to begin with), signalling that the NPC may start moving
|
|
123
|
+
* to the next waypoint.
|
|
124
|
+
*
|
|
125
|
+
* @param deltaMs - Milliseconds elapsed since the last tick.
|
|
126
|
+
*/
|
|
127
|
+
tickWait(deltaMs) {
|
|
128
|
+
if (this.waitRemaining <= 0)
|
|
129
|
+
return true;
|
|
130
|
+
this.waitRemaining -= deltaMs;
|
|
131
|
+
return this.waitRemaining <= 0;
|
|
132
|
+
}
|
|
133
|
+
/** Reset the tracker to the first waypoint and clear completion state. */
|
|
134
|
+
reset() {
|
|
135
|
+
this.currentIndex = 0;
|
|
136
|
+
this.direction = 1;
|
|
137
|
+
this.waitRemaining = 0;
|
|
138
|
+
this.completed = false;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=PatrolRoute.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PatrolRoute.js","sourceRoot":"","sources":["../../src/movement/PatrolRoute.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/movement/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC9D,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/movement/index.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAC3B,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE9D,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
export interface IGraphVertex {
|
|
2
|
+
readonly id: string;
|
|
3
|
+
readonly x: number;
|
|
4
|
+
readonly y: number;
|
|
5
|
+
/** Terrain/location tags for path filtering (e.g. 'outdoor', 'indoor', 'danger') */
|
|
6
|
+
readonly tags: ReadonlyArray<string>;
|
|
7
|
+
}
|
|
8
|
+
export interface IGraphEdge {
|
|
9
|
+
readonly to: string;
|
|
10
|
+
readonly weight: number;
|
|
11
|
+
}
|
|
12
|
+
export interface ILevelGraphState {
|
|
13
|
+
vertices: Array<{
|
|
14
|
+
id: string;
|
|
15
|
+
x: number;
|
|
16
|
+
y: number;
|
|
17
|
+
tags: string[];
|
|
18
|
+
}>;
|
|
19
|
+
edges: Array<{
|
|
20
|
+
from: string;
|
|
21
|
+
edges: Array<{
|
|
22
|
+
to: string;
|
|
23
|
+
weight: number;
|
|
24
|
+
}>;
|
|
25
|
+
}>;
|
|
26
|
+
}
|
|
27
|
+
/** Predicate to filter which vertices an NPC can traverse */
|
|
28
|
+
export type TerrainFilter = (vertex: IGraphVertex) => boolean;
|
|
29
|
+
export declare class LevelGraph {
|
|
30
|
+
private readonly _vertices;
|
|
31
|
+
private readonly _edges;
|
|
32
|
+
/** Add a vertex. Overwrites if ID already exists. */
|
|
33
|
+
addVertex(id: string, x: number, y: number, tags?: string[]): this;
|
|
34
|
+
/** Add a directed edge from → to. Weight defaults to Euclidean distance. */
|
|
35
|
+
addEdge(from: string, to: string, weight?: number): this;
|
|
36
|
+
/** Add an undirected edge (both directions). */
|
|
37
|
+
addUndirectedEdge(a: string, b: string, weight?: number): this;
|
|
38
|
+
getVertex(id: string): IGraphVertex | undefined;
|
|
39
|
+
getEdges(fromId: string): ReadonlyArray<IGraphEdge>;
|
|
40
|
+
get vertexCount(): number;
|
|
41
|
+
get edgeCount(): number;
|
|
42
|
+
/** Check if a vertex exists. */
|
|
43
|
+
hasVertex(id: string): boolean;
|
|
44
|
+
/** Returns all vertex IDs. */
|
|
45
|
+
vertexIds(): IterableIterator<string>;
|
|
46
|
+
/** Returns an iterator over all IGraphVertex values. */
|
|
47
|
+
vertices(): IterableIterator<IGraphVertex>;
|
|
48
|
+
/** Remove a vertex, all its outgoing edges, and all incoming edges from other vertices. */
|
|
49
|
+
removeVertex(id: string): this;
|
|
50
|
+
/**
|
|
51
|
+
* A* pathfinding using a binary min-heap for O(log n) open-set operations.
|
|
52
|
+
*
|
|
53
|
+
* Returns an array of vertex IDs from start to goal (inclusive), or null
|
|
54
|
+
* if no path exists.
|
|
55
|
+
*
|
|
56
|
+
* @param filter - Optional predicate; vertices returning false are skipped.
|
|
57
|
+
* The start and goal vertices are never filtered out.
|
|
58
|
+
*/
|
|
59
|
+
findPath(startId: string, goalId: string, filter?: TerrainFilter): string[] | null;
|
|
60
|
+
/**
|
|
61
|
+
* Linear interpolation of world position along an edge.
|
|
62
|
+
* t = 0 → fromVertex position, t = 1 → toVertex position.
|
|
63
|
+
*/
|
|
64
|
+
interpolatePosition(fromId: string, toId: string, t: number): {
|
|
65
|
+
x: number;
|
|
66
|
+
y: number;
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Get edge weight between two directly connected vertices.
|
|
70
|
+
* Returns Infinity if no direct edge exists.
|
|
71
|
+
*/
|
|
72
|
+
edgeWeight(fromId: string, toId: string): number;
|
|
73
|
+
/** Serialize graph state for save/load. */
|
|
74
|
+
serialize(): ILevelGraphState;
|
|
75
|
+
/** Restore a LevelGraph from serialized state (skips weight recalculation). */
|
|
76
|
+
static restore(state: ILevelGraphState): LevelGraph;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=LevelGraph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LevelGraph.d.ts","sourceRoot":"","sources":["../../src/navigation/LevelGraph.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,oFAAoF;IACpF,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAMD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IACtE,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,KAAK,CAAC;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC,CAAC;CAC9E;AAED,6DAA6D;AAC7D,MAAM,MAAM,aAAa,GAAG,CAAC,MAAM,EAAE,YAAY,KAAK,OAAO,CAAC;AAiE9D,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAmC;IAC7D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsC;IAM7D,qDAAqD;IACrD,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,EAAO,GAAG,IAAI;IAMtE,4EAA4E;IAC5E,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IASxD,gDAAgD;IAChD,iBAAiB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IAU9D,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAI/C,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,CAAC,UAAU,CAAC;IAInD,IAAI,WAAW,IAAI,MAAM,CAAgC;IAEzD,IAAI,SAAS,IAAI,MAAM,CAItB;IAED,gCAAgC;IAChC,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAI9B,8BAA8B;IAC9B,SAAS,IAAI,gBAAgB,CAAC,MAAM,CAAC;IAIrC,wDAAwD;IACxD,QAAQ,IAAI,gBAAgB,CAAC,YAAY,CAAC;IAQ1C,2FAA2F;IAC3F,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAgB9B;;;;;;;;OAQG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,MAAM,EAAE,GAAG,IAAI;IAoElF;;;OAGG;IACH,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE;IAWtF;;;OAGG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM;IAWhD,2CAA2C;IAC3C,SAAS,IAAI,gBAAgB;IAe7B,+EAA+E;IAC/E,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,gBAAgB,GAAG,UAAU;CAepD"}
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
// navigation/LevelGraph.ts
|
|
2
|
+
// Abstract 2D waypoint graph for offline NPC navigation.
|
|
3
|
+
//
|
|
4
|
+
// Vertices = named waypoints with (x, y) position and optional terrain tags.
|
|
5
|
+
// Edges = directed connections with distance weight.
|
|
6
|
+
// Path = A* search returning array of vertex IDs.
|
|
7
|
+
/** Compact binary min-heap over HeapEntry sorted by f score. */
|
|
8
|
+
class MinHeap {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.data = [];
|
|
11
|
+
}
|
|
12
|
+
get size() { return this.data.length; }
|
|
13
|
+
push(entry) {
|
|
14
|
+
this.data.push(entry);
|
|
15
|
+
this._bubbleUp(this.data.length - 1);
|
|
16
|
+
}
|
|
17
|
+
pop() {
|
|
18
|
+
if (this.data.length === 0)
|
|
19
|
+
return undefined;
|
|
20
|
+
const top = this.data[0];
|
|
21
|
+
const last = this.data.pop();
|
|
22
|
+
if (this.data.length > 0) {
|
|
23
|
+
this.data[0] = last;
|
|
24
|
+
this._sinkDown(0);
|
|
25
|
+
}
|
|
26
|
+
return top;
|
|
27
|
+
}
|
|
28
|
+
_bubbleUp(i) {
|
|
29
|
+
while (i > 0) {
|
|
30
|
+
const parent = (i - 1) >> 1;
|
|
31
|
+
if (this.data[parent].f <= this.data[i].f)
|
|
32
|
+
break;
|
|
33
|
+
const tmp = this.data[parent];
|
|
34
|
+
this.data[parent] = this.data[i];
|
|
35
|
+
this.data[i] = tmp;
|
|
36
|
+
i = parent;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
_sinkDown(i) {
|
|
40
|
+
const n = this.data.length;
|
|
41
|
+
for (;;) {
|
|
42
|
+
let smallest = i;
|
|
43
|
+
const l = 2 * i + 1;
|
|
44
|
+
const r = 2 * i + 2;
|
|
45
|
+
if (l < n && this.data[l].f < this.data[smallest].f)
|
|
46
|
+
smallest = l;
|
|
47
|
+
if (r < n && this.data[r].f < this.data[smallest].f)
|
|
48
|
+
smallest = r;
|
|
49
|
+
if (smallest === i)
|
|
50
|
+
break;
|
|
51
|
+
const tmp = this.data[smallest];
|
|
52
|
+
this.data[smallest] = this.data[i];
|
|
53
|
+
this.data[i] = tmp;
|
|
54
|
+
i = smallest;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// ---------------------------------------------------------------------------
|
|
59
|
+
// LevelGraph
|
|
60
|
+
// ---------------------------------------------------------------------------
|
|
61
|
+
export class LevelGraph {
|
|
62
|
+
constructor() {
|
|
63
|
+
this._vertices = new Map();
|
|
64
|
+
this._edges = new Map();
|
|
65
|
+
}
|
|
66
|
+
// -------------------------------------------------------------------------
|
|
67
|
+
// Graph construction
|
|
68
|
+
// -------------------------------------------------------------------------
|
|
69
|
+
/** Add a vertex. Overwrites if ID already exists. */
|
|
70
|
+
addVertex(id, x, y, tags = []) {
|
|
71
|
+
this._vertices.set(id, { id, x, y, tags });
|
|
72
|
+
if (!this._edges.has(id))
|
|
73
|
+
this._edges.set(id, []);
|
|
74
|
+
return this;
|
|
75
|
+
}
|
|
76
|
+
/** Add a directed edge from → to. Weight defaults to Euclidean distance. */
|
|
77
|
+
addEdge(from, to, weight) {
|
|
78
|
+
const src = this._vertices.get(from);
|
|
79
|
+
const dst = this._vertices.get(to);
|
|
80
|
+
if (!src || !dst)
|
|
81
|
+
return this;
|
|
82
|
+
const w = weight ?? Math.sqrt((dst.x - src.x) ** 2 + (dst.y - src.y) ** 2);
|
|
83
|
+
this._edges.get(from).push({ to, weight: w });
|
|
84
|
+
return this;
|
|
85
|
+
}
|
|
86
|
+
/** Add an undirected edge (both directions). */
|
|
87
|
+
addUndirectedEdge(a, b, weight) {
|
|
88
|
+
this.addEdge(a, b, weight);
|
|
89
|
+
this.addEdge(b, a, weight);
|
|
90
|
+
return this;
|
|
91
|
+
}
|
|
92
|
+
// -------------------------------------------------------------------------
|
|
93
|
+
// Accessors
|
|
94
|
+
// -------------------------------------------------------------------------
|
|
95
|
+
getVertex(id) {
|
|
96
|
+
return this._vertices.get(id);
|
|
97
|
+
}
|
|
98
|
+
getEdges(fromId) {
|
|
99
|
+
return this._edges.get(fromId) ?? [];
|
|
100
|
+
}
|
|
101
|
+
get vertexCount() { return this._vertices.size; }
|
|
102
|
+
get edgeCount() {
|
|
103
|
+
let n = 0;
|
|
104
|
+
for (const edges of this._edges.values())
|
|
105
|
+
n += edges.length;
|
|
106
|
+
return n;
|
|
107
|
+
}
|
|
108
|
+
/** Check if a vertex exists. */
|
|
109
|
+
hasVertex(id) {
|
|
110
|
+
return this._vertices.has(id);
|
|
111
|
+
}
|
|
112
|
+
/** Returns all vertex IDs. */
|
|
113
|
+
vertexIds() {
|
|
114
|
+
return this._vertices.keys();
|
|
115
|
+
}
|
|
116
|
+
/** Returns an iterator over all IGraphVertex values. */
|
|
117
|
+
vertices() {
|
|
118
|
+
return this._vertices.values();
|
|
119
|
+
}
|
|
120
|
+
// -------------------------------------------------------------------------
|
|
121
|
+
// Mutation
|
|
122
|
+
// -------------------------------------------------------------------------
|
|
123
|
+
/** Remove a vertex, all its outgoing edges, and all incoming edges from other vertices. */
|
|
124
|
+
removeVertex(id) {
|
|
125
|
+
this._vertices.delete(id);
|
|
126
|
+
this._edges.delete(id);
|
|
127
|
+
// Remove all incoming edges pointing to `id`
|
|
128
|
+
for (const edges of this._edges.values()) {
|
|
129
|
+
for (let i = edges.length - 1; i >= 0; i--) {
|
|
130
|
+
if (edges[i].to === id)
|
|
131
|
+
edges.splice(i, 1);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return this;
|
|
135
|
+
}
|
|
136
|
+
// -------------------------------------------------------------------------
|
|
137
|
+
// Pathfinding
|
|
138
|
+
// -------------------------------------------------------------------------
|
|
139
|
+
/**
|
|
140
|
+
* A* pathfinding using a binary min-heap for O(log n) open-set operations.
|
|
141
|
+
*
|
|
142
|
+
* Returns an array of vertex IDs from start to goal (inclusive), or null
|
|
143
|
+
* if no path exists.
|
|
144
|
+
*
|
|
145
|
+
* @param filter - Optional predicate; vertices returning false are skipped.
|
|
146
|
+
* The start and goal vertices are never filtered out.
|
|
147
|
+
*/
|
|
148
|
+
findPath(startId, goalId, filter) {
|
|
149
|
+
if (startId === goalId)
|
|
150
|
+
return [startId];
|
|
151
|
+
if (!this._vertices.has(startId) || !this._vertices.has(goalId))
|
|
152
|
+
return null;
|
|
153
|
+
const goal = this._vertices.get(goalId);
|
|
154
|
+
const heuristic = (id) => {
|
|
155
|
+
const v = this._vertices.get(id);
|
|
156
|
+
const dx = v.x - goal.x;
|
|
157
|
+
const dy = v.y - goal.y;
|
|
158
|
+
return Math.sqrt(dx * dx + dy * dy);
|
|
159
|
+
};
|
|
160
|
+
const gScore = new Map();
|
|
161
|
+
const cameFrom = new Map();
|
|
162
|
+
const closedSet = new Set();
|
|
163
|
+
const heap = new MinHeap();
|
|
164
|
+
gScore.set(startId, 0);
|
|
165
|
+
heap.push({ id: startId, f: heuristic(startId) });
|
|
166
|
+
while (heap.size > 0) {
|
|
167
|
+
const { id: current } = heap.pop();
|
|
168
|
+
if (current === goalId) {
|
|
169
|
+
// Reconstruct path — push+reverse is O(n) vs unshift which is O(n²)
|
|
170
|
+
const path = [];
|
|
171
|
+
let node = goalId;
|
|
172
|
+
while (node !== undefined) {
|
|
173
|
+
path.push(node);
|
|
174
|
+
node = cameFrom.get(node);
|
|
175
|
+
}
|
|
176
|
+
path.reverse();
|
|
177
|
+
return path;
|
|
178
|
+
}
|
|
179
|
+
if (closedSet.has(current))
|
|
180
|
+
continue;
|
|
181
|
+
closedSet.add(current);
|
|
182
|
+
const edges = this._edges.get(current);
|
|
183
|
+
if (!edges)
|
|
184
|
+
continue;
|
|
185
|
+
for (const edge of edges) {
|
|
186
|
+
if (closedSet.has(edge.to))
|
|
187
|
+
continue;
|
|
188
|
+
const dst = this._vertices.get(edge.to);
|
|
189
|
+
if (!dst)
|
|
190
|
+
continue;
|
|
191
|
+
// Start and goal are never filtered
|
|
192
|
+
if (filter && edge.to !== goalId && !filter(dst))
|
|
193
|
+
continue;
|
|
194
|
+
const tentativeG = (gScore.get(current) ?? Infinity) + edge.weight;
|
|
195
|
+
if (tentativeG < (gScore.get(edge.to) ?? Infinity)) {
|
|
196
|
+
cameFrom.set(edge.to, current);
|
|
197
|
+
gScore.set(edge.to, tentativeG);
|
|
198
|
+
heap.push({ id: edge.to, f: tentativeG + heuristic(edge.to) });
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return null; // No path found
|
|
203
|
+
}
|
|
204
|
+
// -------------------------------------------------------------------------
|
|
205
|
+
// Geometry helpers
|
|
206
|
+
// -------------------------------------------------------------------------
|
|
207
|
+
/**
|
|
208
|
+
* Linear interpolation of world position along an edge.
|
|
209
|
+
* t = 0 → fromVertex position, t = 1 → toVertex position.
|
|
210
|
+
*/
|
|
211
|
+
interpolatePosition(fromId, toId, t) {
|
|
212
|
+
const from = this._vertices.get(fromId);
|
|
213
|
+
const to = this._vertices.get(toId);
|
|
214
|
+
if (!from || !to)
|
|
215
|
+
return { x: 0, y: 0 };
|
|
216
|
+
const clamped = Math.max(0, Math.min(1, t));
|
|
217
|
+
return {
|
|
218
|
+
x: from.x + (to.x - from.x) * clamped,
|
|
219
|
+
y: from.y + (to.y - from.y) * clamped,
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Get edge weight between two directly connected vertices.
|
|
224
|
+
* Returns Infinity if no direct edge exists.
|
|
225
|
+
*/
|
|
226
|
+
edgeWeight(fromId, toId) {
|
|
227
|
+
const edges = this._edges.get(fromId);
|
|
228
|
+
if (!edges)
|
|
229
|
+
return Infinity;
|
|
230
|
+
const edge = edges.find(e => e.to === toId);
|
|
231
|
+
return edge?.weight ?? Infinity;
|
|
232
|
+
}
|
|
233
|
+
// -------------------------------------------------------------------------
|
|
234
|
+
// Serialization
|
|
235
|
+
// -------------------------------------------------------------------------
|
|
236
|
+
/** Serialize graph state for save/load. */
|
|
237
|
+
serialize() {
|
|
238
|
+
return {
|
|
239
|
+
vertices: Array.from(this._vertices.values()).map(v => ({
|
|
240
|
+
id: v.id,
|
|
241
|
+
x: v.x,
|
|
242
|
+
y: v.y,
|
|
243
|
+
tags: [...v.tags],
|
|
244
|
+
})),
|
|
245
|
+
edges: Array.from(this._edges.entries()).map(([from, edges]) => ({
|
|
246
|
+
from,
|
|
247
|
+
edges: edges.map(e => ({ to: e.to, weight: e.weight })),
|
|
248
|
+
})),
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
/** Restore a LevelGraph from serialized state (skips weight recalculation). */
|
|
252
|
+
static restore(state) {
|
|
253
|
+
const graph = new LevelGraph();
|
|
254
|
+
for (const v of state.vertices) {
|
|
255
|
+
graph.addVertex(v.id, v.x, v.y, [...v.tags]);
|
|
256
|
+
}
|
|
257
|
+
for (const { from, edges } of state.edges) {
|
|
258
|
+
const list = graph._edges.get(from);
|
|
259
|
+
if (list) {
|
|
260
|
+
for (const e of edges) {
|
|
261
|
+
list.push({ to: e.to, weight: e.weight });
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
return graph;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
//# sourceMappingURL=LevelGraph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LevelGraph.js","sourceRoot":"","sources":["../../src/navigation/LevelGraph.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAC3B,yDAAyD;AACzD,EAAE;AACF,6EAA6E;AAC7E,wDAAwD;AACxD,sDAAsD;AAoCtD,gEAAgE;AAChE,MAAM,OAAO;IAAb;QACmB,SAAI,GAAgB,EAAE,CAAC;IA8C1C,CAAC;IA5CC,IAAI,IAAI,KAAa,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;IAE/C,IAAI,CAAC,KAAgB;QACnB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACtB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACvC,CAAC;IAED,GAAG;QACD,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QAC7C,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACzB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAG,CAAC;QAC9B,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;YACpB,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QACpB,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAEO,SAAS,CAAC,CAAS;QACzB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YACb,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;YAC5B,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;gBAAE,MAAM;YACjD,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC9B,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACjC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;YACnB,CAAC,GAAG,MAAM,CAAC;QACb,CAAC;IACH,CAAC;IAEO,SAAS,CAAC,CAAS;QACzB,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;QAC3B,SAAS,CAAC;YACR,IAAI,QAAQ,GAAG,CAAC,CAAC;YACjB,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACpB,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACpB,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAAE,QAAQ,GAAG,CAAC,CAAC;YAClE,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAAE,QAAQ,GAAG,CAAC,CAAC;YAClE,IAAI,QAAQ,KAAK,CAAC;gBAAE,MAAM;YAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAChC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACnC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;YACnB,CAAC,GAAG,QAAQ,CAAC;QACf,CAAC;IACH,CAAC;CACF;AAED,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E,MAAM,OAAO,UAAU;IAAvB;QACmB,cAAS,GAAG,IAAI,GAAG,EAAwB,CAAC;QAC5C,WAAM,GAAM,IAAI,GAAG,EAAwB,CAAC;IAiO/D,CAAC;IA/NC,4EAA4E;IAC5E,qBAAqB;IACrB,4EAA4E;IAE5E,qDAAqD;IACrD,SAAS,CAAC,EAAU,EAAE,CAAS,EAAE,CAAS,EAAE,OAAiB,EAAE;QAC7D,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3C,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QAClD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,4EAA4E;IAC5E,OAAO,CAAC,IAAY,EAAE,EAAU,EAAE,MAAe;QAC/C,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACnC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAC;QAC9B,MAAM,CAAC,GAAG,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAC3E,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;QAC/C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,gDAAgD;IAChD,iBAAiB,CAAC,CAAS,EAAE,CAAS,EAAE,MAAe;QACrD,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;QAC3B,IAAI,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;QAC3B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,4EAA4E;IAC5E,YAAY;IACZ,4EAA4E;IAE5E,SAAS,CAAC,EAAU;QAClB,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChC,CAAC;IAED,QAAQ,CAAC,MAAc;QACrB,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IACvC,CAAC;IAED,IAAI,WAAW,KAAa,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;IAEzD,IAAI,SAAS;QACX,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;YAAE,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC;QAC5D,OAAO,CAAC,CAAC;IACX,CAAC;IAED,gCAAgC;IAChC,SAAS,CAAC,EAAU;QAClB,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChC,CAAC;IAED,8BAA8B;IAC9B,SAAS;QACP,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;IAC/B,CAAC;IAED,wDAAwD;IACxD,QAAQ;QACN,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC;IACjC,CAAC;IAED,4EAA4E;IAC5E,WAAW;IACX,4EAA4E;IAE5E,2FAA2F;IAC3F,YAAY,CAAC,EAAU;QACrB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC1B,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACvB,6CAA6C;QAC7C,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;YACzC,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC3C,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE;oBAAE,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAC7C,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,4EAA4E;IAC5E,cAAc;IACd,4EAA4E;IAE5E;;;;;;;;OAQG;IACH,QAAQ,CAAC,OAAe,EAAE,MAAc,EAAE,MAAsB;QAC9D,IAAI,OAAO,KAAK,MAAM;YAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QACzC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC;YAAE,OAAO,IAAI,CAAC;QAE7E,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAE,CAAC;QAEzC,MAAM,SAAS,GAAG,CAAC,EAAU,EAAU,EAAE;YACvC,MAAM,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAE,CAAC;YAClC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;YACxB,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;YACxB,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;QACtC,CAAC,CAAC;QAEF,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;QACzC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC;QAC3C,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;QAEpC,MAAM,IAAI,GAAG,IAAI,OAAO,EAAE,CAAC;QAE3B,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACvB,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAElD,OAAO,IAAI,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,EAAG,CAAC;YAEpC,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;gBACvB,oEAAoE;gBACpE,MAAM,IAAI,GAAa,EAAE,CAAC;gBAC1B,IAAI,IAAI,GAAuB,MAAM,CAAC;gBACtC,OAAO,IAAI,KAAK,SAAS,EAAE,CAAC;oBAC1B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBAChB,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBAC5B,CAAC;gBACD,IAAI,CAAC,OAAO,EAAE,CAAC;gBACf,OAAO,IAAI,CAAC;YACd,CAAC;YAED,IAAI,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC;gBAAE,SAAS;YACrC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAEvB,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACvC,IAAI,CAAC,KAAK;gBAAE,SAAS;YAErB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;oBAAE,SAAS;gBAErC,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACxC,IAAI,CAAC,GAAG;oBAAE,SAAS;gBAEnB,oCAAoC;gBACpC,IAAI,MAAM,IAAI,IAAI,CAAC,EAAE,KAAK,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC;oBAAE,SAAS;gBAE3D,MAAM,UAAU,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,QAAQ,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;gBACnE,IAAI,UAAU,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,QAAQ,CAAC,EAAE,CAAC;oBACnD,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;oBAC/B,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;oBAChC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;gBACjE,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC,CAAC,gBAAgB;IAC/B,CAAC;IAED,4EAA4E;IAC5E,mBAAmB;IACnB,4EAA4E;IAE5E;;;OAGG;IACH,mBAAmB,CAAC,MAAc,EAAE,IAAY,EAAE,CAAS;QACzD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACxC,MAAM,EAAE,GAAK,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACtC,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE;YAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;QACxC,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC5C,OAAO;YACL,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,OAAO;YACrC,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,OAAO;SACtC,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,UAAU,CAAC,MAAc,EAAE,IAAY;QACrC,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACtC,IAAI,CAAC,KAAK;YAAE,OAAO,QAAQ,CAAC;QAC5B,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC;QAC5C,OAAO,IAAI,EAAE,MAAM,IAAI,QAAQ,CAAC;IAClC,CAAC;IAED,4EAA4E;IAC5E,gBAAgB;IAChB,4EAA4E;IAE5E,2CAA2C;IAC3C,SAAS;QACP,OAAO;YACL,QAAQ,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACtD,EAAE,EAAE,CAAC,CAAC,EAAE;gBACR,CAAC,EAAE,CAAC,CAAC,CAAC;gBACN,CAAC,EAAE,CAAC,CAAC,CAAC;gBACN,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;aAClB,CAAC,CAAC;YACH,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC/D,IAAI;gBACJ,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;aACxD,CAAC,CAAC;SACJ,CAAC;IACJ,CAAC;IAED,+EAA+E;IAC/E,MAAM,CAAC,OAAO,CAAC,KAAuB;QACpC,MAAM,KAAK,GAAG,IAAI,UAAU,EAAE,CAAC;QAC/B,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;YAC/B,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAC/C,CAAC;QACD,KAAK,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAC1C,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACpC,IAAI,IAAI,EAAE,CAAC;gBACT,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;oBACtB,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;gBAC5C,CAAC;YACH,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;CACF"}
|