@alife-sdk/ai 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 +385 -0
- package/dist/animation/AnimationController.d.ts +60 -0
- package/dist/animation/AnimationController.d.ts.map +1 -0
- package/dist/animation/AnimationController.js +71 -0
- package/dist/animation/AnimationController.js.map +1 -0
- package/dist/animation/AnimationSelector.d.ts +108 -0
- package/dist/animation/AnimationSelector.d.ts.map +1 -0
- package/dist/animation/AnimationSelector.js +194 -0
- package/dist/animation/AnimationSelector.js.map +1 -0
- package/dist/animation/index.d.ts +5 -0
- package/dist/animation/index.d.ts.map +1 -0
- package/dist/animation/index.js +4 -0
- package/dist/animation/index.js.map +1 -0
- package/dist/combat/CombatTransitionChain.d.ts +95 -0
- package/dist/combat/CombatTransitionChain.d.ts.map +1 -0
- package/dist/combat/CombatTransitionChain.js +117 -0
- package/dist/combat/CombatTransitionChain.js.map +1 -0
- package/dist/combat/LoadoutBuilder.d.ts +83 -0
- package/dist/combat/LoadoutBuilder.d.ts.map +1 -0
- package/dist/combat/LoadoutBuilder.js +213 -0
- package/dist/combat/LoadoutBuilder.js.map +1 -0
- package/dist/combat/MonsterAbilityData.d.ts +97 -0
- package/dist/combat/MonsterAbilityData.d.ts.map +1 -0
- package/dist/combat/MonsterAbilityData.js +94 -0
- package/dist/combat/MonsterAbilityData.js.map +1 -0
- package/dist/combat/WeaponSelector.d.ts +47 -0
- package/dist/combat/WeaponSelector.d.ts.map +1 -0
- package/dist/combat/WeaponSelector.js +180 -0
- package/dist/combat/WeaponSelector.js.map +1 -0
- package/dist/combat/index.d.ts +9 -0
- package/dist/combat/index.d.ts.map +1 -0
- package/dist/combat/index.js +6 -0
- package/dist/combat/index.js.map +1 -0
- package/dist/conditions/ConditionBank.d.ts +179 -0
- package/dist/conditions/ConditionBank.d.ts.map +1 -0
- package/dist/conditions/ConditionBank.js +220 -0
- package/dist/conditions/ConditionBank.js.map +1 -0
- package/dist/conditions/index.d.ts +3 -0
- package/dist/conditions/index.d.ts.map +1 -0
- package/dist/conditions/index.js +3 -0
- package/dist/conditions/index.js.map +1 -0
- package/dist/config/createDefaultAIConfig.d.ts +25 -0
- package/dist/config/createDefaultAIConfig.d.ts.map +1 -0
- package/dist/config/createDefaultAIConfig.js +147 -0
- package/dist/config/createDefaultAIConfig.js.map +1 -0
- package/dist/config/index.d.ts +2 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +3 -0
- package/dist/config/index.js.map +1 -0
- package/dist/cover/CoverAccessAdapter.d.ts +61 -0
- package/dist/cover/CoverAccessAdapter.d.ts.map +1 -0
- package/dist/cover/CoverAccessAdapter.js +74 -0
- package/dist/cover/CoverAccessAdapter.js.map +1 -0
- package/dist/cover/CoverEvaluators.d.ts +43 -0
- package/dist/cover/CoverEvaluators.d.ts.map +1 -0
- package/dist/cover/CoverEvaluators.js +193 -0
- package/dist/cover/CoverEvaluators.js.map +1 -0
- package/dist/cover/CoverLockRegistry.d.ts +50 -0
- package/dist/cover/CoverLockRegistry.d.ts.map +1 -0
- package/dist/cover/CoverLockRegistry.js +164 -0
- package/dist/cover/CoverLockRegistry.js.map +1 -0
- package/dist/cover/CoverRecommender.d.ts +32 -0
- package/dist/cover/CoverRecommender.d.ts.map +1 -0
- package/dist/cover/CoverRecommender.js +45 -0
- package/dist/cover/CoverRecommender.js.map +1 -0
- package/dist/cover/CoverRegistry.d.ts +97 -0
- package/dist/cover/CoverRegistry.d.ts.map +1 -0
- package/dist/cover/CoverRegistry.js +223 -0
- package/dist/cover/CoverRegistry.js.map +1 -0
- package/dist/cover/ICoverEvaluator.d.ts +15 -0
- package/dist/cover/ICoverEvaluator.d.ts.map +1 -0
- package/dist/cover/ICoverEvaluator.js +4 -0
- package/dist/cover/ICoverEvaluator.js.map +1 -0
- package/dist/cover/ICoverLockConfig.d.ts +83 -0
- package/dist/cover/ICoverLockConfig.d.ts.map +1 -0
- package/dist/cover/ICoverLockConfig.js +21 -0
- package/dist/cover/ICoverLockConfig.js.map +1 -0
- package/dist/cover/LoopholeGenerator.d.ts +44 -0
- package/dist/cover/LoopholeGenerator.d.ts.map +1 -0
- package/dist/cover/LoopholeGenerator.js +96 -0
- package/dist/cover/LoopholeGenerator.js.map +1 -0
- package/dist/cover/index.d.ts +11 -0
- package/dist/cover/index.d.ts.map +1 -0
- package/dist/cover/index.js +8 -0
- package/dist/cover/index.js.map +1 -0
- package/dist/goap/EvadeHazardAction.d.ts +34 -0
- package/dist/goap/EvadeHazardAction.d.ts.map +1 -0
- package/dist/goap/EvadeHazardAction.js +48 -0
- package/dist/goap/EvadeHazardAction.js.map +1 -0
- package/dist/goap/GOAPController.d.ts +114 -0
- package/dist/goap/GOAPController.d.ts.map +1 -0
- package/dist/goap/GOAPController.js +191 -0
- package/dist/goap/GOAPController.js.map +1 -0
- package/dist/goap/GoalSelector.d.ts +40 -0
- package/dist/goap/GoalSelector.d.ts.map +1 -0
- package/dist/goap/GoalSelector.js +115 -0
- package/dist/goap/GoalSelector.js.map +1 -0
- package/dist/goap/IHazardZoneAccess.d.ts +16 -0
- package/dist/goap/IHazardZoneAccess.d.ts.map +1 -0
- package/dist/goap/IHazardZoneAccess.js +2 -0
- package/dist/goap/IHazardZoneAccess.js.map +1 -0
- package/dist/goap/WorldStateBuilder.d.ts +27 -0
- package/dist/goap/WorldStateBuilder.d.ts.map +1 -0
- package/dist/goap/WorldStateBuilder.js +51 -0
- package/dist/goap/WorldStateBuilder.js.map +1 -0
- package/dist/goap/index.d.ts +9 -0
- package/dist/goap/index.d.ts.map +1 -0
- package/dist/goap/index.js +6 -0
- package/dist/goap/index.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/navigation/PathSmoother.d.ts +29 -0
- package/dist/navigation/PathSmoother.d.ts.map +1 -0
- package/dist/navigation/PathSmoother.js +172 -0
- package/dist/navigation/PathSmoother.js.map +1 -0
- package/dist/navigation/RestrictedZoneManager.d.ts +83 -0
- package/dist/navigation/RestrictedZoneManager.d.ts.map +1 -0
- package/dist/navigation/RestrictedZoneManager.js +179 -0
- package/dist/navigation/RestrictedZoneManager.js.map +1 -0
- package/dist/navigation/SmoothPathFollower.d.ts +55 -0
- package/dist/navigation/SmoothPathFollower.d.ts.map +1 -0
- package/dist/navigation/SmoothPathFollower.js +132 -0
- package/dist/navigation/SmoothPathFollower.js.map +1 -0
- package/dist/navigation/SteeringBehaviors.d.ts +123 -0
- package/dist/navigation/SteeringBehaviors.d.ts.map +1 -0
- package/dist/navigation/SteeringBehaviors.js +211 -0
- package/dist/navigation/SteeringBehaviors.js.map +1 -0
- package/dist/navigation/index.d.ts +7 -0
- package/dist/navigation/index.d.ts.map +1 -0
- package/dist/navigation/index.js +6 -0
- package/dist/navigation/index.js.map +1 -0
- package/dist/perception/NPCSensors.d.ts +129 -0
- package/dist/perception/NPCSensors.d.ts.map +1 -0
- package/dist/perception/NPCSensors.js +147 -0
- package/dist/perception/NPCSensors.js.map +1 -0
- package/dist/perception/PerceptionQuery.d.ts +65 -0
- package/dist/perception/PerceptionQuery.d.ts.map +1 -0
- package/dist/perception/PerceptionQuery.js +199 -0
- package/dist/perception/PerceptionQuery.js.map +1 -0
- package/dist/perception/index.d.ts +4 -0
- package/dist/perception/index.d.ts.map +1 -0
- package/dist/perception/index.js +4 -0
- package/dist/perception/index.js.map +1 -0
- package/dist/plugin/AIPlugin.d.ts +71 -0
- package/dist/plugin/AIPlugin.d.ts.map +1 -0
- package/dist/plugin/AIPlugin.js +134 -0
- package/dist/plugin/AIPlugin.js.map +1 -0
- package/dist/plugin/index.d.ts +3 -0
- package/dist/plugin/index.d.ts.map +1 -0
- package/dist/plugin/index.js +3 -0
- package/dist/plugin/index.js.map +1 -0
- package/dist/ports/AIPorts.d.ts +13 -0
- package/dist/ports/AIPorts.d.ts.map +1 -0
- package/dist/ports/AIPorts.js +14 -0
- package/dist/ports/AIPorts.js.map +1 -0
- package/dist/ports/ICoverPointSource.d.ts +27 -0
- package/dist/ports/ICoverPointSource.d.ts.map +1 -0
- package/dist/ports/ICoverPointSource.js +4 -0
- package/dist/ports/ICoverPointSource.js.map +1 -0
- package/dist/ports/IPerceptionProvider.d.ts +42 -0
- package/dist/ports/IPerceptionProvider.d.ts.map +1 -0
- package/dist/ports/IPerceptionProvider.js +4 -0
- package/dist/ports/IPerceptionProvider.js.map +1 -0
- package/dist/ports/index.d.ts +4 -0
- package/dist/ports/index.d.ts.map +1 -0
- package/dist/ports/index.js +3 -0
- package/dist/ports/index.js.map +1 -0
- package/dist/sound/VocalizationTypes.d.ts +57 -0
- package/dist/sound/VocalizationTypes.d.ts.map +1 -0
- package/dist/sound/VocalizationTypes.js +87 -0
- package/dist/sound/VocalizationTypes.js.map +1 -0
- package/dist/sound/index.d.ts +3 -0
- package/dist/sound/index.d.ts.map +1 -0
- package/dist/sound/index.js +3 -0
- package/dist/sound/index.js.map +1 -0
- package/dist/squad/SquadSharedTarget.d.ts +137 -0
- package/dist/squad/SquadSharedTarget.d.ts.map +1 -0
- package/dist/squad/SquadSharedTarget.js +145 -0
- package/dist/squad/SquadSharedTarget.js.map +1 -0
- package/dist/squad/SquadTactics.d.ts +63 -0
- package/dist/squad/SquadTactics.d.ts.map +1 -0
- package/dist/squad/SquadTactics.js +76 -0
- package/dist/squad/SquadTactics.js.map +1 -0
- package/dist/squad/index.d.ts +5 -0
- package/dist/squad/index.d.ts.map +1 -0
- package/dist/squad/index.js +4 -0
- package/dist/squad/index.js.map +1 -0
- package/dist/states/INPCContext.d.ts +550 -0
- package/dist/states/INPCContext.d.ts.map +1 -0
- package/dist/states/INPCContext.js +17 -0
- package/dist/states/INPCContext.js.map +1 -0
- package/dist/states/INPCOnlineState.d.ts +202 -0
- package/dist/states/INPCOnlineState.d.ts.map +1 -0
- package/dist/states/INPCOnlineState.js +9 -0
- package/dist/states/INPCOnlineState.js.map +1 -0
- package/dist/states/IOnlineStateHandler.d.ts +58 -0
- package/dist/states/IOnlineStateHandler.d.ts.map +1 -0
- package/dist/states/IOnlineStateHandler.js +13 -0
- package/dist/states/IOnlineStateHandler.js.map +1 -0
- package/dist/states/IStateConfig.d.ts +272 -0
- package/dist/states/IStateConfig.d.ts.map +1 -0
- package/dist/states/IStateConfig.js +100 -0
- package/dist/states/IStateConfig.js.map +1 -0
- package/dist/states/IStateTransitionMap.d.ts +89 -0
- package/dist/states/IStateTransitionMap.d.ts.map +1 -0
- package/dist/states/IStateTransitionMap.js +75 -0
- package/dist/states/IStateTransitionMap.js.map +1 -0
- package/dist/states/NPCOnlineState.d.ts +19 -0
- package/dist/states/NPCOnlineState.d.ts.map +1 -0
- package/dist/states/NPCOnlineState.js +75 -0
- package/dist/states/NPCOnlineState.js.map +1 -0
- package/dist/states/NPCPerception.d.ts +108 -0
- package/dist/states/NPCPerception.d.ts.map +1 -0
- package/dist/states/NPCPerception.js +122 -0
- package/dist/states/NPCPerception.js.map +1 -0
- package/dist/states/OnlineAIDriver.d.ts +64 -0
- package/dist/states/OnlineAIDriver.d.ts.map +1 -0
- package/dist/states/OnlineAIDriver.js +171 -0
- package/dist/states/OnlineAIDriver.js.map +1 -0
- package/dist/states/OnlineStateRegistryBuilder.d.ts +115 -0
- package/dist/states/OnlineStateRegistryBuilder.d.ts.map +1 -0
- package/dist/states/OnlineStateRegistryBuilder.js +184 -0
- package/dist/states/OnlineStateRegistryBuilder.js.map +1 -0
- package/dist/states/StateHandlerMap.d.ts +52 -0
- package/dist/states/StateHandlerMap.d.ts.map +1 -0
- package/dist/states/StateHandlerMap.js +88 -0
- package/dist/states/StateHandlerMap.js.map +1 -0
- package/dist/states/eat-corpse/EatCorpseState.d.ts +32 -0
- package/dist/states/eat-corpse/EatCorpseState.d.ts.map +1 -0
- package/dist/states/eat-corpse/EatCorpseState.js +126 -0
- package/dist/states/eat-corpse/EatCorpseState.js.map +1 -0
- package/dist/states/eat-corpse/EatCorpseTransitionGuard.d.ts +34 -0
- package/dist/states/eat-corpse/EatCorpseTransitionGuard.d.ts.map +1 -0
- package/dist/states/eat-corpse/EatCorpseTransitionGuard.js +82 -0
- package/dist/states/eat-corpse/EatCorpseTransitionGuard.js.map +1 -0
- package/dist/states/eat-corpse/ICorpseSource.d.ts +87 -0
- package/dist/states/eat-corpse/ICorpseSource.d.ts.map +1 -0
- package/dist/states/eat-corpse/ICorpseSource.js +5 -0
- package/dist/states/eat-corpse/ICorpseSource.js.map +1 -0
- package/dist/states/eat-corpse/IEatCorpseConfig.d.ts +75 -0
- package/dist/states/eat-corpse/IEatCorpseConfig.d.ts.map +1 -0
- package/dist/states/eat-corpse/IEatCorpseConfig.js +23 -0
- package/dist/states/eat-corpse/IEatCorpseConfig.js.map +1 -0
- package/dist/states/eat-corpse/IEatCorpsePhase.d.ts +23 -0
- package/dist/states/eat-corpse/IEatCorpsePhase.d.ts.map +1 -0
- package/dist/states/eat-corpse/IEatCorpsePhase.js +5 -0
- package/dist/states/eat-corpse/IEatCorpsePhase.js.map +1 -0
- package/dist/states/eat-corpse/index.d.ts +7 -0
- package/dist/states/eat-corpse/index.d.ts.map +1 -0
- package/dist/states/eat-corpse/index.js +11 -0
- package/dist/states/eat-corpse/index.js.map +1 -0
- package/dist/states/handlers/AlertState.d.ts +18 -0
- package/dist/states/handlers/AlertState.d.ts.map +1 -0
- package/dist/states/handlers/AlertState.js +104 -0
- package/dist/states/handlers/AlertState.js.map +1 -0
- package/dist/states/handlers/CampState.d.ts +18 -0
- package/dist/states/handlers/CampState.d.ts.map +1 -0
- package/dist/states/handlers/CampState.js +94 -0
- package/dist/states/handlers/CampState.js.map +1 -0
- package/dist/states/handlers/ChargeState.d.ts +18 -0
- package/dist/states/handlers/ChargeState.d.ts.map +1 -0
- package/dist/states/handlers/ChargeState.js +103 -0
- package/dist/states/handlers/ChargeState.js.map +1 -0
- package/dist/states/handlers/CombatState.d.ts +19 -0
- package/dist/states/handlers/CombatState.d.ts.map +1 -0
- package/dist/states/handlers/CombatState.js +137 -0
- package/dist/states/handlers/CombatState.js.map +1 -0
- package/dist/states/handlers/CombatTransitionHandler.d.ts +34 -0
- package/dist/states/handlers/CombatTransitionHandler.d.ts.map +1 -0
- package/dist/states/handlers/CombatTransitionHandler.js +137 -0
- package/dist/states/handlers/CombatTransitionHandler.js.map +1 -0
- package/dist/states/handlers/DeadState.d.ts +16 -0
- package/dist/states/handlers/DeadState.d.ts.map +1 -0
- package/dist/states/handlers/DeadState.js +35 -0
- package/dist/states/handlers/DeadState.js.map +1 -0
- package/dist/states/handlers/EvadeGrenadeState.d.ts +23 -0
- package/dist/states/handlers/EvadeGrenadeState.d.ts.map +1 -0
- package/dist/states/handlers/EvadeGrenadeState.js +93 -0
- package/dist/states/handlers/EvadeGrenadeState.js.map +1 -0
- package/dist/states/handlers/FleeState.d.ts +18 -0
- package/dist/states/handlers/FleeState.d.ts.map +1 -0
- package/dist/states/handlers/FleeState.js +61 -0
- package/dist/states/handlers/FleeState.js.map +1 -0
- package/dist/states/handlers/GrenadeState.d.ts +18 -0
- package/dist/states/handlers/GrenadeState.d.ts.map +1 -0
- package/dist/states/handlers/GrenadeState.js +61 -0
- package/dist/states/handlers/GrenadeState.js.map +1 -0
- package/dist/states/handlers/HelpWoundedState.d.ts +27 -0
- package/dist/states/handlers/HelpWoundedState.d.ts.map +1 -0
- package/dist/states/handlers/HelpWoundedState.js +131 -0
- package/dist/states/handlers/HelpWoundedState.js.map +1 -0
- package/dist/states/handlers/IdleState.d.ts +18 -0
- package/dist/states/handlers/IdleState.d.ts.map +1 -0
- package/dist/states/handlers/IdleState.js +127 -0
- package/dist/states/handlers/IdleState.js.map +1 -0
- package/dist/states/handlers/InvestigateState.d.ts +27 -0
- package/dist/states/handlers/InvestigateState.d.ts.map +1 -0
- package/dist/states/handlers/InvestigateState.js +145 -0
- package/dist/states/handlers/InvestigateState.js.map +1 -0
- package/dist/states/handlers/KillWoundedState.d.ts +27 -0
- package/dist/states/handlers/KillWoundedState.d.ts.map +1 -0
- package/dist/states/handlers/KillWoundedState.js +147 -0
- package/dist/states/handlers/KillWoundedState.js.map +1 -0
- package/dist/states/handlers/LeapState.d.ts +18 -0
- package/dist/states/handlers/LeapState.d.ts.map +1 -0
- package/dist/states/handlers/LeapState.js +115 -0
- package/dist/states/handlers/LeapState.js.map +1 -0
- package/dist/states/handlers/MonsterCombatController.d.ts +55 -0
- package/dist/states/handlers/MonsterCombatController.d.ts.map +1 -0
- package/dist/states/handlers/MonsterCombatController.js +152 -0
- package/dist/states/handlers/MonsterCombatController.js.map +1 -0
- package/dist/states/handlers/PatrolState.d.ts +18 -0
- package/dist/states/handlers/PatrolState.d.ts.map +1 -0
- package/dist/states/handlers/PatrolState.js +137 -0
- package/dist/states/handlers/PatrolState.js.map +1 -0
- package/dist/states/handlers/PsiAttackState.d.ts +18 -0
- package/dist/states/handlers/PsiAttackState.d.ts.map +1 -0
- package/dist/states/handlers/PsiAttackState.js +101 -0
- package/dist/states/handlers/PsiAttackState.js.map +1 -0
- package/dist/states/handlers/RetreatState.d.ts +18 -0
- package/dist/states/handlers/RetreatState.d.ts.map +1 -0
- package/dist/states/handlers/RetreatState.js +131 -0
- package/dist/states/handlers/RetreatState.js.map +1 -0
- package/dist/states/handlers/SearchState.d.ts +18 -0
- package/dist/states/handlers/SearchState.d.ts.map +1 -0
- package/dist/states/handlers/SearchState.js +64 -0
- package/dist/states/handlers/SearchState.js.map +1 -0
- package/dist/states/handlers/SleepState.d.ts +18 -0
- package/dist/states/handlers/SleepState.d.ts.map +1 -0
- package/dist/states/handlers/SleepState.js +94 -0
- package/dist/states/handlers/SleepState.js.map +1 -0
- package/dist/states/handlers/StalkState.d.ts +18 -0
- package/dist/states/handlers/StalkState.d.ts.map +1 -0
- package/dist/states/handlers/StalkState.js +82 -0
- package/dist/states/handlers/StalkState.js.map +1 -0
- package/dist/states/handlers/TakeCoverState.d.ts +18 -0
- package/dist/states/handlers/TakeCoverState.d.ts.map +1 -0
- package/dist/states/handlers/TakeCoverState.js +208 -0
- package/dist/states/handlers/TakeCoverState.js.map +1 -0
- package/dist/states/handlers/WoundedState.d.ts +18 -0
- package/dist/states/handlers/WoundedState.d.ts.map +1 -0
- package/dist/states/handlers/WoundedState.js +71 -0
- package/dist/states/handlers/WoundedState.js.map +1 -0
- package/dist/states/handlers/_utils.d.ts +55 -0
- package/dist/states/handlers/_utils.d.ts.map +1 -0
- package/dist/states/handlers/_utils.js +88 -0
- package/dist/states/handlers/_utils.js.map +1 -0
- package/dist/states/handlers/index.d.ts +25 -0
- package/dist/states/handlers/index.d.ts.map +1 -0
- package/dist/states/handlers/index.js +28 -0
- package/dist/states/handlers/index.js.map +1 -0
- package/dist/states/index.d.ts +17 -0
- package/dist/states/index.d.ts.map +1 -0
- package/dist/states/index.js +12 -0
- package/dist/states/index.js.map +1 -0
- package/dist/states/pack/IPackAccess.d.ts +46 -0
- package/dist/states/pack/IPackAccess.d.ts.map +1 -0
- package/dist/states/pack/IPackAccess.js +8 -0
- package/dist/states/pack/IPackAccess.js.map +1 -0
- package/dist/suspicion/SuspicionAccumulator.d.ts +166 -0
- package/dist/suspicion/SuspicionAccumulator.d.ts.map +1 -0
- package/dist/suspicion/SuspicionAccumulator.js +191 -0
- package/dist/suspicion/SuspicionAccumulator.js.map +1 -0
- package/dist/suspicion/index.d.ts +3 -0
- package/dist/suspicion/index.d.ts.map +1 -0
- package/dist/suspicion/index.js +2 -0
- package/dist/suspicion/index.js.map +1 -0
- package/dist/types/IAnimationTypes.d.ts +28 -0
- package/dist/types/IAnimationTypes.d.ts.map +1 -0
- package/dist/types/IAnimationTypes.js +17 -0
- package/dist/types/IAnimationTypes.js.map +1 -0
- package/dist/types/ICoverPoint.d.ts +76 -0
- package/dist/types/ICoverPoint.d.ts.map +1 -0
- package/dist/types/ICoverPoint.js +21 -0
- package/dist/types/ICoverPoint.js.map +1 -0
- package/dist/types/IOnlineAIConfig.d.ts +150 -0
- package/dist/types/IOnlineAIConfig.d.ts.map +1 -0
- package/dist/types/IOnlineAIConfig.js +5 -0
- package/dist/types/IOnlineAIConfig.js.map +1 -0
- package/dist/types/IPerceptionTypes.d.ts +94 -0
- package/dist/types/IPerceptionTypes.d.ts.map +1 -0
- package/dist/types/IPerceptionTypes.js +37 -0
- package/dist/types/IPerceptionTypes.js.map +1 -0
- package/dist/types/IWeaponTypes.d.ts +56 -0
- package/dist/types/IWeaponTypes.d.ts.map +1 -0
- package/dist/types/IWeaponTypes.js +15 -0
- package/dist/types/IWeaponTypes.js.map +1 -0
- package/dist/types/index.d.ts +10 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +5 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +123 -0
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
// navigation/SteeringBehaviors.ts
|
|
2
|
+
// Pure functions for Craig Reynolds-style flocking / pack movement.
|
|
3
|
+
//
|
|
4
|
+
// Design principles:
|
|
5
|
+
// • All functions are pure (no side effects, no ctx dependency).
|
|
6
|
+
// • All accept and return Vec2 — no mutable state.
|
|
7
|
+
// • combineForces() is the extensibility escape-hatch for custom force composition.
|
|
8
|
+
// • Nothing is hardcoded — every threshold lives in ISteeringConfig.
|
|
9
|
+
import { ZERO, normalize, magnitude, subtract } from '@alife-sdk/core';
|
|
10
|
+
/**
|
|
11
|
+
* Create an {@link ISteeringConfig} with production defaults.
|
|
12
|
+
* Pass a partial override object to tune individual values without touching the rest.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* const cfg = createDefaultSteeringConfig({ separationRadius: 60 });
|
|
16
|
+
*/
|
|
17
|
+
export function createDefaultSteeringConfig(overrides) {
|
|
18
|
+
return {
|
|
19
|
+
separationRadius: 40,
|
|
20
|
+
separationWeight: 1.5,
|
|
21
|
+
neighborRadius: 150,
|
|
22
|
+
cohesionWeight: 0.5,
|
|
23
|
+
alignmentWeight: 0.3,
|
|
24
|
+
maxSteeringForce: 80,
|
|
25
|
+
...overrides,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
// Primitive steering forces
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
/**
|
|
32
|
+
* Compute the separation steering force — repulsion away from any neighbor
|
|
33
|
+
* that is closer than {@link ISteeringConfig.separationRadius}.
|
|
34
|
+
*
|
|
35
|
+
* The force is inversely proportional to distance: the closer the neighbor,
|
|
36
|
+
* the stronger the push. Neighbors outside the radius are ignored.
|
|
37
|
+
* Returns {@link ZERO} when `neighbors` is empty or none are within radius.
|
|
38
|
+
*
|
|
39
|
+
* @param self - Position of the NPC computing the force.
|
|
40
|
+
* @param neighbors - Positions of nearby agents (e.g. from getVisibleAllies()).
|
|
41
|
+
* @param config - Steering configuration.
|
|
42
|
+
*/
|
|
43
|
+
export function separation(self, neighbors, config) {
|
|
44
|
+
let fx = 0;
|
|
45
|
+
let fy = 0;
|
|
46
|
+
const rSq = config.separationRadius * config.separationRadius;
|
|
47
|
+
for (const n of neighbors) {
|
|
48
|
+
const dx = self.x - n.x;
|
|
49
|
+
const dy = self.y - n.y;
|
|
50
|
+
const distSq = dx * dx + dy * dy;
|
|
51
|
+
// Compare squared first to avoid sqrt for out-of-range neighbors.
|
|
52
|
+
if (distSq === 0 || distSq >= rSq)
|
|
53
|
+
continue;
|
|
54
|
+
const dist = Math.sqrt(distSq);
|
|
55
|
+
// Inverse-distance weighting: closer → stronger push
|
|
56
|
+
const strength = 1 - dist / config.separationRadius;
|
|
57
|
+
fx += (dx / dist) * strength;
|
|
58
|
+
fy += (dy / dist) * strength;
|
|
59
|
+
}
|
|
60
|
+
if (fx === 0 && fy === 0)
|
|
61
|
+
return ZERO;
|
|
62
|
+
return normalize({ x: fx, y: fy });
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Compute the cohesion steering force — attraction toward the average position
|
|
66
|
+
* (center of mass) of neighbors within {@link ISteeringConfig.neighborRadius}.
|
|
67
|
+
*
|
|
68
|
+
* Returns {@link ZERO} when `neighbors` is empty or none are within the radius.
|
|
69
|
+
*
|
|
70
|
+
* @param self - Position of the NPC computing the force.
|
|
71
|
+
* @param neighbors - Positions of nearby agents.
|
|
72
|
+
* @param config - Steering configuration.
|
|
73
|
+
*/
|
|
74
|
+
export function cohesion(self, neighbors, config) {
|
|
75
|
+
let cx = 0;
|
|
76
|
+
let cy = 0;
|
|
77
|
+
let count = 0;
|
|
78
|
+
const rSq = config.neighborRadius * config.neighborRadius;
|
|
79
|
+
for (const n of neighbors) {
|
|
80
|
+
const dx = n.x - self.x;
|
|
81
|
+
const dy = n.y - self.y;
|
|
82
|
+
if (dx * dx + dy * dy > rSq)
|
|
83
|
+
continue;
|
|
84
|
+
cx += n.x;
|
|
85
|
+
cy += n.y;
|
|
86
|
+
count++;
|
|
87
|
+
}
|
|
88
|
+
if (count === 0)
|
|
89
|
+
return ZERO;
|
|
90
|
+
const center = { x: cx / count, y: cy / count };
|
|
91
|
+
const toCenter = subtract(center, self);
|
|
92
|
+
const mag = magnitude(toCenter);
|
|
93
|
+
return mag < 0.001 ? ZERO : normalize(toCenter);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Compute the alignment steering force — the average of all provided desired
|
|
97
|
+
* directions (normalized).
|
|
98
|
+
*
|
|
99
|
+
* **API note:** `self` is intentionally absent — alignment depends only on
|
|
100
|
+
* neighbor directions, not on the caller's own position. The caller is
|
|
101
|
+
* responsible for computing `neighborDirections`
|
|
102
|
+
* (e.g. `normalize(target − npcPos)` for each neighbor's target vector).
|
|
103
|
+
*
|
|
104
|
+
* The `alignmentWeight` from config is applied by the caller via
|
|
105
|
+
* {@link combineForces}, consistent with how separation / cohesion weights work.
|
|
106
|
+
*
|
|
107
|
+
* Returns {@link ZERO} when `neighborDirections` is empty.
|
|
108
|
+
*
|
|
109
|
+
* @param neighborDirections - Desired movement directions of nearby agents.
|
|
110
|
+
*/
|
|
111
|
+
export function alignment(neighborDirections) {
|
|
112
|
+
if (neighborDirections.length === 0)
|
|
113
|
+
return ZERO;
|
|
114
|
+
let ax = 0;
|
|
115
|
+
let ay = 0;
|
|
116
|
+
for (const d of neighborDirections) {
|
|
117
|
+
ax += d.x;
|
|
118
|
+
ay += d.y;
|
|
119
|
+
}
|
|
120
|
+
const avg = { x: ax / neighborDirections.length, y: ay / neighborDirections.length };
|
|
121
|
+
const mag = magnitude(avg);
|
|
122
|
+
return mag < 0.001 ? ZERO : normalize(avg);
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Compute a weighted sum of arbitrary steering forces, clamped to `maxMagnitude`.
|
|
126
|
+
*
|
|
127
|
+
* This is the **extensibility escape-hatch**: SDK users can compose any mix of
|
|
128
|
+
* built-in forces (separation, cohesion, alignment) with their own custom forces
|
|
129
|
+
* without modifying the SDK.
|
|
130
|
+
*
|
|
131
|
+
* @example
|
|
132
|
+
* const combined = combineForces([
|
|
133
|
+
* { force: sep, weight: cfg.separationWeight },
|
|
134
|
+
* { force: coh, weight: cfg.cohesionWeight },
|
|
135
|
+
* { force: myFormation, weight: 2.0 },
|
|
136
|
+
* ], cfg.maxSteeringForce);
|
|
137
|
+
*
|
|
138
|
+
* @param forces - Array of `{ force, weight }` entries to blend.
|
|
139
|
+
* @param maxMagnitude - Maximum allowed magnitude of the result (px/s).
|
|
140
|
+
*/
|
|
141
|
+
export function combineForces(forces, maxMagnitude) {
|
|
142
|
+
let fx = 0;
|
|
143
|
+
let fy = 0;
|
|
144
|
+
for (const { force, weight } of forces) {
|
|
145
|
+
fx += force.x * weight;
|
|
146
|
+
fy += force.y * weight;
|
|
147
|
+
}
|
|
148
|
+
if (fx === 0 && fy === 0)
|
|
149
|
+
return ZERO;
|
|
150
|
+
const mag = Math.sqrt(fx * fx + fy * fy);
|
|
151
|
+
if (mag <= maxMagnitude)
|
|
152
|
+
return { x: fx, y: fy };
|
|
153
|
+
const ratio = maxMagnitude / mag;
|
|
154
|
+
return { x: fx * ratio, y: fy * ratio };
|
|
155
|
+
}
|
|
156
|
+
// ---------------------------------------------------------------------------
|
|
157
|
+
// Convenience combinations
|
|
158
|
+
// ---------------------------------------------------------------------------
|
|
159
|
+
/**
|
|
160
|
+
* Compute the combined separation + cohesion steering force, clamped to
|
|
161
|
+
* {@link ISteeringConfig.maxSteeringForce}.
|
|
162
|
+
*
|
|
163
|
+
* Does **not** include alignment — alignment requires caller-supplied desired
|
|
164
|
+
* directions (see {@link alignment}). Use {@link combineForces} to add it.
|
|
165
|
+
*
|
|
166
|
+
* Returns {@link ZERO} when `neighbors` is empty.
|
|
167
|
+
*
|
|
168
|
+
* @param self - Position of the NPC.
|
|
169
|
+
* @param neighbors - Positions of nearby agents.
|
|
170
|
+
* @param config - Steering configuration.
|
|
171
|
+
*/
|
|
172
|
+
export function computePackSteering(self, neighbors, config) {
|
|
173
|
+
if (neighbors.length === 0)
|
|
174
|
+
return ZERO;
|
|
175
|
+
const sep = separation(self, neighbors, config);
|
|
176
|
+
const coh = cohesion(self, neighbors, config);
|
|
177
|
+
return combineForces([
|
|
178
|
+
{ force: sep, weight: config.separationWeight },
|
|
179
|
+
{ force: coh, weight: config.cohesionWeight },
|
|
180
|
+
], config.maxSteeringForce);
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Blend a normalised primary movement direction with a computed steering force.
|
|
184
|
+
*
|
|
185
|
+
* Returns `{ vx, vy }` ready for `ctx.setVelocity()` — consistent with the
|
|
186
|
+
* positional-tuple style used by `moveToward` / `awayFrom` in `_utils.ts`.
|
|
187
|
+
*
|
|
188
|
+
* The result is re-normalised to `speed` so the final magnitude is always
|
|
189
|
+
* consistent regardless of the blend ratio.
|
|
190
|
+
*
|
|
191
|
+
* @param primaryVx - Normalised X component of the desired direction (toward target, etc.).
|
|
192
|
+
* @param primaryVy - Normalised Y component of the desired direction.
|
|
193
|
+
* @param steeringForce - Steering correction force (e.g. from computePackSteering).
|
|
194
|
+
* @param speed - Base movement speed (px/s).
|
|
195
|
+
* @param weight - Blend weight: 0 = pure primary × speed, 1 = pure steering.
|
|
196
|
+
*/
|
|
197
|
+
export function blendWithPrimary(primaryVx, primaryVy, steeringForce, speed, weight) {
|
|
198
|
+
// Normalise steering to a unit direction so `weight` controls directional split
|
|
199
|
+
// independently of the force magnitude (0..maxSteeringForce).
|
|
200
|
+
const smag = Math.sqrt(steeringForce.x * steeringForce.x + steeringForce.y * steeringForce.y);
|
|
201
|
+
const sdx = smag < 0.001 ? primaryVx : steeringForce.x / smag;
|
|
202
|
+
const sdy = smag < 0.001 ? primaryVy : steeringForce.y / smag;
|
|
203
|
+
// Blend normalised directions. primaryVx/Vy are expected to be normalised by the caller.
|
|
204
|
+
const rx = primaryVx * (1 - weight) + sdx * weight;
|
|
205
|
+
const ry = primaryVy * (1 - weight) + sdy * weight;
|
|
206
|
+
const mag = Math.sqrt(rx * rx + ry * ry);
|
|
207
|
+
if (mag < 0.001)
|
|
208
|
+
return { vx: 0, vy: 0 };
|
|
209
|
+
return { vx: (rx / mag) * speed, vy: (ry / mag) * speed };
|
|
210
|
+
}
|
|
211
|
+
//# sourceMappingURL=SteeringBehaviors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SteeringBehaviors.js","sourceRoot":"","sources":["../../src/navigation/SteeringBehaviors.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { smoothPath, smoothPathWithTurning } from './PathSmoother';
|
|
2
|
+
export { SmoothPathFollower } from './SmoothPathFollower';
|
|
3
|
+
export { RestrictedZoneManager, RestrictionType } from './RestrictedZoneManager';
|
|
4
|
+
export type { IRestrictedZone } from './RestrictedZoneManager';
|
|
5
|
+
export { createDefaultSteeringConfig, separation, cohesion, alignment, combineForces, computePackSteering, blendWithPrimary, } from './SteeringBehaviors';
|
|
6
|
+
export type { ISteeringConfig } from './SteeringBehaviors';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/navigation/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AACjF,YAAY,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EACL,2BAA2B,EAC3B,UAAU,EACV,QAAQ,EACR,SAAS,EACT,aAAa,EACb,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// navigation sub-path barrel
|
|
2
|
+
export { smoothPath, smoothPathWithTurning } from './PathSmoother';
|
|
3
|
+
export { SmoothPathFollower } from './SmoothPathFollower';
|
|
4
|
+
export { RestrictedZoneManager, RestrictionType } from './RestrictedZoneManager';
|
|
5
|
+
export { createDefaultSteeringConfig, separation, cohesion, alignment, combineForces, computePackSteering, blendWithPrimary, } from './SteeringBehaviors';
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/navigation/index.ts"],"names":[],"mappings":"AAAA,6BAA6B;AAC7B,OAAO,EAAE,UAAU,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAEjF,OAAO,EACL,2BAA2B,EAC3B,UAAU,EACV,QAAQ,EACR,SAAS,EACT,aAAa,EACb,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import type { Vec2 } from '@alife-sdk/core';
|
|
2
|
+
import type { SpatialGrid } from '@alife-sdk/core';
|
|
3
|
+
/**
|
|
4
|
+
* Entity that can both observe and be observed.
|
|
5
|
+
* Agnostic — callers map their game entities to this interface.
|
|
6
|
+
*/
|
|
7
|
+
export interface IPerceptibleEntity {
|
|
8
|
+
readonly id: string;
|
|
9
|
+
readonly position: Vec2;
|
|
10
|
+
readonly factionId: string;
|
|
11
|
+
/** Facing direction in radians (0 = right / +X axis). */
|
|
12
|
+
readonly facingAngle: number;
|
|
13
|
+
readonly isAlive: boolean;
|
|
14
|
+
/** Maximum vision distance in world units. */
|
|
15
|
+
readonly visionRange: number;
|
|
16
|
+
/** Half-angle of the FOV cone in radians (e.g. Math.PI/3 = 60° half = 120° total). */
|
|
17
|
+
readonly visionHalfAngle: number;
|
|
18
|
+
/** Maximum hearing range in world units. */
|
|
19
|
+
readonly hearingRange: number;
|
|
20
|
+
}
|
|
21
|
+
/** Result of a sensor detection — framework-agnostic. */
|
|
22
|
+
export interface IDetectionEvent {
|
|
23
|
+
readonly observerId: string;
|
|
24
|
+
readonly targetId: string;
|
|
25
|
+
readonly targetPosition: Vec2;
|
|
26
|
+
readonly channel: 'visual' | 'sound';
|
|
27
|
+
/**
|
|
28
|
+
* Detection confidence in [0, 1].
|
|
29
|
+
* Visual detections always have confidence 1.0.
|
|
30
|
+
* Sound confidence decreases linearly with distance.
|
|
31
|
+
*/
|
|
32
|
+
readonly confidence: number;
|
|
33
|
+
}
|
|
34
|
+
export interface INPCSensorsConfig {
|
|
35
|
+
/**
|
|
36
|
+
* Spatial hash grid for O(k) candidate lookup.
|
|
37
|
+
* Entities must be registered in the grid by the caller.
|
|
38
|
+
*/
|
|
39
|
+
spatialGrid: SpatialGrid<{
|
|
40
|
+
id: string;
|
|
41
|
+
position: Vec2;
|
|
42
|
+
}>;
|
|
43
|
+
/** Returns true if observerFaction is hostile toward targetFaction. */
|
|
44
|
+
isHostile: (observerFaction: string, targetFaction: string) => boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Optional LOS check — called after the FOV cone test.
|
|
47
|
+
* Return `true` if the line from `from` to `to` is unobstructed.
|
|
48
|
+
* When absent, LOS is assumed clear (backward-compatible).
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```ts
|
|
52
|
+
* isLineOfSightClear(from, to) {
|
|
53
|
+
* const line = new Phaser.Geom.Line(from.x, from.y, to.x, to.y);
|
|
54
|
+
* return obstacles.every(r => !Phaser.Geom.Intersects.LineToRectangle(line, r));
|
|
55
|
+
* }
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
isLineOfSightClear?: (from: Vec2, to: Vec2) => boolean;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* NPC vision and hearing sensors.
|
|
62
|
+
*
|
|
63
|
+
* Two sensors:
|
|
64
|
+
* - **Vision** (`detectVision`): FOV cone per NPC, hostile-only, O(n×k) via SpatialGrid.
|
|
65
|
+
* - **Sound** (`detectSound`): omnidirectional from a source, all factions hear it, confidence decays with distance.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```ts
|
|
69
|
+
* const sensors = new NPCSensors({ spatialGrid, isHostile });
|
|
70
|
+
*
|
|
71
|
+
* // Each frame — who sees who:
|
|
72
|
+
* const visionEvents = sensors.detectVision(onlineNPCs);
|
|
73
|
+
* for (const event of visionEvents) {
|
|
74
|
+
* memoryBanks.get(event.observerId)?.add({ ... });
|
|
75
|
+
* }
|
|
76
|
+
*
|
|
77
|
+
* // On shot fired — who hears it:
|
|
78
|
+
* const soundEvents = sensors.detectSound(shootPos, 500, shooterId, shooterFaction, onlineNPCs);
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
export declare class NPCSensors {
|
|
82
|
+
private readonly _grid;
|
|
83
|
+
private readonly _isHostile;
|
|
84
|
+
private readonly _isLOSClear;
|
|
85
|
+
constructor(config: INPCSensorsConfig);
|
|
86
|
+
/**
|
|
87
|
+
* Vision sensor — for each living NPC: query nearby candidates via SpatialGrid,
|
|
88
|
+
* apply FOV cone check, emit detection events for visible hostile targets.
|
|
89
|
+
*
|
|
90
|
+
* Builds an id→entity index once at O(n), then candidate lookup is O(1).
|
|
91
|
+
* Overall complexity: O(n * k) where n = observers, k = avg candidates per vision radius.
|
|
92
|
+
*
|
|
93
|
+
* NOTE: SpatialGrid.queryRadius() returns a scratch array that is reused between
|
|
94
|
+
* calls. Results are copied per observer to avoid aliasing issues.
|
|
95
|
+
*/
|
|
96
|
+
detectVision(observers: readonly IPerceptibleEntity[]): IDetectionEvent[];
|
|
97
|
+
/**
|
|
98
|
+
* Sound sensor — detect all NPCs that hear a sound event.
|
|
99
|
+
*
|
|
100
|
+
* Sound is omnidirectional (no FOV cone). Confidence decays linearly with distance.
|
|
101
|
+
* Both hostile and friendly entities can hear the sound.
|
|
102
|
+
*
|
|
103
|
+
* O(h) where h = hearer count.
|
|
104
|
+
*
|
|
105
|
+
* @param sourcePos - World-space origin of the sound.
|
|
106
|
+
* @param soundRange - Maximum propagation range in world units.
|
|
107
|
+
* @param sourceId - Entity id of the sound source (excluded from results).
|
|
108
|
+
* @param _sourceFactionId - Faction of the sound source (unused — sound is omnidirectional).
|
|
109
|
+
* @param hearers - Candidate entities that may hear the sound.
|
|
110
|
+
*/
|
|
111
|
+
detectSound(sourcePos: Vec2, soundRange: number, sourceId: string, _sourceFactionId: string, hearers: readonly IPerceptibleEntity[]): IDetectionEvent[];
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Filter squad-shared target intel by freshness.
|
|
115
|
+
* Returns only targets seen within `freshnessMs` milliseconds.
|
|
116
|
+
*
|
|
117
|
+
* @param sharedTargets - Targets shared by squad members.
|
|
118
|
+
* @param currentTimeMs - Current game time in ms.
|
|
119
|
+
* @param freshnessMs - Max age of intel (default: 5000ms).
|
|
120
|
+
*/
|
|
121
|
+
export declare function filterFreshIntel(sharedTargets: ReadonlyArray<{
|
|
122
|
+
id: string;
|
|
123
|
+
position: Vec2;
|
|
124
|
+
lastSeenMs: number;
|
|
125
|
+
}>, currentTimeMs: number, freshnessMs?: number): ReadonlyArray<{
|
|
126
|
+
id: string;
|
|
127
|
+
position: Vec2;
|
|
128
|
+
}>;
|
|
129
|
+
//# sourceMappingURL=NPCSensors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NPCSensors.d.ts","sourceRoot":"","sources":["../../src/perception/NPCSensors.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAOnD;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,yDAAyD;IACzD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,8CAA8C;IAC9C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,sFAAsF;IACtF,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,4CAA4C;IAC5C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED,yDAAyD;AACzD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,cAAc,EAAE,IAAI,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC;IACrC;;;;OAIG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,WAAW,EAAE,WAAW,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,IAAI,CAAA;KAAE,CAAC,CAAC;IACzD,uEAAuE;IACvE,SAAS,EAAE,CAAC,eAAe,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,KAAK,OAAO,CAAC;IACvE;;;;;;;;;;;;OAYG;IACH,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,KAAK,OAAO,CAAC;CACxD;AAMD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA8C;IACpE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAoC;IAC/D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAkD;gBAElE,MAAM,EAAE,iBAAiB;IAMrC;;;;;;;;;OASG;IACH,YAAY,CAAC,SAAS,EAAE,SAAS,kBAAkB,EAAE,GAAG,eAAe,EAAE;IA4CzE;;;;;;;;;;;;;OAaG;IACH,WAAW,CACT,SAAS,EAAE,IAAI,EACf,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,gBAAgB,EAAE,MAAM,EACxB,OAAO,EAAE,SAAS,kBAAkB,EAAE,GACrC,eAAe,EAAE;CA+BrB;AAMD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,aAAa,EAAE,aAAa,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,IAAI,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,EAChF,aAAa,EAAE,MAAM,EACrB,WAAW,SAAO,GACjB,aAAa,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,IAAI,CAAA;CAAE,CAAC,CAQ/C"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
// perception/NPCSensors.ts
|
|
2
|
+
// NPC vision and hearing sensors — scene-level coordinator.
|
|
3
|
+
//
|
|
4
|
+
// Uses SpatialGrid for O(k) candidate lookup instead of O(n) full scan.
|
|
5
|
+
// Returns IDetectionEvent[] — caller decides what to do (write to MemoryBank, emit events, etc.).
|
|
6
|
+
//
|
|
7
|
+
// Pure deterministic logic — no side effects, no EventBus dependency.
|
|
8
|
+
import { isInFOV, distanceSq } from './PerceptionQuery';
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// NPCSensors
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
/**
|
|
13
|
+
* NPC vision and hearing sensors.
|
|
14
|
+
*
|
|
15
|
+
* Two sensors:
|
|
16
|
+
* - **Vision** (`detectVision`): FOV cone per NPC, hostile-only, O(n×k) via SpatialGrid.
|
|
17
|
+
* - **Sound** (`detectSound`): omnidirectional from a source, all factions hear it, confidence decays with distance.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* const sensors = new NPCSensors({ spatialGrid, isHostile });
|
|
22
|
+
*
|
|
23
|
+
* // Each frame — who sees who:
|
|
24
|
+
* const visionEvents = sensors.detectVision(onlineNPCs);
|
|
25
|
+
* for (const event of visionEvents) {
|
|
26
|
+
* memoryBanks.get(event.observerId)?.add({ ... });
|
|
27
|
+
* }
|
|
28
|
+
*
|
|
29
|
+
* // On shot fired — who hears it:
|
|
30
|
+
* const soundEvents = sensors.detectSound(shootPos, 500, shooterId, shooterFaction, onlineNPCs);
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export class NPCSensors {
|
|
34
|
+
constructor(config) {
|
|
35
|
+
this._grid = config.spatialGrid;
|
|
36
|
+
this._isHostile = config.isHostile;
|
|
37
|
+
this._isLOSClear = config.isLineOfSightClear;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Vision sensor — for each living NPC: query nearby candidates via SpatialGrid,
|
|
41
|
+
* apply FOV cone check, emit detection events for visible hostile targets.
|
|
42
|
+
*
|
|
43
|
+
* Builds an id→entity index once at O(n), then candidate lookup is O(1).
|
|
44
|
+
* Overall complexity: O(n * k) where n = observers, k = avg candidates per vision radius.
|
|
45
|
+
*
|
|
46
|
+
* NOTE: SpatialGrid.queryRadius() returns a scratch array that is reused between
|
|
47
|
+
* calls. Results are copied per observer to avoid aliasing issues.
|
|
48
|
+
*/
|
|
49
|
+
detectVision(observers) {
|
|
50
|
+
const results = [];
|
|
51
|
+
// Build id→entity index once — O(n), gives O(1) candidate lookup
|
|
52
|
+
const entityMap = new Map();
|
|
53
|
+
for (const e of observers)
|
|
54
|
+
entityMap.set(e.id, e);
|
|
55
|
+
for (const observer of observers) {
|
|
56
|
+
if (!observer.isAlive)
|
|
57
|
+
continue;
|
|
58
|
+
// queryRadius returns a scratch array — copy immediately to avoid aliasing
|
|
59
|
+
const candidates = [...this._grid.queryRadius(observer.position, observer.visionRange)];
|
|
60
|
+
for (const cell of candidates) {
|
|
61
|
+
if (cell.id === observer.id)
|
|
62
|
+
continue;
|
|
63
|
+
const target = entityMap.get(cell.id);
|
|
64
|
+
if (!target || !target.isAlive)
|
|
65
|
+
continue;
|
|
66
|
+
if (!this._isHostile(observer.factionId, target.factionId))
|
|
67
|
+
continue;
|
|
68
|
+
if (!isInFOV(observer.position, observer.facingAngle, target.position, observer.visionRange, observer.visionHalfAngle))
|
|
69
|
+
continue;
|
|
70
|
+
// LOS obstacle check — optional, skipped when not configured
|
|
71
|
+
if (this._isLOSClear && !this._isLOSClear(observer.position, target.position))
|
|
72
|
+
continue;
|
|
73
|
+
results.push({
|
|
74
|
+
observerId: observer.id,
|
|
75
|
+
targetId: target.id,
|
|
76
|
+
targetPosition: target.position,
|
|
77
|
+
channel: 'visual',
|
|
78
|
+
confidence: 1.0,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return results;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Sound sensor — detect all NPCs that hear a sound event.
|
|
86
|
+
*
|
|
87
|
+
* Sound is omnidirectional (no FOV cone). Confidence decays linearly with distance.
|
|
88
|
+
* Both hostile and friendly entities can hear the sound.
|
|
89
|
+
*
|
|
90
|
+
* O(h) where h = hearer count.
|
|
91
|
+
*
|
|
92
|
+
* @param sourcePos - World-space origin of the sound.
|
|
93
|
+
* @param soundRange - Maximum propagation range in world units.
|
|
94
|
+
* @param sourceId - Entity id of the sound source (excluded from results).
|
|
95
|
+
* @param _sourceFactionId - Faction of the sound source (unused — sound is omnidirectional).
|
|
96
|
+
* @param hearers - Candidate entities that may hear the sound.
|
|
97
|
+
*/
|
|
98
|
+
detectSound(sourcePos, soundRange, sourceId, _sourceFactionId, hearers) {
|
|
99
|
+
if (soundRange <= 0)
|
|
100
|
+
return [];
|
|
101
|
+
const results = [];
|
|
102
|
+
const soundRangeSq = soundRange * soundRange;
|
|
103
|
+
for (const hearer of hearers) {
|
|
104
|
+
if (!hearer.isAlive)
|
|
105
|
+
continue;
|
|
106
|
+
if (hearer.id === sourceId)
|
|
107
|
+
continue;
|
|
108
|
+
const dSq = distanceSq(hearer.position, sourcePos);
|
|
109
|
+
const hearRangeSq = hearer.hearingRange * hearer.hearingRange;
|
|
110
|
+
// Must be within both sound propagation range AND hearer's hearing range
|
|
111
|
+
if (dSq > soundRangeSq || dSq > hearRangeSq)
|
|
112
|
+
continue;
|
|
113
|
+
// Linear confidence decay: 1.0 at source, 0.0 at soundRange
|
|
114
|
+
const dist = Math.sqrt(dSq);
|
|
115
|
+
const confidence = Math.max(0, 1.0 - dist / soundRange);
|
|
116
|
+
results.push({
|
|
117
|
+
observerId: hearer.id,
|
|
118
|
+
targetId: sourceId,
|
|
119
|
+
targetPosition: sourcePos,
|
|
120
|
+
channel: 'sound',
|
|
121
|
+
confidence,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
return results;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// ---------------------------------------------------------------------------
|
|
128
|
+
// Utility
|
|
129
|
+
// ---------------------------------------------------------------------------
|
|
130
|
+
/**
|
|
131
|
+
* Filter squad-shared target intel by freshness.
|
|
132
|
+
* Returns only targets seen within `freshnessMs` milliseconds.
|
|
133
|
+
*
|
|
134
|
+
* @param sharedTargets - Targets shared by squad members.
|
|
135
|
+
* @param currentTimeMs - Current game time in ms.
|
|
136
|
+
* @param freshnessMs - Max age of intel (default: 5000ms).
|
|
137
|
+
*/
|
|
138
|
+
export function filterFreshIntel(sharedTargets, currentTimeMs, freshnessMs = 5000) {
|
|
139
|
+
const result = [];
|
|
140
|
+
for (const t of sharedTargets) {
|
|
141
|
+
if (currentTimeMs - t.lastSeenMs <= freshnessMs) {
|
|
142
|
+
result.push({ id: t.id, position: t.position });
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return result;
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=NPCSensors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"NPCSensors.js","sourceRoot":"","sources":["../../src/perception/NPCSensors.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { Vec2 } from '@alife-sdk/core';
|
|
2
|
+
import type { IPerceivedEntity, IPerceptionConfig } from '../types/IPerceptionTypes';
|
|
3
|
+
/**
|
|
4
|
+
* Check if a target is within a vision cone.
|
|
5
|
+
*
|
|
6
|
+
* Uses squared-distance for the range check (no sqrt).
|
|
7
|
+
* The vision cone is defined by a half-angle from the facing direction.
|
|
8
|
+
*
|
|
9
|
+
* @returns true if target is within range AND within the cone angle
|
|
10
|
+
*/
|
|
11
|
+
export declare function isInFOV(origin: Vec2, facingAngle: number, target: Vec2, visionRange: number, visionHalfAngle: number): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Filter entities that are visible to the observer.
|
|
14
|
+
*
|
|
15
|
+
* Combines FOV cone test with alive check.
|
|
16
|
+
* O(n) where n = candidate count.
|
|
17
|
+
* Precomputes trig values once per call (same pattern as scanForEnemies).
|
|
18
|
+
* Returns a reusable scratch array — do not hold a reference across calls.
|
|
19
|
+
*/
|
|
20
|
+
export declare function filterVisibleEntities(origin: Vec2, facingAngle: number, candidates: readonly IPerceivedEntity[], config: IPerceptionConfig): IPerceivedEntity[];
|
|
21
|
+
/**
|
|
22
|
+
* Filter entities that can hear a sound from a source.
|
|
23
|
+
*
|
|
24
|
+
* Sound is omnidirectional — no cone test, just distance.
|
|
25
|
+
* Uses squared-distance for performance.
|
|
26
|
+
* Returns a reusable scratch array — do not hold a reference across calls.
|
|
27
|
+
*
|
|
28
|
+
* @param source - Sound origin point
|
|
29
|
+
* @param soundRange - Maximum propagation range (px)
|
|
30
|
+
* @param entities - All candidate listeners
|
|
31
|
+
* @param hearingRange - Per-listener hearing range (overrides soundRange if smaller)
|
|
32
|
+
*/
|
|
33
|
+
export declare function filterHearingEntities(source: Vec2, soundRange: number, entities: readonly IPerceivedEntity[], hearingRange?: number): IPerceivedEntity[];
|
|
34
|
+
/**
|
|
35
|
+
* Filter entities by faction hostility.
|
|
36
|
+
* Returns a reusable scratch array — do not hold a reference across calls.
|
|
37
|
+
*
|
|
38
|
+
* @param entities - Entity candidates
|
|
39
|
+
* @param observerFactionId - The observer's faction
|
|
40
|
+
* @param isHostile - Callback checking if two factions are hostile
|
|
41
|
+
*/
|
|
42
|
+
export declare function filterHostileEntities(entities: readonly IPerceivedEntity[], observerFactionId: string, isHostile: (factionA: string, factionB: string) => boolean): IPerceivedEntity[];
|
|
43
|
+
/**
|
|
44
|
+
* Filter entities that are friendlies (same faction OR non-hostile).
|
|
45
|
+
* Returns a reusable scratch array — do not hold a reference across calls.
|
|
46
|
+
*/
|
|
47
|
+
export declare function filterFriendlyEntities(entities: readonly IPerceivedEntity[], observerFactionId: string, isHostile: (factionA: string, factionB: string) => boolean): IPerceivedEntity[];
|
|
48
|
+
/**
|
|
49
|
+
* Calculate squared distance between two points.
|
|
50
|
+
* Avoid sqrt when only comparing relative distances.
|
|
51
|
+
*/
|
|
52
|
+
export declare function distanceSq(a: Vec2, b: Vec2): number;
|
|
53
|
+
/**
|
|
54
|
+
* Find the closest entity to a position.
|
|
55
|
+
* Returns null if array is empty.
|
|
56
|
+
*/
|
|
57
|
+
export declare function findClosest(origin: Vec2, entities: readonly IPerceivedEntity[]): IPerceivedEntity | null;
|
|
58
|
+
/**
|
|
59
|
+
* Full perception scan: find visible hostile entities.
|
|
60
|
+
*
|
|
61
|
+
* Combines FOV filtering + faction filtering in a single pass.
|
|
62
|
+
* This is the primary query used by GOAP world state building.
|
|
63
|
+
*/
|
|
64
|
+
export declare function scanForEnemies(origin: Vec2, facingAngle: number, candidates: readonly IPerceivedEntity[], observerFactionId: string, isHostile: (factionA: string, factionB: string) => boolean, config: IPerceptionConfig): IPerceivedEntity[];
|
|
65
|
+
//# sourceMappingURL=PerceptionQuery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PerceptionQuery.d.ts","sourceRoot":"","sources":["../../src/perception/PerceptionQuery.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAWrF;;;;;;;GAOG;AACH,wBAAgB,OAAO,CACrB,MAAM,EAAE,IAAI,EACZ,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,IAAI,EACZ,WAAW,EAAE,MAAM,EACnB,eAAe,EAAE,MAAM,GACtB,OAAO,CAgBT;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,IAAI,EACZ,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,SAAS,gBAAgB,EAAE,EACvC,MAAM,EAAE,iBAAiB,GACxB,gBAAgB,EAAE,CA8BpB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,IAAI,EACZ,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,SAAS,gBAAgB,EAAE,EACrC,YAAY,CAAC,EAAE,MAAM,GACpB,gBAAgB,EAAE,CAiBpB;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,SAAS,gBAAgB,EAAE,EACrC,iBAAiB,EAAE,MAAM,EACzB,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,GACzD,gBAAgB,EAAE,CASpB;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,SAAS,gBAAgB,EAAE,EACrC,iBAAiB,EAAE,MAAM,EACzB,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,GACzD,gBAAgB,EAAE,CAYpB;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,GAAG,MAAM,CAInD;AAED;;;GAGG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,IAAI,EACZ,QAAQ,EAAE,SAAS,gBAAgB,EAAE,GACpC,gBAAgB,GAAG,IAAI,CAazB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,IAAI,EACZ,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,SAAS,gBAAgB,EAAE,EACvC,iBAAiB,EAAE,MAAM,EACzB,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,EAC1D,MAAM,EAAE,iBAAiB,GACxB,gBAAgB,EAAE,CAgCpB"}
|