@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.
Files changed (395) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +385 -0
  3. package/dist/animation/AnimationController.d.ts +60 -0
  4. package/dist/animation/AnimationController.d.ts.map +1 -0
  5. package/dist/animation/AnimationController.js +71 -0
  6. package/dist/animation/AnimationController.js.map +1 -0
  7. package/dist/animation/AnimationSelector.d.ts +108 -0
  8. package/dist/animation/AnimationSelector.d.ts.map +1 -0
  9. package/dist/animation/AnimationSelector.js +194 -0
  10. package/dist/animation/AnimationSelector.js.map +1 -0
  11. package/dist/animation/index.d.ts +5 -0
  12. package/dist/animation/index.d.ts.map +1 -0
  13. package/dist/animation/index.js +4 -0
  14. package/dist/animation/index.js.map +1 -0
  15. package/dist/combat/CombatTransitionChain.d.ts +95 -0
  16. package/dist/combat/CombatTransitionChain.d.ts.map +1 -0
  17. package/dist/combat/CombatTransitionChain.js +117 -0
  18. package/dist/combat/CombatTransitionChain.js.map +1 -0
  19. package/dist/combat/LoadoutBuilder.d.ts +83 -0
  20. package/dist/combat/LoadoutBuilder.d.ts.map +1 -0
  21. package/dist/combat/LoadoutBuilder.js +213 -0
  22. package/dist/combat/LoadoutBuilder.js.map +1 -0
  23. package/dist/combat/MonsterAbilityData.d.ts +97 -0
  24. package/dist/combat/MonsterAbilityData.d.ts.map +1 -0
  25. package/dist/combat/MonsterAbilityData.js +94 -0
  26. package/dist/combat/MonsterAbilityData.js.map +1 -0
  27. package/dist/combat/WeaponSelector.d.ts +47 -0
  28. package/dist/combat/WeaponSelector.d.ts.map +1 -0
  29. package/dist/combat/WeaponSelector.js +180 -0
  30. package/dist/combat/WeaponSelector.js.map +1 -0
  31. package/dist/combat/index.d.ts +9 -0
  32. package/dist/combat/index.d.ts.map +1 -0
  33. package/dist/combat/index.js +6 -0
  34. package/dist/combat/index.js.map +1 -0
  35. package/dist/conditions/ConditionBank.d.ts +179 -0
  36. package/dist/conditions/ConditionBank.d.ts.map +1 -0
  37. package/dist/conditions/ConditionBank.js +220 -0
  38. package/dist/conditions/ConditionBank.js.map +1 -0
  39. package/dist/conditions/index.d.ts +3 -0
  40. package/dist/conditions/index.d.ts.map +1 -0
  41. package/dist/conditions/index.js +3 -0
  42. package/dist/conditions/index.js.map +1 -0
  43. package/dist/config/createDefaultAIConfig.d.ts +25 -0
  44. package/dist/config/createDefaultAIConfig.d.ts.map +1 -0
  45. package/dist/config/createDefaultAIConfig.js +147 -0
  46. package/dist/config/createDefaultAIConfig.js.map +1 -0
  47. package/dist/config/index.d.ts +2 -0
  48. package/dist/config/index.d.ts.map +1 -0
  49. package/dist/config/index.js +3 -0
  50. package/dist/config/index.js.map +1 -0
  51. package/dist/cover/CoverAccessAdapter.d.ts +61 -0
  52. package/dist/cover/CoverAccessAdapter.d.ts.map +1 -0
  53. package/dist/cover/CoverAccessAdapter.js +74 -0
  54. package/dist/cover/CoverAccessAdapter.js.map +1 -0
  55. package/dist/cover/CoverEvaluators.d.ts +43 -0
  56. package/dist/cover/CoverEvaluators.d.ts.map +1 -0
  57. package/dist/cover/CoverEvaluators.js +193 -0
  58. package/dist/cover/CoverEvaluators.js.map +1 -0
  59. package/dist/cover/CoverLockRegistry.d.ts +50 -0
  60. package/dist/cover/CoverLockRegistry.d.ts.map +1 -0
  61. package/dist/cover/CoverLockRegistry.js +164 -0
  62. package/dist/cover/CoverLockRegistry.js.map +1 -0
  63. package/dist/cover/CoverRecommender.d.ts +32 -0
  64. package/dist/cover/CoverRecommender.d.ts.map +1 -0
  65. package/dist/cover/CoverRecommender.js +45 -0
  66. package/dist/cover/CoverRecommender.js.map +1 -0
  67. package/dist/cover/CoverRegistry.d.ts +97 -0
  68. package/dist/cover/CoverRegistry.d.ts.map +1 -0
  69. package/dist/cover/CoverRegistry.js +223 -0
  70. package/dist/cover/CoverRegistry.js.map +1 -0
  71. package/dist/cover/ICoverEvaluator.d.ts +15 -0
  72. package/dist/cover/ICoverEvaluator.d.ts.map +1 -0
  73. package/dist/cover/ICoverEvaluator.js +4 -0
  74. package/dist/cover/ICoverEvaluator.js.map +1 -0
  75. package/dist/cover/ICoverLockConfig.d.ts +83 -0
  76. package/dist/cover/ICoverLockConfig.d.ts.map +1 -0
  77. package/dist/cover/ICoverLockConfig.js +21 -0
  78. package/dist/cover/ICoverLockConfig.js.map +1 -0
  79. package/dist/cover/LoopholeGenerator.d.ts +44 -0
  80. package/dist/cover/LoopholeGenerator.d.ts.map +1 -0
  81. package/dist/cover/LoopholeGenerator.js +96 -0
  82. package/dist/cover/LoopholeGenerator.js.map +1 -0
  83. package/dist/cover/index.d.ts +11 -0
  84. package/dist/cover/index.d.ts.map +1 -0
  85. package/dist/cover/index.js +8 -0
  86. package/dist/cover/index.js.map +1 -0
  87. package/dist/goap/EvadeHazardAction.d.ts +34 -0
  88. package/dist/goap/EvadeHazardAction.d.ts.map +1 -0
  89. package/dist/goap/EvadeHazardAction.js +48 -0
  90. package/dist/goap/EvadeHazardAction.js.map +1 -0
  91. package/dist/goap/GOAPController.d.ts +114 -0
  92. package/dist/goap/GOAPController.d.ts.map +1 -0
  93. package/dist/goap/GOAPController.js +191 -0
  94. package/dist/goap/GOAPController.js.map +1 -0
  95. package/dist/goap/GoalSelector.d.ts +40 -0
  96. package/dist/goap/GoalSelector.d.ts.map +1 -0
  97. package/dist/goap/GoalSelector.js +115 -0
  98. package/dist/goap/GoalSelector.js.map +1 -0
  99. package/dist/goap/IHazardZoneAccess.d.ts +16 -0
  100. package/dist/goap/IHazardZoneAccess.d.ts.map +1 -0
  101. package/dist/goap/IHazardZoneAccess.js +2 -0
  102. package/dist/goap/IHazardZoneAccess.js.map +1 -0
  103. package/dist/goap/WorldStateBuilder.d.ts +27 -0
  104. package/dist/goap/WorldStateBuilder.d.ts.map +1 -0
  105. package/dist/goap/WorldStateBuilder.js +51 -0
  106. package/dist/goap/WorldStateBuilder.js.map +1 -0
  107. package/dist/goap/index.d.ts +9 -0
  108. package/dist/goap/index.d.ts.map +1 -0
  109. package/dist/goap/index.js +6 -0
  110. package/dist/goap/index.js.map +1 -0
  111. package/dist/index.d.ts +16 -0
  112. package/dist/index.d.ts.map +1 -0
  113. package/dist/index.js +18 -0
  114. package/dist/index.js.map +1 -0
  115. package/dist/navigation/PathSmoother.d.ts +29 -0
  116. package/dist/navigation/PathSmoother.d.ts.map +1 -0
  117. package/dist/navigation/PathSmoother.js +172 -0
  118. package/dist/navigation/PathSmoother.js.map +1 -0
  119. package/dist/navigation/RestrictedZoneManager.d.ts +83 -0
  120. package/dist/navigation/RestrictedZoneManager.d.ts.map +1 -0
  121. package/dist/navigation/RestrictedZoneManager.js +179 -0
  122. package/dist/navigation/RestrictedZoneManager.js.map +1 -0
  123. package/dist/navigation/SmoothPathFollower.d.ts +55 -0
  124. package/dist/navigation/SmoothPathFollower.d.ts.map +1 -0
  125. package/dist/navigation/SmoothPathFollower.js +132 -0
  126. package/dist/navigation/SmoothPathFollower.js.map +1 -0
  127. package/dist/navigation/SteeringBehaviors.d.ts +123 -0
  128. package/dist/navigation/SteeringBehaviors.d.ts.map +1 -0
  129. package/dist/navigation/SteeringBehaviors.js +211 -0
  130. package/dist/navigation/SteeringBehaviors.js.map +1 -0
  131. package/dist/navigation/index.d.ts +7 -0
  132. package/dist/navigation/index.d.ts.map +1 -0
  133. package/dist/navigation/index.js +6 -0
  134. package/dist/navigation/index.js.map +1 -0
  135. package/dist/perception/NPCSensors.d.ts +129 -0
  136. package/dist/perception/NPCSensors.d.ts.map +1 -0
  137. package/dist/perception/NPCSensors.js +147 -0
  138. package/dist/perception/NPCSensors.js.map +1 -0
  139. package/dist/perception/PerceptionQuery.d.ts +65 -0
  140. package/dist/perception/PerceptionQuery.d.ts.map +1 -0
  141. package/dist/perception/PerceptionQuery.js +199 -0
  142. package/dist/perception/PerceptionQuery.js.map +1 -0
  143. package/dist/perception/index.d.ts +4 -0
  144. package/dist/perception/index.d.ts.map +1 -0
  145. package/dist/perception/index.js +4 -0
  146. package/dist/perception/index.js.map +1 -0
  147. package/dist/plugin/AIPlugin.d.ts +71 -0
  148. package/dist/plugin/AIPlugin.d.ts.map +1 -0
  149. package/dist/plugin/AIPlugin.js +134 -0
  150. package/dist/plugin/AIPlugin.js.map +1 -0
  151. package/dist/plugin/index.d.ts +3 -0
  152. package/dist/plugin/index.d.ts.map +1 -0
  153. package/dist/plugin/index.js +3 -0
  154. package/dist/plugin/index.js.map +1 -0
  155. package/dist/ports/AIPorts.d.ts +13 -0
  156. package/dist/ports/AIPorts.d.ts.map +1 -0
  157. package/dist/ports/AIPorts.js +14 -0
  158. package/dist/ports/AIPorts.js.map +1 -0
  159. package/dist/ports/ICoverPointSource.d.ts +27 -0
  160. package/dist/ports/ICoverPointSource.d.ts.map +1 -0
  161. package/dist/ports/ICoverPointSource.js +4 -0
  162. package/dist/ports/ICoverPointSource.js.map +1 -0
  163. package/dist/ports/IPerceptionProvider.d.ts +42 -0
  164. package/dist/ports/IPerceptionProvider.d.ts.map +1 -0
  165. package/dist/ports/IPerceptionProvider.js +4 -0
  166. package/dist/ports/IPerceptionProvider.js.map +1 -0
  167. package/dist/ports/index.d.ts +4 -0
  168. package/dist/ports/index.d.ts.map +1 -0
  169. package/dist/ports/index.js +3 -0
  170. package/dist/ports/index.js.map +1 -0
  171. package/dist/sound/VocalizationTypes.d.ts +57 -0
  172. package/dist/sound/VocalizationTypes.d.ts.map +1 -0
  173. package/dist/sound/VocalizationTypes.js +87 -0
  174. package/dist/sound/VocalizationTypes.js.map +1 -0
  175. package/dist/sound/index.d.ts +3 -0
  176. package/dist/sound/index.d.ts.map +1 -0
  177. package/dist/sound/index.js +3 -0
  178. package/dist/sound/index.js.map +1 -0
  179. package/dist/squad/SquadSharedTarget.d.ts +137 -0
  180. package/dist/squad/SquadSharedTarget.d.ts.map +1 -0
  181. package/dist/squad/SquadSharedTarget.js +145 -0
  182. package/dist/squad/SquadSharedTarget.js.map +1 -0
  183. package/dist/squad/SquadTactics.d.ts +63 -0
  184. package/dist/squad/SquadTactics.d.ts.map +1 -0
  185. package/dist/squad/SquadTactics.js +76 -0
  186. package/dist/squad/SquadTactics.js.map +1 -0
  187. package/dist/squad/index.d.ts +5 -0
  188. package/dist/squad/index.d.ts.map +1 -0
  189. package/dist/squad/index.js +4 -0
  190. package/dist/squad/index.js.map +1 -0
  191. package/dist/states/INPCContext.d.ts +550 -0
  192. package/dist/states/INPCContext.d.ts.map +1 -0
  193. package/dist/states/INPCContext.js +17 -0
  194. package/dist/states/INPCContext.js.map +1 -0
  195. package/dist/states/INPCOnlineState.d.ts +202 -0
  196. package/dist/states/INPCOnlineState.d.ts.map +1 -0
  197. package/dist/states/INPCOnlineState.js +9 -0
  198. package/dist/states/INPCOnlineState.js.map +1 -0
  199. package/dist/states/IOnlineStateHandler.d.ts +58 -0
  200. package/dist/states/IOnlineStateHandler.d.ts.map +1 -0
  201. package/dist/states/IOnlineStateHandler.js +13 -0
  202. package/dist/states/IOnlineStateHandler.js.map +1 -0
  203. package/dist/states/IStateConfig.d.ts +272 -0
  204. package/dist/states/IStateConfig.d.ts.map +1 -0
  205. package/dist/states/IStateConfig.js +100 -0
  206. package/dist/states/IStateConfig.js.map +1 -0
  207. package/dist/states/IStateTransitionMap.d.ts +89 -0
  208. package/dist/states/IStateTransitionMap.d.ts.map +1 -0
  209. package/dist/states/IStateTransitionMap.js +75 -0
  210. package/dist/states/IStateTransitionMap.js.map +1 -0
  211. package/dist/states/NPCOnlineState.d.ts +19 -0
  212. package/dist/states/NPCOnlineState.d.ts.map +1 -0
  213. package/dist/states/NPCOnlineState.js +75 -0
  214. package/dist/states/NPCOnlineState.js.map +1 -0
  215. package/dist/states/NPCPerception.d.ts +108 -0
  216. package/dist/states/NPCPerception.d.ts.map +1 -0
  217. package/dist/states/NPCPerception.js +122 -0
  218. package/dist/states/NPCPerception.js.map +1 -0
  219. package/dist/states/OnlineAIDriver.d.ts +64 -0
  220. package/dist/states/OnlineAIDriver.d.ts.map +1 -0
  221. package/dist/states/OnlineAIDriver.js +171 -0
  222. package/dist/states/OnlineAIDriver.js.map +1 -0
  223. package/dist/states/OnlineStateRegistryBuilder.d.ts +115 -0
  224. package/dist/states/OnlineStateRegistryBuilder.d.ts.map +1 -0
  225. package/dist/states/OnlineStateRegistryBuilder.js +184 -0
  226. package/dist/states/OnlineStateRegistryBuilder.js.map +1 -0
  227. package/dist/states/StateHandlerMap.d.ts +52 -0
  228. package/dist/states/StateHandlerMap.d.ts.map +1 -0
  229. package/dist/states/StateHandlerMap.js +88 -0
  230. package/dist/states/StateHandlerMap.js.map +1 -0
  231. package/dist/states/eat-corpse/EatCorpseState.d.ts +32 -0
  232. package/dist/states/eat-corpse/EatCorpseState.d.ts.map +1 -0
  233. package/dist/states/eat-corpse/EatCorpseState.js +126 -0
  234. package/dist/states/eat-corpse/EatCorpseState.js.map +1 -0
  235. package/dist/states/eat-corpse/EatCorpseTransitionGuard.d.ts +34 -0
  236. package/dist/states/eat-corpse/EatCorpseTransitionGuard.d.ts.map +1 -0
  237. package/dist/states/eat-corpse/EatCorpseTransitionGuard.js +82 -0
  238. package/dist/states/eat-corpse/EatCorpseTransitionGuard.js.map +1 -0
  239. package/dist/states/eat-corpse/ICorpseSource.d.ts +87 -0
  240. package/dist/states/eat-corpse/ICorpseSource.d.ts.map +1 -0
  241. package/dist/states/eat-corpse/ICorpseSource.js +5 -0
  242. package/dist/states/eat-corpse/ICorpseSource.js.map +1 -0
  243. package/dist/states/eat-corpse/IEatCorpseConfig.d.ts +75 -0
  244. package/dist/states/eat-corpse/IEatCorpseConfig.d.ts.map +1 -0
  245. package/dist/states/eat-corpse/IEatCorpseConfig.js +23 -0
  246. package/dist/states/eat-corpse/IEatCorpseConfig.js.map +1 -0
  247. package/dist/states/eat-corpse/IEatCorpsePhase.d.ts +23 -0
  248. package/dist/states/eat-corpse/IEatCorpsePhase.d.ts.map +1 -0
  249. package/dist/states/eat-corpse/IEatCorpsePhase.js +5 -0
  250. package/dist/states/eat-corpse/IEatCorpsePhase.js.map +1 -0
  251. package/dist/states/eat-corpse/index.d.ts +7 -0
  252. package/dist/states/eat-corpse/index.d.ts.map +1 -0
  253. package/dist/states/eat-corpse/index.js +11 -0
  254. package/dist/states/eat-corpse/index.js.map +1 -0
  255. package/dist/states/handlers/AlertState.d.ts +18 -0
  256. package/dist/states/handlers/AlertState.d.ts.map +1 -0
  257. package/dist/states/handlers/AlertState.js +104 -0
  258. package/dist/states/handlers/AlertState.js.map +1 -0
  259. package/dist/states/handlers/CampState.d.ts +18 -0
  260. package/dist/states/handlers/CampState.d.ts.map +1 -0
  261. package/dist/states/handlers/CampState.js +94 -0
  262. package/dist/states/handlers/CampState.js.map +1 -0
  263. package/dist/states/handlers/ChargeState.d.ts +18 -0
  264. package/dist/states/handlers/ChargeState.d.ts.map +1 -0
  265. package/dist/states/handlers/ChargeState.js +103 -0
  266. package/dist/states/handlers/ChargeState.js.map +1 -0
  267. package/dist/states/handlers/CombatState.d.ts +19 -0
  268. package/dist/states/handlers/CombatState.d.ts.map +1 -0
  269. package/dist/states/handlers/CombatState.js +137 -0
  270. package/dist/states/handlers/CombatState.js.map +1 -0
  271. package/dist/states/handlers/CombatTransitionHandler.d.ts +34 -0
  272. package/dist/states/handlers/CombatTransitionHandler.d.ts.map +1 -0
  273. package/dist/states/handlers/CombatTransitionHandler.js +137 -0
  274. package/dist/states/handlers/CombatTransitionHandler.js.map +1 -0
  275. package/dist/states/handlers/DeadState.d.ts +16 -0
  276. package/dist/states/handlers/DeadState.d.ts.map +1 -0
  277. package/dist/states/handlers/DeadState.js +35 -0
  278. package/dist/states/handlers/DeadState.js.map +1 -0
  279. package/dist/states/handlers/EvadeGrenadeState.d.ts +23 -0
  280. package/dist/states/handlers/EvadeGrenadeState.d.ts.map +1 -0
  281. package/dist/states/handlers/EvadeGrenadeState.js +93 -0
  282. package/dist/states/handlers/EvadeGrenadeState.js.map +1 -0
  283. package/dist/states/handlers/FleeState.d.ts +18 -0
  284. package/dist/states/handlers/FleeState.d.ts.map +1 -0
  285. package/dist/states/handlers/FleeState.js +61 -0
  286. package/dist/states/handlers/FleeState.js.map +1 -0
  287. package/dist/states/handlers/GrenadeState.d.ts +18 -0
  288. package/dist/states/handlers/GrenadeState.d.ts.map +1 -0
  289. package/dist/states/handlers/GrenadeState.js +61 -0
  290. package/dist/states/handlers/GrenadeState.js.map +1 -0
  291. package/dist/states/handlers/HelpWoundedState.d.ts +27 -0
  292. package/dist/states/handlers/HelpWoundedState.d.ts.map +1 -0
  293. package/dist/states/handlers/HelpWoundedState.js +131 -0
  294. package/dist/states/handlers/HelpWoundedState.js.map +1 -0
  295. package/dist/states/handlers/IdleState.d.ts +18 -0
  296. package/dist/states/handlers/IdleState.d.ts.map +1 -0
  297. package/dist/states/handlers/IdleState.js +127 -0
  298. package/dist/states/handlers/IdleState.js.map +1 -0
  299. package/dist/states/handlers/InvestigateState.d.ts +27 -0
  300. package/dist/states/handlers/InvestigateState.d.ts.map +1 -0
  301. package/dist/states/handlers/InvestigateState.js +145 -0
  302. package/dist/states/handlers/InvestigateState.js.map +1 -0
  303. package/dist/states/handlers/KillWoundedState.d.ts +27 -0
  304. package/dist/states/handlers/KillWoundedState.d.ts.map +1 -0
  305. package/dist/states/handlers/KillWoundedState.js +147 -0
  306. package/dist/states/handlers/KillWoundedState.js.map +1 -0
  307. package/dist/states/handlers/LeapState.d.ts +18 -0
  308. package/dist/states/handlers/LeapState.d.ts.map +1 -0
  309. package/dist/states/handlers/LeapState.js +115 -0
  310. package/dist/states/handlers/LeapState.js.map +1 -0
  311. package/dist/states/handlers/MonsterCombatController.d.ts +55 -0
  312. package/dist/states/handlers/MonsterCombatController.d.ts.map +1 -0
  313. package/dist/states/handlers/MonsterCombatController.js +152 -0
  314. package/dist/states/handlers/MonsterCombatController.js.map +1 -0
  315. package/dist/states/handlers/PatrolState.d.ts +18 -0
  316. package/dist/states/handlers/PatrolState.d.ts.map +1 -0
  317. package/dist/states/handlers/PatrolState.js +137 -0
  318. package/dist/states/handlers/PatrolState.js.map +1 -0
  319. package/dist/states/handlers/PsiAttackState.d.ts +18 -0
  320. package/dist/states/handlers/PsiAttackState.d.ts.map +1 -0
  321. package/dist/states/handlers/PsiAttackState.js +101 -0
  322. package/dist/states/handlers/PsiAttackState.js.map +1 -0
  323. package/dist/states/handlers/RetreatState.d.ts +18 -0
  324. package/dist/states/handlers/RetreatState.d.ts.map +1 -0
  325. package/dist/states/handlers/RetreatState.js +131 -0
  326. package/dist/states/handlers/RetreatState.js.map +1 -0
  327. package/dist/states/handlers/SearchState.d.ts +18 -0
  328. package/dist/states/handlers/SearchState.d.ts.map +1 -0
  329. package/dist/states/handlers/SearchState.js +64 -0
  330. package/dist/states/handlers/SearchState.js.map +1 -0
  331. package/dist/states/handlers/SleepState.d.ts +18 -0
  332. package/dist/states/handlers/SleepState.d.ts.map +1 -0
  333. package/dist/states/handlers/SleepState.js +94 -0
  334. package/dist/states/handlers/SleepState.js.map +1 -0
  335. package/dist/states/handlers/StalkState.d.ts +18 -0
  336. package/dist/states/handlers/StalkState.d.ts.map +1 -0
  337. package/dist/states/handlers/StalkState.js +82 -0
  338. package/dist/states/handlers/StalkState.js.map +1 -0
  339. package/dist/states/handlers/TakeCoverState.d.ts +18 -0
  340. package/dist/states/handlers/TakeCoverState.d.ts.map +1 -0
  341. package/dist/states/handlers/TakeCoverState.js +208 -0
  342. package/dist/states/handlers/TakeCoverState.js.map +1 -0
  343. package/dist/states/handlers/WoundedState.d.ts +18 -0
  344. package/dist/states/handlers/WoundedState.d.ts.map +1 -0
  345. package/dist/states/handlers/WoundedState.js +71 -0
  346. package/dist/states/handlers/WoundedState.js.map +1 -0
  347. package/dist/states/handlers/_utils.d.ts +55 -0
  348. package/dist/states/handlers/_utils.d.ts.map +1 -0
  349. package/dist/states/handlers/_utils.js +88 -0
  350. package/dist/states/handlers/_utils.js.map +1 -0
  351. package/dist/states/handlers/index.d.ts +25 -0
  352. package/dist/states/handlers/index.d.ts.map +1 -0
  353. package/dist/states/handlers/index.js +28 -0
  354. package/dist/states/handlers/index.js.map +1 -0
  355. package/dist/states/index.d.ts +17 -0
  356. package/dist/states/index.d.ts.map +1 -0
  357. package/dist/states/index.js +12 -0
  358. package/dist/states/index.js.map +1 -0
  359. package/dist/states/pack/IPackAccess.d.ts +46 -0
  360. package/dist/states/pack/IPackAccess.d.ts.map +1 -0
  361. package/dist/states/pack/IPackAccess.js +8 -0
  362. package/dist/states/pack/IPackAccess.js.map +1 -0
  363. package/dist/suspicion/SuspicionAccumulator.d.ts +166 -0
  364. package/dist/suspicion/SuspicionAccumulator.d.ts.map +1 -0
  365. package/dist/suspicion/SuspicionAccumulator.js +191 -0
  366. package/dist/suspicion/SuspicionAccumulator.js.map +1 -0
  367. package/dist/suspicion/index.d.ts +3 -0
  368. package/dist/suspicion/index.d.ts.map +1 -0
  369. package/dist/suspicion/index.js +2 -0
  370. package/dist/suspicion/index.js.map +1 -0
  371. package/dist/types/IAnimationTypes.d.ts +28 -0
  372. package/dist/types/IAnimationTypes.d.ts.map +1 -0
  373. package/dist/types/IAnimationTypes.js +17 -0
  374. package/dist/types/IAnimationTypes.js.map +1 -0
  375. package/dist/types/ICoverPoint.d.ts +76 -0
  376. package/dist/types/ICoverPoint.d.ts.map +1 -0
  377. package/dist/types/ICoverPoint.js +21 -0
  378. package/dist/types/ICoverPoint.js.map +1 -0
  379. package/dist/types/IOnlineAIConfig.d.ts +150 -0
  380. package/dist/types/IOnlineAIConfig.d.ts.map +1 -0
  381. package/dist/types/IOnlineAIConfig.js +5 -0
  382. package/dist/types/IOnlineAIConfig.js.map +1 -0
  383. package/dist/types/IPerceptionTypes.d.ts +94 -0
  384. package/dist/types/IPerceptionTypes.d.ts.map +1 -0
  385. package/dist/types/IPerceptionTypes.js +37 -0
  386. package/dist/types/IPerceptionTypes.js.map +1 -0
  387. package/dist/types/IWeaponTypes.d.ts +56 -0
  388. package/dist/types/IWeaponTypes.d.ts.map +1 -0
  389. package/dist/types/IWeaponTypes.js +15 -0
  390. package/dist/types/IWeaponTypes.js.map +1 -0
  391. package/dist/types/index.d.ts +10 -0
  392. package/dist/types/index.d.ts.map +1 -0
  393. package/dist/types/index.js +5 -0
  394. package/dist/types/index.js.map +1 -0
  395. package/package.json +123 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Eugene Rusakov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,385 @@
1
+ # @alife-sdk/ai
2
+
3
+ Online frame-based NPC behavior system.
4
+
5
+ Engine-agnostic. Works with Phaser, PixiJS, Node.js, or any other runtime.
6
+ Depends on [`@alife-sdk/core`](../alife-core/README.md).
7
+
8
+ ```
9
+ npm install @alife-sdk/ai
10
+ ```
11
+
12
+ ---
13
+
14
+ ## What this package does
15
+
16
+ `@alife-sdk/ai` drives every online NPC — an NPC that is within the player's
17
+ view and must behave in real-time.
18
+
19
+ - **State machine driver** — `OnlineAIDriver` + `StateHandlerMap` runs a per-NPC FSM
20
+ over 18 built-in states (idle, patrol, combat, flee, wounded, monster abilities, …)
21
+ - **Cover system** — 6 evaluators, loophole peek/fire cycles, TTL-based cover locking
22
+ - **Perception** — FOV queries, hearing radius, intel freshness filters
23
+ - **GOAP** — elite NPC goal-oriented planning over a 16-property world state bitmask
24
+ - **Navigation** — Catmull-Rom + Dubins arc path smoothing, restricted zones, pack steering
25
+ - **Squad tactics** — situational assessment, 6 commands, shared target table
26
+ - **Animation** — 8-direction state→key mapping, layered debounced controller
27
+ - **Suspicion** — stimulus accumulation → alert threshold crossing
28
+ - **Conditions** — multi-channel boolean state for dialogue / event gating
29
+
30
+ The package is intentionally engine-agnostic. All engine interaction goes
31
+ through **ports** — narrow interfaces you implement once for your engine.
32
+
33
+ ---
34
+
35
+ ## Quick start
36
+
37
+ > `buildNPCContext` and `liveDrivers` below are **your** code, not SDK exports.
38
+ > `INPCContext` is an interface — you assemble it once per NPC from your engine objects.
39
+ > See the [Key concepts → INPCContext](#inpccontext--narrow-access-interfaces) section for the full interface shape.
40
+
41
+ ```ts
42
+ import { ALifeKernel } from '@alife-sdk/core';
43
+ import { AIPlugin } from '@alife-sdk/ai/plugin';
44
+ import { buildDefaultHandlerMap,
45
+ OnlineAIDriver,
46
+ ONLINE_STATE } from '@alife-sdk/ai/states';
47
+ import { SeededRandom } from '@alife-sdk/core/ports';
48
+
49
+ // 1. Set up the kernel (see @alife-sdk/core quick start for full kernel setup)
50
+ const kernel = new ALifeKernel({ /* your engine adapters */ });
51
+
52
+ // 2. Install AIPlugin — owns shared cover registry and restricted zones
53
+ const random = new SeededRandom(42);
54
+ const aiPlugin = new AIPlugin(random);
55
+ kernel.use(aiPlugin);
56
+
57
+ await kernel.init();
58
+
59
+ // 3. Build a handler map — one instance, shared across all human NPCs
60
+ const handlers = buildDefaultHandlerMap({ combatRange: 350, meleeRange: 60 });
61
+
62
+ // 4. Create an OnlineAIDriver per NPC (in your spawn / online transition)
63
+ function spawnNPC(npcId: string): OnlineAIDriver {
64
+ const coverAccess = aiPlugin.createCoverAccess(npcId);
65
+ // buildNPCContext — your function that assembles INPCContext from engine objects
66
+ // (perception adapter, health adapter, cover access, danger access, etc.)
67
+ const ctx = buildNPCContext(npcId, coverAccess);
68
+ return new OnlineAIDriver(ctx, handlers, ONLINE_STATE.IDLE);
69
+ }
70
+
71
+ // 5. Game loop — call update() on each live driver
72
+ // liveDrivers — your Map/Array of active OnlineAIDriver instances
73
+ function update(deltaMs: number): void {
74
+ kernel.update(deltaMs); // A-Life tick + events flush
75
+ for (const driver of liveDrivers) {
76
+ driver.update(deltaMs); // per-NPC state machine
77
+ }
78
+ }
79
+
80
+ // 6. Read current state
81
+ const state = driver.currentState; // e.g. 'COMBAT'
82
+
83
+ // 7. Force a state transition (e.g. on NPC death)
84
+ driver.transitionTo(ONLINE_STATE.DEAD);
85
+ ```
86
+
87
+ ---
88
+
89
+ ## Sub-path imports
90
+
91
+ Each module has its own import path for optimal tree-shaking:
92
+
93
+ | Import path | What's inside | Module docs |
94
+ |-------------|--------------|-------------|
95
+ | `@alife-sdk/ai` | Full re-export of all sub-modules | [src/](src/) |
96
+ | `@alife-sdk/ai/plugin` | `AIPlugin`, `IAIPluginConfig` | [plugin/](src/plugin/) |
97
+ | `@alife-sdk/ai/states` | `OnlineAIDriver`, `StateHandlerMap`, `ONLINE_STATE`, all handlers, builder functions | [states/](src/states/) |
98
+ | `@alife-sdk/ai/cover` | `CoverRegistry`, `CoverLockRegistry`, 6 evaluators, `LoopholeGenerator` | [cover/](src/cover/) |
99
+ | `@alife-sdk/ai/perception` | `NPCSensors`, `isInFOV`, `filterVisibleEntities`, `filterFreshIntel` | [perception/](src/perception/) |
100
+ | `@alife-sdk/ai/goap` | `GOAPController`, `buildWorldState`, `selectGoal`, `EvadeHazardAction` | [goap/](src/goap/) |
101
+ | `@alife-sdk/ai/navigation` | `smoothPath`, `smoothPathWithTurning`, `SmoothPathFollower`, `RestrictedZoneManager`, `SteeringBehaviors` | [navigation/](src/navigation/) |
102
+ | `@alife-sdk/ai/squad` | `evaluateSituation`, `SquadCommand`, `SquadSharedTargetTable` | [squad/](src/squad/) |
103
+ | `@alife-sdk/ai/animation` | `getAnimationKey`, `AnimationController`, `DirectionCache` | [animation/](src/animation/) |
104
+ | `@alife-sdk/ai/sound` | `VocalizationType`, `VocalizationTracker` | [sound/](src/sound/) |
105
+ | `@alife-sdk/ai/suspicion` | `SuspicionAccumulator`, `SuspicionStimuli` | [suspicion/](src/suspicion/) |
106
+ | `@alife-sdk/ai/conditions` | `ConditionBank`, `ConditionChannels` | [conditions/](src/conditions/) |
107
+ | `@alife-sdk/ai/combat` | Combat helpers for online NPC state handlers | [combat/](src/combat/) |
108
+ | `@alife-sdk/ai/types` | Shared interfaces (`INPCContext`, `INPCOnlineState`, …) | [types/](src/types/) |
109
+ | `@alife-sdk/ai/config` | `IStateConfig`, default config helpers | [config/](src/config/) |
110
+ | `@alife-sdk/ai/ports` | AI-specific port interfaces | [ports/](src/ports/) |
111
+
112
+ ---
113
+
114
+ ## Architecture
115
+
116
+ ```
117
+ ┌────────────────────────────────────────┐
118
+ │ ALifeKernel │
119
+ │ (from @alife-sdk/core) │
120
+ └──────────────┬─────────────────────────┘
121
+ │ kernel.use(aiPlugin)
122
+ ┌──────────────▼─────────────────────────┐
123
+ │ AIPlugin │
124
+ │ CoverRegistry · CoverLockRegistry │
125
+ │ RestrictedZoneManager │
126
+ │ createCoverAccess(npcId) ─────────────┼──► ICoverAccess (per NPC)
127
+ └────────────────────────────────────────┘
128
+
129
+ Per-NPC (created on online transition):
130
+ ┌──────────────────────────────────────────────────────┐
131
+ │ OnlineAIDriver │
132
+ │ │
133
+ │ StateHandlerMap ──► IOnlineStateHandler │
134
+ │ DEAD · IDLE · PATROL · ALERT · FLEE · SEARCH │
135
+ │ CAMP · SLEEP · COMBAT · TAKE_COVER · GRENADE │
136
+ │ EVADE_GRENADE · WOUNDED · RETREAT │
137
+ │ CHARGE · STALK · LEAP · PSI_ATTACK │
138
+ │ │
139
+ │ INPCContext ─┬─ INPCPerception (FOV / hearing) │
140
+ │ ├─ INPCHealth (hp / morale) │
141
+ │ ├─ ICoverAccess (find / lock cover) │
142
+ │ ├─ IDangerAccess (DangerManager port) │
143
+ │ ├─ ISquadAccess (commands / target) │
144
+ │ ├─ ISuspicionAccess │
145
+ │ └─ IConditionAccess │
146
+ └──────────────────────────────────────────────────────┘
147
+
148
+ Shared systems (optional, compose as needed):
149
+ NPCSensors filterVisibleEntities / filterHearingEntities
150
+ GOAPController elite NPC A* planning (rank ≥ 5)
151
+ SmoothPathFollower Catmull-Rom + Dubins arc path cursor
152
+ AnimationController layered, debounced animation dispatch
153
+ SuspicionAccumulator stimulus → alert threshold crossing
154
+ ConditionBank multi-channel boolean state
155
+ ```
156
+
157
+ ---
158
+
159
+ ## Key concepts
160
+
161
+ ### OnlineAIDriver — per-NPC state machine
162
+
163
+ `OnlineAIDriver` is created once per NPC when it enters the online zone
164
+ and destroyed when it goes offline. It ticks one `IOnlineStateHandler`
165
+ per frame: `enter → update (every frame) → exit`.
166
+
167
+ ```ts
168
+ const driver = new OnlineAIDriver(ctx, handlers, ONLINE_STATE.IDLE);
169
+
170
+ driver.update(deltaMs); // call every frame
171
+ driver.currentState; // current state ID string
172
+ driver.transitionTo('PATROL'); // force transition
173
+ ```
174
+
175
+ Each state handler is a stateless object — all per-NPC runtime data lives in
176
+ `INPCOnlineState` (position, target, phase flags, timer, etc.), not in the handler.
177
+ The handler map can be shared across all NPCs of the same type.
178
+
179
+ ### StateHandlerMap — three built-in presets
180
+
181
+ Choose the right preset for your entity type:
182
+
183
+ | Builder function | States | Use for |
184
+ |-----------------|--------|---------|
185
+ | `buildDefaultHandlerMap()` | 14 (core + `CombatState`) | Human NPCs — ranged weapons, cover, grenades |
186
+ | `buildMonsterHandlerMap()` | 14 (core + `MonsterCombatController`) | Monsters — melee only, no special abilities |
187
+ | `buildChornobylMonsterHandlerMap()` | 18 (core + controller + 4 abilities) | Stalker-style monsters: `CHARGE / STALK / LEAP / PSI_ATTACK` |
188
+
189
+ All three return a fresh `StateHandlerMap` you can extend with `.register()`:
190
+
191
+ ```ts
192
+ // Add a custom HUNT state to the default human map
193
+ const handlers = buildDefaultHandlerMap({ combatRange: 300 })
194
+ .register('HUNT', new HuntState(cfg));
195
+ ```
196
+
197
+ Monster ability states map to entity types via `CHORNOBYL_ABILITY_SELECTOR`
198
+ (or your own `IMonsterAbilityRule[]`):
199
+
200
+ | Type | Ability state |
201
+ |------|--------------|
202
+ | `boar` | `CHARGE` — windup → ram at 2× speed |
203
+ | `bloodsucker` | `STALK` — go invisible (alpha 0.08) → approach |
204
+ | `snork` | `LEAP` — windup → airborne lerp → land |
205
+ | `controller` | `PSI_ATTACK` — channel 2 s → PSI area damage |
206
+
207
+ ### AIPlugin — shared world state
208
+
209
+ `AIPlugin` owns the data structures that must be shared across all NPCs:
210
+
211
+ - `CoverRegistry` — all cover points in the scene
212
+ - `CoverLockRegistry` — TTL-based locking so two NPCs don't pick the same cover
213
+ - `RestrictedZoneManager` — zones where NPCs cannot enter / must leave
214
+
215
+ Install it once, then get a per-NPC adapter from `createCoverAccess(npcId)`:
216
+
217
+ ```ts
218
+ const aiPlugin = new AIPlugin(random);
219
+ kernel.use(aiPlugin);
220
+ await kernel.init();
221
+
222
+ // For each NPC going online:
223
+ const coverAccess = aiPlugin.createCoverAccess(npcId);
224
+ ```
225
+
226
+ `AIPlugin.serialize()` saves `RestrictedZoneManager` state.
227
+ Cover locks are intentionally NOT serialized — they are ephemeral TTL data.
228
+
229
+ ### INPCContext — narrow access interfaces
230
+
231
+ Every state handler receives `INPCContext`, which is a bag of narrow port
232
+ interfaces. You implement each interface once and compose them per NPC:
233
+
234
+ ```ts
235
+ const ctx: INPCContext = {
236
+ npcId: npc.id,
237
+ faction: npc.faction,
238
+ perception: new MyPerception(npc), // INPCPerception
239
+ health: new MyHealth(npc), // INPCHealth
240
+ cover: coverAccess, // ICoverAccess (from AIPlugin)
241
+ danger: dangerAdapter, // IDangerAccess
242
+ squad: squadAccess, // ISquadAccess
243
+ suspicion: suspicionAccess, // ISuspicionAccess
244
+ conditions: conditionAccess, // IConditionAccess
245
+ shoot: (payload) => fireWeapon(npc, payload),
246
+ meleeHit: (payload) => applyMelee(npc, payload),
247
+ };
248
+ ```
249
+
250
+ ### Cover system
251
+
252
+ The cover module provides a full pipeline from raw cover points to per-NPC
253
+ peek/fire cycles:
254
+
255
+ 1. **Register** cover points into `CoverRegistry` (world space positions + normal)
256
+ 2. **Evaluate** — choose the right evaluator for the situation:
257
+ - `CloseCoverEvaluator` — nearest cover
258
+ - `FarCoverEvaluator` — cover far from threat
259
+ - `BalancedCoverEvaluator` — balanced distance + angle
260
+ - `BestCoverEvaluator` — best angle + distance combined
261
+ - `AmbushCoverEvaluator` — optimal ambush position
262
+ - `SafeCoverEvaluator` — maximum distance from all threats
263
+ 3. **Lock** — `CoverLockRegistry.lock(npcId, coverId, ttlMs)` so no two NPCs share a point
264
+ 4. **Loopholes** — each cover point has 1–3 loophole offsets; `TakeCoverState` cycles `WAIT → PEEK → FIRE → RETURN`
265
+
266
+ ```ts
267
+ import { recommendCoverType } from '@alife-sdk/ai/cover';
268
+
269
+ const evaluatorType = recommendCoverType({
270
+ threatCount: 3,
271
+ npcHp: 15,
272
+ npcHpMax: 100,
273
+ isElite: false,
274
+ });
275
+ // → 'SAFE' (low HP + many threats → maximize distance)
276
+ ```
277
+
278
+ ### GOAP — elite NPC planning
279
+
280
+ For NPCs with rank ≥ 5, `GOAPController` wraps a `GOAPPlanner` (A* on a
281
+ 16-property `WorldState` bitmask) to select and execute goal-oriented action
282
+ sequences. Replanning happens every 5 s or on a forced trigger.
283
+
284
+ ```ts
285
+ const goap = new GOAPController(ctx, goapConfig);
286
+ goap.update(deltaMs); // ticks current action or replans if needed
287
+
288
+ // Custom world property builders and goal rules are opt-in:
289
+ import { DEFAULT_WORLD_PROPERTY_BUILDERS,
290
+ DEFAULT_GOAL_RULES } from '@alife-sdk/ai/goap';
291
+ ```
292
+
293
+ ---
294
+
295
+ ## Lifecycle
296
+
297
+ ```
298
+ kernel.use(aiPlugin) ← register AI plugin
299
+
300
+ kernel.init() ← freeze registries, init plugin
301
+
302
+ NPC goes online:
303
+ coverAccess = aiPlugin.createCoverAccess(npcId)
304
+ driver = new OnlineAIDriver(ctx, handlers, ONLINE_STATE.IDLE)
305
+
306
+ Every frame:
307
+ kernel.update(delta) ← A-Life tick + events flush
308
+ driver.update(delta) ← state enter/update/exit
309
+
310
+ NPC goes offline:
311
+ driver is discarded ← no serialization needed
312
+
313
+ Save / restore:
314
+ aiPlugin.serialize() ← RestrictedZoneManager state
315
+ aiPlugin.restore(state) ← rebuilds zones
316
+
317
+ kernel.destroy() ← cleanup
318
+ ```
319
+
320
+ ---
321
+
322
+ ## Testing
323
+
324
+ Run only the AI package tests:
325
+
326
+ ```
327
+ pnpm test --filter @alife-sdk/ai
328
+ ```
329
+
330
+ Each system is designed for isolated unit tests:
331
+
332
+ ```ts
333
+ import { buildDefaultHandlerMap, OnlineAIDriver, ONLINE_STATE } from '@alife-sdk/ai/states';
334
+
335
+ // Minimal stub context — implement only the interfaces your test exercises
336
+ const ctx = buildStubContext({ hp: 100, targetId: 'enemy1' });
337
+ const driver = new OnlineAIDriver(ctx, buildDefaultHandlerMap(), ONLINE_STATE.IDLE);
338
+
339
+ driver.transitionTo(ONLINE_STATE.COMBAT);
340
+ driver.update(16);
341
+
342
+ expect(driver.currentState).toBe(ONLINE_STATE.COMBAT);
343
+ ```
344
+
345
+ Tips:
346
+ - State handlers are stateless objects — instantiate once, reuse across tests
347
+ - `INPCOnlineState` is a plain object — mutate it directly in tests to simulate phase changes
348
+ - `CoverRegistry` / `CoverLockRegistry` have no external dependencies — construct them directly
349
+ - `SuspicionAccumulator` and `ConditionBank` are standalone classes with no kernel dependency
350
+
351
+ ---
352
+
353
+ ## Module map
354
+
355
+ ```
356
+ src/
357
+ ├── plugin/ AIPlugin, IAIPluginConfig, createDefaultAIPluginConfig
358
+ ├── states/ OnlineAIDriver, StateHandlerMap, ONLINE_STATE, builder functions
359
+ │ ├── handlers/ DeadState, IdleState, PatrolState, AlertState, FleeState,
360
+ │ │ SearchState, CampState, SleepState, CombatState, TakeCoverState,
361
+ │ │ GrenadeState, EvadeGrenadeState, WoundedState, RetreatState,
362
+ │ │ MonsterCombatController, ChargeState, StalkState, LeapState, PsiAttackState
363
+ │ └── eat-corpse/ EatCorpseState (opt-in monster sub-state)
364
+ ├── cover/ CoverRegistry, CoverLockRegistry, CoverAccessAdapter,
365
+ │ 6 evaluators, LoopholeGenerator, findBestLoophole, recommendCoverType
366
+ ├── perception/ NPCSensors, isInFOV, filterVisibleEntities, filterHearingEntities,
367
+ │ filterHostileEntities, filterFriendlyEntities, filterFreshIntel
368
+ ├── goap/ GOAPController, buildWorldState, selectGoal, EvadeHazardAction,
369
+ │ DEFAULT_WORLD_PROPERTY_BUILDERS, DEFAULT_GOAL_RULES
370
+ ├── navigation/ smoothPath, smoothPathWithTurning, SmoothPathFollower,
371
+ │ RestrictedZoneManager, RestrictionType, SteeringBehaviors
372
+ ├── squad/ evaluateSituation, SquadCommand, canApplyCommand,
373
+ │ SquadSharedTargetTable, PROTECTED_STATES
374
+ ├── animation/ getDirection, getAnimationKey, AnimationController,
375
+ │ DirectionCache, DEFAULT_STATE_ANIM_MAP, DEFAULT_WEAPON_SUFFIXES
376
+ ├── sound/ VocalizationType, VocalizationTracker, createDefaultVocalizationConfig
377
+ ├── suspicion/ SuspicionAccumulator, SuspicionStimuli, createDefaultSuspicionConfig
378
+ ├── conditions/ ConditionBank, ConditionChannels, createDefaultConditionBankConfig
379
+ ├── combat/ combat helpers used by state handlers
380
+ ├── types/ INPCContext, INPCOnlineState, IOnlineStateHandler, INPCPerception,
381
+ │ INPCHealth, ICoverAccess, IDangerAccess, ISquadAccess, IPackAccess,
382
+ │ ISuspicionAccess, IConditionAccess, IShootPayload, IMeleeHitPayload
383
+ ├── config/ IStateConfig, IStateTransitionMap, createDefaultStateConfig
384
+ └── ports/ AI-specific port interfaces (IRestrictedZoneAccess, IHazardZoneAccess)
385
+ ```
@@ -0,0 +1,60 @@
1
+ import type { AnimLayer, IAnimationRequest } from './AnimationSelector';
2
+ /**
3
+ * Port — developer injects a Phaser/Pixi/etc. implementation.
4
+ */
5
+ export interface IAnimationDriver {
6
+ play(key: string, options: IAnimPlayOptions): void;
7
+ hasAnimation(key: string): boolean;
8
+ }
9
+ export interface IAnimPlayOptions {
10
+ readonly loop: boolean;
11
+ readonly frameRate: number;
12
+ }
13
+ /**
14
+ * Optional per-layer priority override.
15
+ * Default priority equals the numeric AnimLayer value (LEGS=0, TORSO=1, HEAD=2).
16
+ */
17
+ export type ILayerPriorityMap = Readonly<Partial<Record<AnimLayer, number>>>;
18
+ export interface IAnimationControllerConfig {
19
+ readonly driver: IAnimationDriver;
20
+ readonly layerPriority?: ILayerPriorityMap;
21
+ }
22
+ /**
23
+ * Stateful per-entity animation controller.
24
+ *
25
+ * - `request()` is debounced: skips play if same key+layer or lower priority layer is active.
26
+ * - `force()` bypasses debounce and priority (for death, hit, ability anims).
27
+ * - `reset()` clears state for respawn or object-pool reuse.
28
+ */
29
+ export declare class AnimationController {
30
+ private _currentKey;
31
+ private _currentLayer;
32
+ private readonly driver;
33
+ private readonly layerPriority;
34
+ constructor(config: IAnimationControllerConfig);
35
+ /**
36
+ * Request an animation play.
37
+ *
38
+ * Plays only if:
39
+ * 1. priority(req.layer) >= priority(currentLayer) [null current = any allowed]
40
+ * 2. req.key !== currentKey || req.layer !== currentLayer
41
+ * 3. driver.hasAnimation(req.key) === true
42
+ *
43
+ * Returns true if driver.play() was actually called.
44
+ */
45
+ request(req: IAnimationRequest): boolean;
46
+ /**
47
+ * Force-play an animation, bypassing debounce and priority.
48
+ * Useful for one-shot priority events: death, hit reaction, special ability.
49
+ * No-ops silently if driver.hasAnimation() returns false.
50
+ */
51
+ force(req: IAnimationRequest): void;
52
+ /**
53
+ * Reset controller state.
54
+ * Call on respawn or when recycling from an object pool.
55
+ */
56
+ reset(): void;
57
+ get currentKey(): string | null;
58
+ get currentLayer(): AnimLayer | null;
59
+ }
60
+ //# sourceMappingURL=AnimationController.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AnimationController.d.ts","sourceRoot":"","sources":["../../src/animation/AnimationController.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAExE;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACnD,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACpC;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;AAE7E,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,aAAa,CAAC,EAAE,iBAAiB,CAAC;CAC5C;AAED;;;;;;GAMG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,aAAa,CAA0B;IAC/C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;IAC1C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAoB;gBAEtC,MAAM,EAAE,0BAA0B;IAK9C;;;;;;;;;OASG;IACH,OAAO,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO;IAiBxC;;;;OAIG;IACH,KAAK,CAAC,GAAG,EAAE,iBAAiB,GAAG,IAAI;IAOnC;;;OAGG;IACH,KAAK,IAAI,IAAI;IAKb,IAAI,UAAU,IAAI,MAAM,GAAG,IAAI,CAE9B;IAED,IAAI,YAAY,IAAI,SAAS,GAAG,IAAI,CAEnC;CACF"}
@@ -0,0 +1,71 @@
1
+ // animation/AnimationController.ts
2
+ // Stateful per-entity animation controller with debounce and layer priority.
3
+ // Framework-agnostic via IAnimationDriver port.
4
+ /**
5
+ * Stateful per-entity animation controller.
6
+ *
7
+ * - `request()` is debounced: skips play if same key+layer or lower priority layer is active.
8
+ * - `force()` bypasses debounce and priority (for death, hit, ability anims).
9
+ * - `reset()` clears state for respawn or object-pool reuse.
10
+ */
11
+ export class AnimationController {
12
+ constructor(config) {
13
+ this._currentKey = null;
14
+ this._currentLayer = null;
15
+ this.driver = config.driver;
16
+ this.layerPriority = config.layerPriority ?? {};
17
+ }
18
+ /**
19
+ * Request an animation play.
20
+ *
21
+ * Plays only if:
22
+ * 1. priority(req.layer) >= priority(currentLayer) [null current = any allowed]
23
+ * 2. req.key !== currentKey || req.layer !== currentLayer
24
+ * 3. driver.hasAnimation(req.key) === true
25
+ *
26
+ * Returns true if driver.play() was actually called.
27
+ */
28
+ request(req) {
29
+ if (this._currentLayer !== null) {
30
+ const newPrio = this.layerPriority[req.layer] ?? req.layer;
31
+ const curPrio = this.layerPriority[this._currentLayer] ?? this._currentLayer;
32
+ if (newPrio < curPrio)
33
+ return false;
34
+ }
35
+ if (req.key === this._currentKey && req.layer === this._currentLayer)
36
+ return false;
37
+ if (!this.driver.hasAnimation(req.key))
38
+ return false;
39
+ this.driver.play(req.key, { loop: req.loop, frameRate: req.frameRate });
40
+ this._currentKey = req.key;
41
+ this._currentLayer = req.layer;
42
+ return true;
43
+ }
44
+ /**
45
+ * Force-play an animation, bypassing debounce and priority.
46
+ * Useful for one-shot priority events: death, hit reaction, special ability.
47
+ * No-ops silently if driver.hasAnimation() returns false.
48
+ */
49
+ force(req) {
50
+ if (!this.driver.hasAnimation(req.key))
51
+ return;
52
+ this.driver.play(req.key, { loop: req.loop, frameRate: req.frameRate });
53
+ this._currentKey = req.key;
54
+ this._currentLayer = req.layer;
55
+ }
56
+ /**
57
+ * Reset controller state.
58
+ * Call on respawn or when recycling from an object pool.
59
+ */
60
+ reset() {
61
+ this._currentKey = null;
62
+ this._currentLayer = null;
63
+ }
64
+ get currentKey() {
65
+ return this._currentKey;
66
+ }
67
+ get currentLayer() {
68
+ return this._currentLayer;
69
+ }
70
+ }
71
+ //# sourceMappingURL=AnimationController.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AnimationController.js","sourceRoot":"","sources":["../../src/animation/AnimationController.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,6EAA6E;AAC7E,gDAAgD;AA4BhD;;;;;;GAMG;AACH,MAAM,OAAO,mBAAmB;IAM9B,YAAY,MAAkC;QALtC,gBAAW,GAAkB,IAAI,CAAC;QAClC,kBAAa,GAAqB,IAAI,CAAC;QAK7C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAC5B,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC,aAAa,IAAI,EAAE,CAAC;IAClD,CAAC;IAED;;;;;;;;;OASG;IACH,OAAO,CAAC,GAAsB;QAC5B,IAAI,IAAI,CAAC,aAAa,KAAK,IAAI,EAAE,CAAC;YAChC,MAAM,OAAO,GAAW,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC;YACnE,MAAM,OAAO,GAAW,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC,aAAa,CAAC;YACrF,IAAI,OAAO,GAAG,OAAO;gBAAE,OAAO,KAAK,CAAC;QACtC,CAAC;QAED,IAAI,GAAG,CAAC,GAAG,KAAK,IAAI,CAAC,WAAW,IAAI,GAAG,CAAC,KAAK,KAAK,IAAI,CAAC,aAAa;YAAE,OAAO,KAAK,CAAC;QAEnF,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO,KAAK,CAAC;QAErD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC;QACxE,IAAI,CAAC,WAAW,GAAG,GAAG,CAAC,GAAG,CAAC;QAC3B,IAAI,CAAC,aAAa,GAAG,GAAG,CAAC,KAAK,CAAC;QAC/B,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,GAAsB;QAC1B,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO;QAC/C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC;QACxE,IAAI,CAAC,WAAW,GAAG,GAAG,CAAC,GAAG,CAAC;QAC3B,IAAI,CAAC,aAAa,GAAG,GAAG,CAAC,KAAK,CAAC;IACjC,CAAC;IAED;;;OAGG;IACH,KAAK;QACH,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;IAC5B,CAAC;IAED,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED,IAAI,YAAY;QACd,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;CACF"}
@@ -0,0 +1,108 @@
1
+ import type { Vec2 } from '@alife-sdk/core';
2
+ /**
3
+ * 8-way directional system for animation facing.
4
+ * Indexed 0–7 clockwise from North.
5
+ */
6
+ export declare const CompassIndex: {
7
+ readonly N: 0;
8
+ readonly NE: 1;
9
+ readonly E: 2;
10
+ readonly SE: 3;
11
+ readonly S: 4;
12
+ readonly SW: 5;
13
+ readonly W: 6;
14
+ readonly NW: 7;
15
+ };
16
+ export type CompassIndex = (typeof CompassIndex)[keyof typeof CompassIndex];
17
+ /**
18
+ * Animation layer for multi-layer sprite rigs.
19
+ */
20
+ export declare const AnimLayer: {
21
+ readonly LEGS: 0;
22
+ readonly TORSO: 1;
23
+ readonly HEAD: 2;
24
+ };
25
+ export type AnimLayer = (typeof AnimLayer)[keyof typeof AnimLayer];
26
+ /**
27
+ * Descriptor for a state → animation mapping entry.
28
+ */
29
+ export interface IAnimDescriptor {
30
+ readonly base: string;
31
+ readonly loop: boolean;
32
+ readonly frameRate: number;
33
+ readonly layer: AnimLayer;
34
+ readonly omitDirection: boolean;
35
+ }
36
+ /**
37
+ * Resolved animation request ready for the host renderer.
38
+ */
39
+ export interface IAnimationRequest {
40
+ readonly key: string;
41
+ readonly loop: boolean;
42
+ readonly frameRate: number;
43
+ readonly layer: AnimLayer;
44
+ }
45
+ /**
46
+ * AI state → animation descriptor mapping.
47
+ * Exported as default; callers may supply a custom map to override.
48
+ */
49
+ export declare const DEFAULT_STATE_ANIM_MAP: Readonly<Record<string, IAnimDescriptor>>;
50
+ /**
51
+ * Weapon suffix lookup.
52
+ * GRENADE and MEDKIT use 'unarmed' (no held weapon visible).
53
+ * Keys are strings for extensibility; numeric categories are stringified at lookup time.
54
+ */
55
+ export declare const DEFAULT_WEAPON_SUFFIXES: Readonly<Record<string, string>>;
56
+ /**
57
+ * Per-entity direction cache. Stores the last computed direction and the
58
+ * velocity that produced it. `resolve()` only calls `getDirection()` when the
59
+ * velocity has changed more than a small epsilon (squared-magnitude test).
60
+ *
61
+ * Allocate one instance per NPC and pass it into `getAnimationRequest()`.
62
+ */
63
+ export declare class DirectionCache {
64
+ private _lastVx;
65
+ private _lastVy;
66
+ private _dir;
67
+ /**
68
+ * Return the cached direction or recompute if velocity changed significantly.
69
+ */
70
+ resolve(vx: number, vy: number): CompassIndex;
71
+ /** Force-invalidate the cache (e.g. on teleport). */
72
+ invalidate(): void;
73
+ }
74
+ /**
75
+ * Convert a 2D velocity vector to an 8-way CompassIndex.
76
+ * Zero vector defaults to South (rest facing).
77
+ */
78
+ export declare function getDirection(vx: number, vy: number): CompassIndex;
79
+ /**
80
+ * Build an animation key from state, weapon type, and direction.
81
+ *
82
+ * Format: `{base}_{weapon}_{direction}` or `{base}_{weapon}` if direction omitted.
83
+ * Falls back to 'rifle' for unknown weapon types.
84
+ *
85
+ * @param animMap - Custom state → descriptor map. Uses DEFAULT_STATE_ANIM_MAP when omitted.
86
+ * @param weaponSuffixes - Custom weapon suffix map. Uses DEFAULT_WEAPON_SUFFIXES when omitted.
87
+ */
88
+ export declare function getAnimationKey(state: string, weaponType: number | string, direction: CompassIndex, animMap?: Readonly<Record<string, IAnimDescriptor>>, weaponSuffixes?: Readonly<Record<string, string>>): string;
89
+ /**
90
+ * Input for resolving an animation request from AI state and movement data.
91
+ * Groups all parameters into a single object for ergonomic callsites.
92
+ */
93
+ export interface IAnimationInput {
94
+ readonly state: string;
95
+ readonly weaponCategory: number | string;
96
+ readonly velocity: Vec2;
97
+ readonly animMap?: Readonly<Record<string, IAnimDescriptor>>;
98
+ readonly weaponSuffixes?: Readonly<Record<string, string>>;
99
+ readonly directionCache?: DirectionCache;
100
+ }
101
+ /**
102
+ * Resolve a full animation request from AI state and movement data.
103
+ *
104
+ * @param input - Animation input (state, weapon, velocity, optional maps/cache).
105
+ * @returns Complete animation request with key, loop, frame rate, and layer.
106
+ */
107
+ export declare function getAnimationRequest(input: IAnimationInput): IAnimationRequest;
108
+ //# sourceMappingURL=AnimationSelector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AnimationSelector.d.ts","sourceRoot":"","sources":["../../src/animation/AnimationSelector.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAE5C;;;GAGG;AACH,eAAO,MAAM,YAAY;;;;;;;;;CASf,CAAC;AAEX,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,OAAO,YAAY,CAAC,CAAC;AAI5E;;GAEG;AACH,eAAO,MAAM,SAAS;;;;CAIZ,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,OAAO,SAAS,CAAC,CAAC;AAEnE;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAC1B,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;CAC3B;AAED;;;GAGG;AACH,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAoB5E,CAAC;AAMF;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOpE,CAAC;AASF;;;;;;GAMG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAAO;IACtB,OAAO,CAAC,OAAO,CAAO;IACtB,OAAO,CAAC,IAAI,CAAgC;IAE5C;;OAEG;IACH,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,YAAY;IAc7C,qDAAqD;IACrD,UAAU,IAAI,IAAI;CAInB;AAiCD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,YAAY,CAajE;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,GAAG,MAAM,EAC3B,SAAS,EAAE,YAAY,EACvB,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,EACnD,cAAc,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAChD,MAAM,CAkBR;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAAC;IACzC,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC;IAC7D,QAAQ,CAAC,cAAc,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC3D,QAAQ,CAAC,cAAc,CAAC,EAAE,cAAc,CAAC;CAC1C;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,eAAe,GACrB,iBAAiB,CAanB"}