@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,147 @@
|
|
|
1
|
+
import { createDefaultTransitionMap } from '../IStateTransitionMap';
|
|
2
|
+
import { moveToward } from './_utils';
|
|
3
|
+
/**
|
|
4
|
+
* Stateless five-phase kill-wounded handler (X-Ray 16 `stalker_kill_wounded` equivalent).
|
|
5
|
+
*
|
|
6
|
+
* A single instance can be shared across all NPC entities.
|
|
7
|
+
*
|
|
8
|
+
* Opt-in activation (add to the handler registry):
|
|
9
|
+
* ```ts
|
|
10
|
+
* const handlers = buildDefaultHandlerMap(cfg, {
|
|
11
|
+
* combatOnKillWounded: 'KILL_WOUNDED',
|
|
12
|
+
* alertOnKillWounded: 'KILL_WOUNDED',
|
|
13
|
+
* });
|
|
14
|
+
* handlers.register('KILL_WOUNDED', new KillWoundedState(cfg));
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export class KillWoundedState {
|
|
18
|
+
constructor(cfg, tr) {
|
|
19
|
+
this.cfg = cfg;
|
|
20
|
+
this.tr = createDefaultTransitionMap(tr);
|
|
21
|
+
}
|
|
22
|
+
enter(ctx) {
|
|
23
|
+
ctx.state.killWoundedStartMs = ctx.now();
|
|
24
|
+
ctx.state.killWoundedAimStartMs = -1;
|
|
25
|
+
ctx.state.killWoundedTauntStartMs = -1;
|
|
26
|
+
ctx.state.killWoundedExecuteStartMs = -1;
|
|
27
|
+
ctx.state.killWoundedShotsFired = 0;
|
|
28
|
+
ctx.state.killWoundedPauseStartMs = -1;
|
|
29
|
+
ctx.halt();
|
|
30
|
+
}
|
|
31
|
+
update(ctx, _deltaMs) {
|
|
32
|
+
const now = ctx.now();
|
|
33
|
+
// ── Priority: panic → flee ───────────────────────────────────────────────
|
|
34
|
+
if (ctx.state.moraleState === 'PANICKED') {
|
|
35
|
+
ctx.halt();
|
|
36
|
+
ctx.transition(this.tr.killWoundedOnPanic);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
// ── PAUSE phase ───────────────────────────────────────────────────────────
|
|
40
|
+
if (ctx.state.killWoundedPauseStartMs >= 0) {
|
|
41
|
+
ctx.halt();
|
|
42
|
+
if (now - ctx.state.killWoundedPauseStartMs >= this.cfg.killWoundedPauseMs) {
|
|
43
|
+
if (ctx.perception?.hasVisibleEnemy()) {
|
|
44
|
+
ctx.transition(this.tr.killWoundedOnComplete); // new threat → COMBAT
|
|
45
|
+
}
|
|
46
|
+
else if (ctx.state.lastKnownEnemyX !== 0 || ctx.state.lastKnownEnemyY !== 0) {
|
|
47
|
+
ctx.transition(this.tr.killWoundedOnNoTarget); // last position known → SEARCH
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
ctx.transition(this.tr.killWoundedOnComplete); // nothing → COMBAT fallback
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
// ── EXECUTE phase ─────────────────────────────────────────────────────────
|
|
56
|
+
if (ctx.state.killWoundedExecuteStartMs >= 0) {
|
|
57
|
+
ctx.halt();
|
|
58
|
+
ctx.setRotation(Math.atan2(ctx.state.killWoundedTargetY - ctx.y, ctx.state.killWoundedTargetX - ctx.x));
|
|
59
|
+
if (ctx.state.killWoundedShotsFired >= this.cfg.killWoundedBurstCount) {
|
|
60
|
+
// All shots fired → move to pause
|
|
61
|
+
ctx.state.killWoundedPauseStartMs = now;
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
// Fire next shot when cooldown elapsed
|
|
65
|
+
if (now - ctx.state.lastShootMs >= this.cfg.fireRateMs) {
|
|
66
|
+
ctx.state.lastShootMs = now;
|
|
67
|
+
ctx.state.killWoundedShotsFired++;
|
|
68
|
+
ctx.emitShoot({
|
|
69
|
+
npcId: ctx.npcId,
|
|
70
|
+
x: ctx.x,
|
|
71
|
+
y: ctx.y,
|
|
72
|
+
targetX: ctx.state.killWoundedTargetX,
|
|
73
|
+
targetY: ctx.state.killWoundedTargetY,
|
|
74
|
+
weaponType: ctx.state.primaryWeapon ?? 'pistol',
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
// ── TAUNT phase ───────────────────────────────────────────────────────────
|
|
80
|
+
if (ctx.state.killWoundedTauntStartMs >= 0) {
|
|
81
|
+
ctx.halt();
|
|
82
|
+
if (now - ctx.state.killWoundedTauntStartMs >= this.cfg.killWoundedTauntMs) {
|
|
83
|
+
ctx.state.killWoundedExecuteStartMs = now;
|
|
84
|
+
ctx.state.killWoundedShotsFired = 0;
|
|
85
|
+
}
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
// ── AIM phase ─────────────────────────────────────────────────────────────
|
|
89
|
+
if (ctx.state.killWoundedAimStartMs >= 0) {
|
|
90
|
+
ctx.halt();
|
|
91
|
+
ctx.setRotation(Math.atan2(ctx.state.killWoundedTargetY - ctx.y, ctx.state.killWoundedTargetX - ctx.x));
|
|
92
|
+
if (now - ctx.state.killWoundedAimStartMs >= this.cfg.killWoundedAimMs) {
|
|
93
|
+
ctx.emitVocalization('KILL_WOUNDED_TAUNT');
|
|
94
|
+
ctx.state.killWoundedTauntStartMs = now;
|
|
95
|
+
}
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
// ── APPROACH phase ────────────────────────────────────────────────────────
|
|
99
|
+
// Overall approach timeout
|
|
100
|
+
if (now - ctx.state.killWoundedStartMs >= this.cfg.killWoundedMaxApproachMs) {
|
|
101
|
+
ctx.halt();
|
|
102
|
+
ctx.transition(this.tr.killWoundedOnTimeout);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
// Refresh target position from live perception
|
|
106
|
+
const woundedEnemies = ctx.perception?.getWoundedEnemies?.() ?? [];
|
|
107
|
+
const target = woundedEnemies.find(e => e.id === ctx.state.killWoundedTargetId) ?? null;
|
|
108
|
+
if (!target) {
|
|
109
|
+
// Target healed, died, or left perception range
|
|
110
|
+
ctx.halt();
|
|
111
|
+
if (ctx.perception?.hasVisibleEnemy()) {
|
|
112
|
+
ctx.transition(this.tr.killWoundedOnComplete); // still enemies → COMBAT
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
ctx.transition(this.tr.killWoundedOnNoTarget); // no one → SEARCH
|
|
116
|
+
}
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
// Keep destination current (wounded enemy may crawl)
|
|
120
|
+
ctx.state.killWoundedTargetX = target.x;
|
|
121
|
+
ctx.state.killWoundedTargetY = target.y;
|
|
122
|
+
// Arrival check → begin AIM
|
|
123
|
+
const dx = target.x - ctx.x;
|
|
124
|
+
const dy = target.y - ctx.y;
|
|
125
|
+
const distSq = dx * dx + dy * dy;
|
|
126
|
+
const range = this.cfg.killWoundedExecuteRange;
|
|
127
|
+
if (distSq <= range * range) {
|
|
128
|
+
ctx.halt();
|
|
129
|
+
ctx.state.killWoundedAimStartMs = now;
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
moveToward(ctx, target.x, target.y, this.cfg.approachSpeed);
|
|
133
|
+
}
|
|
134
|
+
exit(ctx) {
|
|
135
|
+
ctx.state.killWoundedTargetId = null;
|
|
136
|
+
ctx.state.killWoundedStartMs = 0;
|
|
137
|
+
ctx.state.killWoundedAimStartMs = -1;
|
|
138
|
+
ctx.state.killWoundedTauntStartMs = -1;
|
|
139
|
+
ctx.state.killWoundedExecuteStartMs = -1;
|
|
140
|
+
ctx.state.killWoundedShotsFired = 0;
|
|
141
|
+
ctx.state.killWoundedPauseStartMs = -1;
|
|
142
|
+
ctx.state.killWoundedTargetX = 0;
|
|
143
|
+
ctx.state.killWoundedTargetY = 0;
|
|
144
|
+
ctx.halt();
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=KillWoundedState.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"KillWoundedState.js","sourceRoot":"","sources":["../../../src/states/handlers/KillWoundedState.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,0BAA0B,EAAE,MAAO,wBAAwB,CAAC;AAErE,OAAO,EAAE,UAAU,EAAE,MAAuB,UAAU,CAAC;AAEvD;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,gBAAgB;IAI3B,YAAY,GAAiB,EAAE,EAAiC;QAC9D,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,EAAE,GAAI,0BAA0B,CAAC,EAAE,CAAC,CAAC;IAC5C,CAAC;IAED,KAAK,CAAC,GAAgB;QACpB,GAAG,CAAC,KAAK,CAAC,kBAAkB,GAAS,GAAG,CAAC,GAAG,EAAE,CAAC;QAC/C,GAAG,CAAC,KAAK,CAAC,qBAAqB,GAAM,CAAC,CAAC,CAAC;QACxC,GAAG,CAAC,KAAK,CAAC,uBAAuB,GAAI,CAAC,CAAC,CAAC;QACxC,GAAG,CAAC,KAAK,CAAC,yBAAyB,GAAG,CAAC,CAAC,CAAC;QACzC,GAAG,CAAC,KAAK,CAAC,qBAAqB,GAAM,CAAC,CAAC;QACvC,GAAG,CAAC,KAAK,CAAC,uBAAuB,GAAI,CAAC,CAAC,CAAC;QACxC,GAAG,CAAC,IAAI,EAAE,CAAC;IACb,CAAC;IAED,MAAM,CAAC,GAAgB,EAAE,QAAgB;QACvC,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC;QAEtB,4EAA4E;QAC5E,IAAI,GAAG,CAAC,KAAK,CAAC,WAAW,KAAK,UAAU,EAAE,CAAC;YACzC,GAAG,CAAC,IAAI,EAAE,CAAC;YACX,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC;YAC3C,OAAO;QACT,CAAC;QAED,6EAA6E;QAC7E,IAAI,GAAG,CAAC,KAAK,CAAC,uBAAuB,IAAI,CAAC,EAAE,CAAC;YAC3C,GAAG,CAAC,IAAI,EAAE,CAAC;YACX,IAAI,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,uBAAuB,IAAI,IAAI,CAAC,GAAG,CAAC,kBAAkB,EAAE,CAAC;gBAC3E,IAAI,GAAG,CAAC,UAAU,EAAE,eAAe,EAAE,EAAE,CAAC;oBACtC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,qBAAqB,CAAC,CAAC,CAAG,sBAAsB;gBACzE,CAAC;qBAAM,IAAI,GAAG,CAAC,KAAK,CAAC,eAAe,KAAK,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC,eAAe,KAAK,CAAC,EAAE,CAAC;oBAC9E,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,qBAAqB,CAAC,CAAC,CAAG,+BAA+B;gBAClF,CAAC;qBAAM,CAAC;oBACN,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,qBAAqB,CAAC,CAAC,CAAG,4BAA4B;gBAC/E,CAAC;YACH,CAAC;YACD,OAAO;QACT,CAAC;QAED,6EAA6E;QAC7E,IAAI,GAAG,CAAC,KAAK,CAAC,yBAAyB,IAAI,CAAC,EAAE,CAAC;YAC7C,GAAG,CAAC,IAAI,EAAE,CAAC;YACX,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CACxB,GAAG,CAAC,KAAK,CAAC,kBAAkB,GAAG,GAAG,CAAC,CAAC,EACpC,GAAG,CAAC,KAAK,CAAC,kBAAkB,GAAG,GAAG,CAAC,CAAC,CACrC,CAAC,CAAC;YAEH,IAAI,GAAG,CAAC,KAAK,CAAC,qBAAqB,IAAI,IAAI,CAAC,GAAG,CAAC,qBAAqB,EAAE,CAAC;gBACtE,kCAAkC;gBAClC,GAAG,CAAC,KAAK,CAAC,uBAAuB,GAAG,GAAG,CAAC;gBACxC,OAAO;YACT,CAAC;YAED,uCAAuC;YACvC,IAAI,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,WAAW,IAAI,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC;gBACvD,GAAG,CAAC,KAAK,CAAC,WAAW,GAAG,GAAG,CAAC;gBAC5B,GAAG,CAAC,KAAK,CAAC,qBAAqB,EAAE,CAAC;gBAClC,GAAG,CAAC,SAAS,CAAC;oBACZ,KAAK,EAAK,GAAG,CAAC,KAAK;oBACnB,CAAC,EAAS,GAAG,CAAC,CAAC;oBACf,CAAC,EAAS,GAAG,CAAC,CAAC;oBACf,OAAO,EAAG,GAAG,CAAC,KAAK,CAAC,kBAAkB;oBACtC,OAAO,EAAG,GAAG,CAAC,KAAK,CAAC,kBAAkB;oBACtC,UAAU,EAAE,GAAG,CAAC,KAAK,CAAC,aAAa,IAAI,QAAQ;iBAChD,CAAC,CAAC;YACL,CAAC;YACD,OAAO;QACT,CAAC;QAED,6EAA6E;QAC7E,IAAI,GAAG,CAAC,KAAK,CAAC,uBAAuB,IAAI,CAAC,EAAE,CAAC;YAC3C,GAAG,CAAC,IAAI,EAAE,CAAC;YACX,IAAI,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,uBAAuB,IAAI,IAAI,CAAC,GAAG,CAAC,kBAAkB,EAAE,CAAC;gBAC3E,GAAG,CAAC,KAAK,CAAC,yBAAyB,GAAG,GAAG,CAAC;gBAC1C,GAAG,CAAC,KAAK,CAAC,qBAAqB,GAAO,CAAC,CAAC;YAC1C,CAAC;YACD,OAAO;QACT,CAAC;QAED,6EAA6E;QAC7E,IAAI,GAAG,CAAC,KAAK,CAAC,qBAAqB,IAAI,CAAC,EAAE,CAAC;YACzC,GAAG,CAAC,IAAI,EAAE,CAAC;YACX,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CACxB,GAAG,CAAC,KAAK,CAAC,kBAAkB,GAAG,GAAG,CAAC,CAAC,EACpC,GAAG,CAAC,KAAK,CAAC,kBAAkB,GAAG,GAAG,CAAC,CAAC,CACrC,CAAC,CAAC;YACH,IAAI,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,qBAAqB,IAAI,IAAI,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;gBACvE,GAAG,CAAC,gBAAgB,CAAC,oBAAoB,CAAC,CAAC;gBAC3C,GAAG,CAAC,KAAK,CAAC,uBAAuB,GAAG,GAAG,CAAC;YAC1C,CAAC;YACD,OAAO;QACT,CAAC;QAED,6EAA6E;QAE7E,2BAA2B;QAC3B,IAAI,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,kBAAkB,IAAI,IAAI,CAAC,GAAG,CAAC,wBAAwB,EAAE,CAAC;YAC5E,GAAG,CAAC,IAAI,EAAE,CAAC;YACX,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,oBAAoB,CAAC,CAAC;YAC7C,OAAO;QACT,CAAC;QAED,+CAA+C;QAC/C,MAAM,cAAc,GAAG,GAAG,CAAC,UAAU,EAAE,iBAAiB,EAAE,EAAE,IAAI,EAAE,CAAC;QACnE,MAAM,MAAM,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,KAAK,CAAC,mBAAmB,CAAC,IAAI,IAAI,CAAC;QAExF,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,gDAAgD;YAChD,GAAG,CAAC,IAAI,EAAE,CAAC;YACX,IAAI,GAAG,CAAC,UAAU,EAAE,eAAe,EAAE,EAAE,CAAC;gBACtC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,qBAAqB,CAAC,CAAC,CAAG,yBAAyB;YAC5E,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,qBAAqB,CAAC,CAAC,CAAG,kBAAkB;YACrE,CAAC;YACD,OAAO;QACT,CAAC;QAED,qDAAqD;QACrD,GAAG,CAAC,KAAK,CAAC,kBAAkB,GAAG,MAAM,CAAC,CAAC,CAAC;QACxC,GAAG,CAAC,KAAK,CAAC,kBAAkB,GAAG,MAAM,CAAC,CAAC,CAAC;QAExC,4BAA4B;QAC5B,MAAM,EAAE,GAAO,MAAM,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;QAChC,MAAM,EAAE,GAAO,MAAM,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;QAChC,MAAM,MAAM,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;QACjC,MAAM,KAAK,GAAI,IAAI,CAAC,GAAG,CAAC,uBAAuB,CAAC;QAEhD,IAAI,MAAM,IAAI,KAAK,GAAG,KAAK,EAAE,CAAC;YAC5B,GAAG,CAAC,IAAI,EAAE,CAAC;YACX,GAAG,CAAC,KAAK,CAAC,qBAAqB,GAAG,GAAG,CAAC;YACtC,OAAO;QACT,CAAC;QAED,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IAC9D,CAAC;IAED,IAAI,CAAC,GAAgB;QACnB,GAAG,CAAC,KAAK,CAAC,mBAAmB,GAAU,IAAI,CAAC;QAC5C,GAAG,CAAC,KAAK,CAAC,kBAAkB,GAAW,CAAC,CAAC;QACzC,GAAG,CAAC,KAAK,CAAC,qBAAqB,GAAQ,CAAC,CAAC,CAAC;QAC1C,GAAG,CAAC,KAAK,CAAC,uBAAuB,GAAM,CAAC,CAAC,CAAC;QAC1C,GAAG,CAAC,KAAK,CAAC,yBAAyB,GAAI,CAAC,CAAC,CAAC;QAC1C,GAAG,CAAC,KAAK,CAAC,qBAAqB,GAAQ,CAAC,CAAC;QACzC,GAAG,CAAC,KAAK,CAAC,uBAAuB,GAAM,CAAC,CAAC,CAAC;QAC1C,GAAG,CAAC,KAAK,CAAC,kBAAkB,GAAW,CAAC,CAAC;QACzC,GAAG,CAAC,KAAK,CAAC,kBAAkB,GAAW,CAAC,CAAC;QACzC,GAAG,CAAC,IAAI,EAAE,CAAC;IACb,CAAC;CACF"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { IOnlineStateHandler } from '../IOnlineStateHandler';
|
|
2
|
+
import type { INPCContext } from '../INPCContext';
|
|
3
|
+
import type { IStateConfig } from '../IStateConfig';
|
|
4
|
+
import type { IStateTransitionMap } from '../IStateTransitionMap';
|
|
5
|
+
/**
|
|
6
|
+
* Stateless snork leap-attack handler.
|
|
7
|
+
*
|
|
8
|
+
* A single instance can be shared across all NPC entities.
|
|
9
|
+
*/
|
|
10
|
+
export declare class LeapState implements IOnlineStateHandler {
|
|
11
|
+
private readonly cfg;
|
|
12
|
+
private readonly tr;
|
|
13
|
+
constructor(cfg: IStateConfig, tr?: Partial<IStateTransitionMap>);
|
|
14
|
+
enter(ctx: INPCContext): void;
|
|
15
|
+
update(ctx: INPCContext, _deltaMs: number): void;
|
|
16
|
+
exit(ctx: INPCContext): void;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=LeapState.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LeapState.d.ts","sourceRoot":"","sources":["../../../src/states/handlers/LeapState.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAGlE;;;;GAIG;AACH,qBAAa,SAAU,YAAW,mBAAmB;IAIjD,OAAO,CAAC,QAAQ,CAAC,GAAG;IAHtB,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAsB;gBAGtB,GAAG,EAAE,YAAY,EAClC,EAAE,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC;IAKnC,KAAK,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI;IAoC7B,MAAM,CAAC,GAAG,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAiEhD,IAAI,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI;CAK7B"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
// states/handlers/LeapState.ts
|
|
2
|
+
// Snork jump-attack state — winds up then arcs through the air to land on target.
|
|
3
|
+
//
|
|
4
|
+
// Phase pipeline (stored in ctx.state.leapPhase):
|
|
5
|
+
// WINDUP — entity stops; counts down leapWindupMs; records start + target positions.
|
|
6
|
+
// AIRBORNE — entity position is teleported (lerped) from start → target over leapAirtimeMs.
|
|
7
|
+
// ctx.teleport() sets position directly to bypass normal velocity physics.
|
|
8
|
+
// airborne flag is set true once this phase begins.
|
|
9
|
+
// LAND — when airtime has fully elapsed: emitMeleeHit + transition (tr.leapOnLand).
|
|
10
|
+
//
|
|
11
|
+
// All mutable state lives in INPCOnlineState.leapPhase so this handler is
|
|
12
|
+
// stateless and safe to share across all NPC entities.
|
|
13
|
+
import { createDefaultTransitionMap } from '../IStateTransitionMap';
|
|
14
|
+
/**
|
|
15
|
+
* Stateless snork leap-attack handler.
|
|
16
|
+
*
|
|
17
|
+
* A single instance can be shared across all NPC entities.
|
|
18
|
+
*/
|
|
19
|
+
export class LeapState {
|
|
20
|
+
constructor(cfg, tr) {
|
|
21
|
+
this.cfg = cfg;
|
|
22
|
+
this.tr = createDefaultTransitionMap(tr);
|
|
23
|
+
}
|
|
24
|
+
enter(ctx) {
|
|
25
|
+
var _a;
|
|
26
|
+
const now = ctx.now();
|
|
27
|
+
// Lock target from first visible enemy or last known position.
|
|
28
|
+
const enemies = ctx.perception?.getVisibleEnemies() ?? [];
|
|
29
|
+
const targetX = enemies.length > 0 ? enemies[0].x : ctx.state.lastKnownEnemyX;
|
|
30
|
+
const targetY = enemies.length > 0 ? enemies[0].y : ctx.state.lastKnownEnemyY;
|
|
31
|
+
if (enemies.length > 0) {
|
|
32
|
+
ctx.state.lastKnownEnemyX = enemies[0].x;
|
|
33
|
+
ctx.state.lastKnownEnemyY = enemies[0].y;
|
|
34
|
+
ctx.state.targetId = enemies[0].id;
|
|
35
|
+
}
|
|
36
|
+
// Lazy-initialise leap phase data if not yet present.
|
|
37
|
+
(_a = ctx.state).leapPhase ?? (_a.leapPhase = { active: false, windupStartMs: 0, airborne: false, startX: 0, startY: 0, targetX: 0, targetY: 0, airStartMs: 0 });
|
|
38
|
+
ctx.state.leapPhase.active = true;
|
|
39
|
+
ctx.state.leapPhase.airborne = false;
|
|
40
|
+
ctx.state.leapPhase.windupStartMs = now;
|
|
41
|
+
ctx.state.leapPhase.airStartMs = 0;
|
|
42
|
+
ctx.state.leapPhase.startX = ctx.x;
|
|
43
|
+
ctx.state.leapPhase.startY = ctx.y;
|
|
44
|
+
ctx.state.leapPhase.targetX = targetX;
|
|
45
|
+
ctx.state.leapPhase.targetY = targetY;
|
|
46
|
+
// Stop and crouch during windup.
|
|
47
|
+
ctx.halt();
|
|
48
|
+
// Face target during windup telegraph.
|
|
49
|
+
const dx = targetX - ctx.x;
|
|
50
|
+
const dy = targetY - ctx.y;
|
|
51
|
+
if (dx !== 0 || dy !== 0) {
|
|
52
|
+
ctx.setRotation(Math.atan2(dy, dx));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
update(ctx, _deltaMs) {
|
|
56
|
+
const now = ctx.now();
|
|
57
|
+
const phase = ctx.state.leapPhase;
|
|
58
|
+
if (!phase.airborne) {
|
|
59
|
+
// -----------------------------------------------------------------------
|
|
60
|
+
// WINDUP phase — wait for leapWindupMs before launching leap
|
|
61
|
+
// -----------------------------------------------------------------------
|
|
62
|
+
const windupElapsed = now - phase.windupStartMs;
|
|
63
|
+
if (windupElapsed < this.cfg.leapWindupMs) {
|
|
64
|
+
// Still winding up — face target but don't move.
|
|
65
|
+
const dx = phase.targetX - ctx.x;
|
|
66
|
+
const dy = phase.targetY - ctx.y;
|
|
67
|
+
if (dx !== 0 || dy !== 0) {
|
|
68
|
+
ctx.setRotation(Math.atan2(dy, dx));
|
|
69
|
+
}
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
// Windup complete — begin airborne phase.
|
|
73
|
+
phase.airborne = true;
|
|
74
|
+
phase.airStartMs = now;
|
|
75
|
+
}
|
|
76
|
+
// -----------------------------------------------------------------------
|
|
77
|
+
// AIRBORNE phase — lerp position from start → target over leapAirtimeMs
|
|
78
|
+
// -----------------------------------------------------------------------
|
|
79
|
+
const airElapsed = now - phase.airStartMs;
|
|
80
|
+
if (airElapsed < this.cfg.leapAirtimeMs) {
|
|
81
|
+
// Lerp progress in [0, 1]; clamped so we never overshoot.
|
|
82
|
+
const progress = Math.min(1, airElapsed / this.cfg.leapAirtimeMs);
|
|
83
|
+
const lerpX = phase.startX + (phase.targetX - phase.startX) * progress;
|
|
84
|
+
const lerpY = phase.startY + (phase.targetY - phase.startY) * progress;
|
|
85
|
+
// Teleport sets world position directly — bypasses arcade velocity so
|
|
86
|
+
// the entity "flies" through the air ignoring normal collision response.
|
|
87
|
+
ctx.teleport(lerpX, lerpY);
|
|
88
|
+
// Face direction of travel during flight.
|
|
89
|
+
const dx = phase.targetX - lerpX;
|
|
90
|
+
const dy = phase.targetY - lerpY;
|
|
91
|
+
if (dx !== 0 || dy !== 0) {
|
|
92
|
+
ctx.setRotation(Math.atan2(dy, dx));
|
|
93
|
+
}
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
// -----------------------------------------------------------------------
|
|
97
|
+
// LAND — airtime elapsed: snap to target, apply damage, return to COMBAT
|
|
98
|
+
// -----------------------------------------------------------------------
|
|
99
|
+
ctx.teleport(phase.targetX, phase.targetY);
|
|
100
|
+
ctx.halt();
|
|
101
|
+
ctx.state.lastMeleeMs = now;
|
|
102
|
+
ctx.emitMeleeHit({
|
|
103
|
+
npcId: ctx.npcId,
|
|
104
|
+
targetId: ctx.state.targetId ?? '',
|
|
105
|
+
damage: this.cfg.meleeDamage,
|
|
106
|
+
});
|
|
107
|
+
ctx.transition(this.tr.leapOnLand);
|
|
108
|
+
}
|
|
109
|
+
exit(ctx) {
|
|
110
|
+
if (ctx.state.leapPhase) {
|
|
111
|
+
ctx.state.leapPhase.active = false;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=LeapState.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LeapState.js","sourceRoot":"","sources":["../../../src/states/handlers/LeapState.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { IOnlineStateHandler } from '../IOnlineStateHandler';
|
|
2
|
+
import type { INPCContext } from '../INPCContext';
|
|
3
|
+
import type { IStateConfig } from '../IStateConfig';
|
|
4
|
+
import type { IStateTransitionMap } from '../IStateTransitionMap';
|
|
5
|
+
/**
|
|
6
|
+
* Callback that selects a special ability state ID for a monster entity.
|
|
7
|
+
* Return null to continue basic melee combat.
|
|
8
|
+
*
|
|
9
|
+
* @param entityType - The NPC's entity type string (e.g., 'boar', 'zombie')
|
|
10
|
+
* @param dist - Current distance to the enemy
|
|
11
|
+
* @param cfg - Current state config (for meleeRange etc.)
|
|
12
|
+
* @returns State ID to transition to, or null to stay in combat
|
|
13
|
+
*/
|
|
14
|
+
export type MonsterAbilitySelector = (entityType: string, dist: number, cfg: IStateConfig) => string | null;
|
|
15
|
+
/**
|
|
16
|
+
* Chornobyl-style ability selector preset.
|
|
17
|
+
* boar→CHARGE, bloodsucker→STALK, snork→LEAP, controller→PSI_ATTACK.
|
|
18
|
+
*
|
|
19
|
+
* Pass this as `abilitySelector` to {@link MonsterCombatController} and
|
|
20
|
+
* register the corresponding ability states in your {@link StateHandlerMap}:
|
|
21
|
+
*
|
|
22
|
+
* ```ts
|
|
23
|
+
* const handlers = buildMonsterHandlerMap(cfg)
|
|
24
|
+
* .register(ONLINE_STATE.CHARGE, new ChargeState(cfg))
|
|
25
|
+
* .register(ONLINE_STATE.STALK, new StalkState(cfg))
|
|
26
|
+
* .register(ONLINE_STATE.LEAP, new LeapState(cfg))
|
|
27
|
+
* .register(ONLINE_STATE.PSI_ATTACK, new PsiAttackState(cfg));
|
|
28
|
+
*
|
|
29
|
+
* // Tell MonsterCombatController to use it:
|
|
30
|
+
* handlers.register(
|
|
31
|
+
* ONLINE_STATE.COMBAT,
|
|
32
|
+
* new MonsterCombatController(cfg, tr, CHORNOBYL_ABILITY_SELECTOR),
|
|
33
|
+
* );
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare const CHORNOBYL_ABILITY_SELECTOR: MonsterAbilitySelector;
|
|
37
|
+
/**
|
|
38
|
+
* Stateless monster melee combat handler.
|
|
39
|
+
*
|
|
40
|
+
* Shared across all monster entity types. Species-specific ability
|
|
41
|
+
* transitions are driven by an injectable {@link MonsterAbilitySelector}
|
|
42
|
+
* callback rather than a hardcoded switch — fully agnostic.
|
|
43
|
+
*
|
|
44
|
+
* A single instance can be shared across all NPC entities.
|
|
45
|
+
*/
|
|
46
|
+
export declare class MonsterCombatController implements IOnlineStateHandler {
|
|
47
|
+
private readonly cfg;
|
|
48
|
+
private readonly tr;
|
|
49
|
+
private readonly selectAbility;
|
|
50
|
+
constructor(cfg: IStateConfig, tr?: Partial<IStateTransitionMap>, abilitySelector?: MonsterAbilitySelector);
|
|
51
|
+
enter(_ctx: INPCContext): void;
|
|
52
|
+
update(ctx: INPCContext, _deltaMs: number): void;
|
|
53
|
+
exit(_ctx: INPCContext): void;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=MonsterCombatController.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MonsterCombatController.d.ts","sourceRoot":"","sources":["../../../src/states/handlers/MonsterCombatController.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAIlE;;;;;;;;GAQG;AACH,MAAM,MAAM,sBAAsB,GAAG,CACnC,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,YAAY,KACd,MAAM,GAAG,IAAI,CAAC;AAEnB;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,0BAA0B,EAAE,sBA4BxC,CAAC;AAEF;;;;;;;;GAQG;AACH,qBAAa,uBAAwB,YAAW,mBAAmB;IAK/D,OAAO,CAAC,QAAQ,CAAC,GAAG;IAJtB,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAsB;IACzC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAyB;gBAGpC,GAAG,EAAE,YAAY,EAClC,EAAE,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC,EACjC,eAAe,CAAC,EAAE,sBAAsB;IAM1C,KAAK,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI;IAK9B,MAAM,CAAC,GAAG,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IA8EhD,IAAI,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI;CAG9B"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
// states/handlers/MonsterCombatController.ts
|
|
2
|
+
// Base melee combat state handler for all monster types.
|
|
3
|
+
//
|
|
4
|
+
// Handles:
|
|
5
|
+
// - Moving toward the visible enemy at approachSpeed
|
|
6
|
+
// - Applying melee hits when within meleeRange (respects meleeCooldownMs)
|
|
7
|
+
// - Transitioning to species-specific ability states via MonsterAbilitySelector
|
|
8
|
+
// - Transitioning to SEARCH when no visual contact (last known exists)
|
|
9
|
+
// - Transitioning to IDLE when no contact and no last known position
|
|
10
|
+
//
|
|
11
|
+
// Monsters do NOT use ranged weapons, grenades, or cover.
|
|
12
|
+
// Special ability transitions are gated by meleeCooldown to prevent
|
|
13
|
+
// immediate re-activation after returning from an ability state.
|
|
14
|
+
import { createDefaultTransitionMap } from '../IStateTransitionMap';
|
|
15
|
+
import { moveToward, distanceTo } from './_utils';
|
|
16
|
+
/**
|
|
17
|
+
* Chornobyl-style ability selector preset.
|
|
18
|
+
* boar→CHARGE, bloodsucker→STALK, snork→LEAP, controller→PSI_ATTACK.
|
|
19
|
+
*
|
|
20
|
+
* Pass this as `abilitySelector` to {@link MonsterCombatController} and
|
|
21
|
+
* register the corresponding ability states in your {@link StateHandlerMap}:
|
|
22
|
+
*
|
|
23
|
+
* ```ts
|
|
24
|
+
* const handlers = buildMonsterHandlerMap(cfg)
|
|
25
|
+
* .register(ONLINE_STATE.CHARGE, new ChargeState(cfg))
|
|
26
|
+
* .register(ONLINE_STATE.STALK, new StalkState(cfg))
|
|
27
|
+
* .register(ONLINE_STATE.LEAP, new LeapState(cfg))
|
|
28
|
+
* .register(ONLINE_STATE.PSI_ATTACK, new PsiAttackState(cfg));
|
|
29
|
+
*
|
|
30
|
+
* // Tell MonsterCombatController to use it:
|
|
31
|
+
* handlers.register(
|
|
32
|
+
* ONLINE_STATE.COMBAT,
|
|
33
|
+
* new MonsterCombatController(cfg, tr, CHORNOBYL_ABILITY_SELECTOR),
|
|
34
|
+
* );
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
export const CHORNOBYL_ABILITY_SELECTOR = (entityType, dist, cfg) => {
|
|
38
|
+
switch (entityType) {
|
|
39
|
+
case 'boar':
|
|
40
|
+
// Charge when the boar is beyond direct melee range.
|
|
41
|
+
return dist > cfg.meleeRange ? 'CHARGE' : null;
|
|
42
|
+
case 'bloodsucker':
|
|
43
|
+
// Stalk when the bloodsucker is far enough to cloak without being seen.
|
|
44
|
+
return dist > cfg.meleeRange * 2 ? 'STALK' : null;
|
|
45
|
+
case 'snork': {
|
|
46
|
+
// Leap when in medium-to-far range (beyond melee but within 3× melee).
|
|
47
|
+
const leapRange = cfg.meleeRange * 3;
|
|
48
|
+
return dist > cfg.meleeRange && dist <= leapRange ? 'LEAP' : null;
|
|
49
|
+
}
|
|
50
|
+
case 'controller':
|
|
51
|
+
// PSI attack when the controller is beyond direct melee range.
|
|
52
|
+
return dist > cfg.meleeRange ? 'PSI_ATTACK' : null;
|
|
53
|
+
// Dogs and other unspecified types rely solely on basic melee.
|
|
54
|
+
default:
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Stateless monster melee combat handler.
|
|
60
|
+
*
|
|
61
|
+
* Shared across all monster entity types. Species-specific ability
|
|
62
|
+
* transitions are driven by an injectable {@link MonsterAbilitySelector}
|
|
63
|
+
* callback rather than a hardcoded switch — fully agnostic.
|
|
64
|
+
*
|
|
65
|
+
* A single instance can be shared across all NPC entities.
|
|
66
|
+
*/
|
|
67
|
+
export class MonsterCombatController {
|
|
68
|
+
constructor(cfg, tr, abilitySelector) {
|
|
69
|
+
this.cfg = cfg;
|
|
70
|
+
this.tr = createDefaultTransitionMap(tr);
|
|
71
|
+
this.selectAbility = abilitySelector ?? (() => null);
|
|
72
|
+
}
|
|
73
|
+
enter(_ctx) {
|
|
74
|
+
// No special enter logic for monster combat — perception/movement
|
|
75
|
+
// is handled in the first update tick.
|
|
76
|
+
}
|
|
77
|
+
update(ctx, _deltaMs) {
|
|
78
|
+
const now = ctx.now();
|
|
79
|
+
// -----------------------------------------------------------------------
|
|
80
|
+
// 1. Resolve visible enemy
|
|
81
|
+
// -----------------------------------------------------------------------
|
|
82
|
+
const enemies = ctx.perception?.getVisibleEnemies() ?? [];
|
|
83
|
+
const hasEnemy = enemies.length > 0;
|
|
84
|
+
if (!hasEnemy) {
|
|
85
|
+
// No visual contact — use last known position or idle.
|
|
86
|
+
if (ctx.state.lastKnownEnemyX !== 0 || ctx.state.lastKnownEnemyY !== 0) {
|
|
87
|
+
ctx.transition(this.tr.monsterOnLastKnown);
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
ctx.transition(this.tr.monsterOnNoEnemy);
|
|
91
|
+
}
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
// Update last known position from closest visible enemy.
|
|
95
|
+
const enemy = enemies[0];
|
|
96
|
+
ctx.state.lastKnownEnemyX = enemy.x;
|
|
97
|
+
ctx.state.lastKnownEnemyY = enemy.y;
|
|
98
|
+
ctx.state.targetId = enemy.id;
|
|
99
|
+
// Pack broadcast (opt-in, throttled)
|
|
100
|
+
if (now - ctx.state.packLastBroadcastMs >= this.cfg.packAlertIntervalMs) {
|
|
101
|
+
ctx.state.packLastBroadcastMs = now;
|
|
102
|
+
ctx.pack?.broadcastTarget(enemy.id, enemy.x, enemy.y);
|
|
103
|
+
ctx.pack?.broadcastAlertLevel('COMBAT');
|
|
104
|
+
}
|
|
105
|
+
// -----------------------------------------------------------------------
|
|
106
|
+
// 2. Compute distance to enemy
|
|
107
|
+
// -----------------------------------------------------------------------
|
|
108
|
+
const dist = distanceTo(ctx.x, ctx.y, enemy.x, enemy.y);
|
|
109
|
+
// -----------------------------------------------------------------------
|
|
110
|
+
// 3. Move toward enemy or halt when in melee range
|
|
111
|
+
// -----------------------------------------------------------------------
|
|
112
|
+
if (dist > this.cfg.meleeRange) {
|
|
113
|
+
moveToward(ctx, enemy.x, enemy.y, this.cfg.approachSpeed);
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
ctx.halt();
|
|
117
|
+
// Face the enemy even when standing still.
|
|
118
|
+
const dx = enemy.x - ctx.x;
|
|
119
|
+
const dy = enemy.y - ctx.y;
|
|
120
|
+
if (dx !== 0 || dy !== 0) {
|
|
121
|
+
ctx.setRotation(Math.atan2(dy, dx));
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// -----------------------------------------------------------------------
|
|
125
|
+
// 4. Melee attack when in range and off cooldown
|
|
126
|
+
// -----------------------------------------------------------------------
|
|
127
|
+
if (dist <= this.cfg.meleeRange) {
|
|
128
|
+
if (now - ctx.state.lastMeleeMs >= this.cfg.meleeCooldownMs) {
|
|
129
|
+
ctx.state.lastMeleeMs = now;
|
|
130
|
+
ctx.emitMeleeHit({
|
|
131
|
+
npcId: ctx.npcId,
|
|
132
|
+
targetId: enemy.id,
|
|
133
|
+
damage: this.cfg.meleeDamage,
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// -----------------------------------------------------------------------
|
|
138
|
+
// 5. Special ability transitions (only when melee cooldown is expired)
|
|
139
|
+
// -----------------------------------------------------------------------
|
|
140
|
+
const meleeCooldownRemaining = this.cfg.meleeCooldownMs - (now - ctx.state.lastMeleeMs);
|
|
141
|
+
if (meleeCooldownRemaining <= 0) {
|
|
142
|
+
const abilityTransition = this.selectAbility(ctx.entityType, dist, this.cfg);
|
|
143
|
+
if (abilityTransition !== null) {
|
|
144
|
+
ctx.transition(abilityTransition);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
exit(_ctx) {
|
|
149
|
+
// No cleanup needed.
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=MonsterCombatController.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MonsterCombatController.js","sourceRoot":"","sources":["../../../src/states/handlers/MonsterCombatController.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { IOnlineStateHandler } from '../IOnlineStateHandler';
|
|
2
|
+
import type { INPCContext } from '../INPCContext';
|
|
3
|
+
import type { IStateConfig } from '../IStateConfig';
|
|
4
|
+
import type { IStateTransitionMap } from '../IStateTransitionMap';
|
|
5
|
+
/**
|
|
6
|
+
* Stateless patrol-state handler.
|
|
7
|
+
*
|
|
8
|
+
* A single instance can be shared across all NPC entities.
|
|
9
|
+
*/
|
|
10
|
+
export declare class PatrolState implements IOnlineStateHandler {
|
|
11
|
+
private readonly cfg;
|
|
12
|
+
private readonly tr;
|
|
13
|
+
constructor(cfg: IStateConfig, tr?: Partial<IStateTransitionMap>);
|
|
14
|
+
enter(ctx: INPCContext): void;
|
|
15
|
+
update(ctx: INPCContext, _deltaMs: number): void;
|
|
16
|
+
exit(ctx: INPCContext): void;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=PatrolState.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PatrolState.d.ts","sourceRoot":"","sources":["../../../src/states/handlers/PatrolState.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEpD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAIlE;;;;GAIG;AACH,qBAAa,WAAY,YAAW,mBAAmB;IACrD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAsB;gBAE7B,GAAG,EAAE,YAAY,EAAE,EAAE,CAAC,EAAE,OAAO,CAAC,mBAAmB,CAAC;IAKhE,KAAK,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI;IAK7B,MAAM,CAAC,GAAG,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAyGhD,IAAI,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI;CAG7B"}
|