@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
@@ -0,0 +1,137 @@
1
+ // states/handlers/PatrolState.ts
2
+ // NPC moves toward the current patrol waypoint stored in ctx.state.
3
+ //
4
+ // Waypoint management:
5
+ // The handler does NOT own the waypoint list. Instead it moves toward the
6
+ // target position stored in ctx.state.coverPointX / coverPointY (repurposed
7
+ // as the "current patrol point"). External code (e.g. PatrolRouteTracker,
8
+ // A-Life brain hooks) is responsible for writing the next target into these
9
+ // fields before entering PATROL state.
10
+ //
11
+ // When the NPC arrives within cfg.waypointArriveThreshold pixels it halts
12
+ // and transitions to IDLE so the host can assign the next waypoint.
13
+ //
14
+ // Transitions out of PATROL:
15
+ // - visible enemy detected via ctx.perception → ALERT
16
+ // - squad intel received (opt-in) → ALERT (via patrolOnSquadIntel)
17
+ // - accumulated suspicion exceeds threshold (opt-in) → ALERT (via patrolOnSuspicious)
18
+ // - wounded ally detected (opt-in) → HELP_WOUNDED (via patrolOnWoundedAlly)
19
+ // - friendly corpse seen (opt-in) → suspicion.add(BODY_FOUND) → cascades
20
+ // - arrived at patrol target → IDLE
21
+ // - no patrol target set (both coords are 0) → IDLE
22
+ import { createDefaultTransitionMap } from '../IStateTransitionMap';
23
+ import { moveToward } from './_utils';
24
+ import { SuspicionStimuli } from '../../suspicion/SuspicionAccumulator';
25
+ /**
26
+ * Stateless patrol-state handler.
27
+ *
28
+ * A single instance can be shared across all NPC entities.
29
+ */
30
+ export class PatrolState {
31
+ constructor(cfg, tr) {
32
+ this.cfg = cfg;
33
+ this.tr = createDefaultTransitionMap(tr);
34
+ }
35
+ enter(ctx) {
36
+ // Velocity will be set in update once we resolve the patrol target.
37
+ ctx.halt();
38
+ }
39
+ update(ctx, _deltaMs) {
40
+ // --- Perception: any visible enemy → ALERT ---
41
+ if (ctx.perception?.hasVisibleEnemy()) {
42
+ const enemies = ctx.perception.getVisibleEnemies();
43
+ const target = enemies[0];
44
+ ctx.state.lastKnownEnemyX = target.x;
45
+ ctx.state.lastKnownEnemyY = target.y;
46
+ ctx.halt();
47
+ ctx.transition(this.tr.patrolOnEnemy);
48
+ return;
49
+ }
50
+ // --- Squad intel check (opt-in) ---
51
+ // Silently skips when ctx.squad is null or getSharedTarget is not implemented.
52
+ const shared = ctx.squad?.getSharedTarget?.() ?? null;
53
+ if (shared !== null) {
54
+ ctx.state.lastKnownEnemyX = shared.x;
55
+ ctx.state.lastKnownEnemyY = shared.y;
56
+ ctx.halt();
57
+ ctx.transition(this.tr.patrolOnSquadIntel);
58
+ return;
59
+ }
60
+ // --- Pack alert check (opt-in) ---
61
+ if (ctx.pack) {
62
+ const level = ctx.pack.getPackAlertLevel();
63
+ if (level !== 'NONE') {
64
+ const pt = ctx.pack.getPackTarget();
65
+ if (pt) {
66
+ ctx.state.lastKnownEnemyX = pt.x;
67
+ ctx.state.lastKnownEnemyY = pt.y;
68
+ }
69
+ ctx.halt();
70
+ ctx.transition(this.tr.patrolOnPackAlert);
71
+ return;
72
+ }
73
+ }
74
+ // --- Suspicion check (opt-in) ---
75
+ // Silently skips when ctx.suspicion is null (not registered by host).
76
+ if (ctx.suspicion?.hasReachedAlert(this.cfg.suspicionAlertThreshold)) {
77
+ const pos = ctx.suspicion.getLastKnownPosition();
78
+ if (pos) {
79
+ ctx.state.lastKnownEnemyX = pos.x;
80
+ ctx.state.lastKnownEnemyY = pos.y;
81
+ }
82
+ ctx.suspicion.clear();
83
+ ctx.halt();
84
+ ctx.transition(this.tr.patrolOnSuspicious);
85
+ return;
86
+ }
87
+ // --- Wounded ally check (opt-in via getWoundedAllies) ---
88
+ // Silently skips when perception is null or getWoundedAllies is not implemented.
89
+ const woundedAllies = ctx.perception?.getWoundedAllies?.() ?? [];
90
+ if (woundedAllies.length > 0) {
91
+ const ally = woundedAllies[0];
92
+ ctx.state.helpWoundedTargetId = ally.id;
93
+ ctx.state.helpWoundedX = ally.x;
94
+ ctx.state.helpWoundedY = ally.y;
95
+ ctx.halt();
96
+ ctx.transition(this.tr.patrolOnWoundedAlly);
97
+ return;
98
+ }
99
+ // --- Corpse detection (opt-in via getVisibleCorpses + suspicion) ---
100
+ // Feeds suspicion accumulator; the existing suspicion check above handles transition.
101
+ if (ctx.suspicion) {
102
+ for (const c of ctx.perception?.getVisibleCorpses?.() ?? []) {
103
+ ctx.suspicion.add(SuspicionStimuli.BODY_FOUND, this.cfg.corpseFoundSuspicion, c.x, c.y);
104
+ }
105
+ }
106
+ // --- Patrol target check ---
107
+ // ctx.state.coverPointX/Y stores the current waypoint destination.
108
+ // If both are 0 we have no assignment — fall back to IDLE.
109
+ const targetX = ctx.state.coverPointX;
110
+ const targetY = ctx.state.coverPointY;
111
+ if (targetX === 0 && targetY === 0) {
112
+ ctx.halt();
113
+ ctx.transition(this.tr.patrolOnNoWaypoint);
114
+ return;
115
+ }
116
+ // --- Arrival check ---
117
+ const dx = targetX - ctx.x;
118
+ const dy = targetY - ctx.y;
119
+ const distSq = dx * dx + dy * dy;
120
+ const thresh = this.cfg.waypointArriveThreshold;
121
+ if (distSq <= thresh * thresh) {
122
+ ctx.halt();
123
+ // Signal arrival: clear the target so the host knows to assign the next
124
+ // waypoint, then fall back to IDLE until re-assigned.
125
+ ctx.state.coverPointX = 0;
126
+ ctx.state.coverPointY = 0;
127
+ ctx.transition(this.tr.patrolOnNoWaypoint);
128
+ return;
129
+ }
130
+ // --- Move toward target ---
131
+ moveToward(ctx, targetX, targetY, this.cfg.approachSpeed);
132
+ }
133
+ exit(ctx) {
134
+ ctx.halt();
135
+ }
136
+ }
137
+ //# sourceMappingURL=PatrolState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PatrolState.js","sourceRoot":"","sources":["../../../src/states/handlers/PatrolState.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 Controller PSI attack handler.
7
+ *
8
+ * A single instance can be shared across all NPC entities.
9
+ */
10
+ export declare class PsiAttackState 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=PsiAttackState.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PsiAttackState.d.ts","sourceRoot":"","sources":["../../../src/states/handlers/PsiAttackState.ts"],"names":[],"mappings":"AAeA,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,cAAe,YAAW,mBAAmB;IAItD,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;IA8B7B,MAAM,CAAC,GAAG,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAqDhD,IAAI,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI;CAK7B"}
@@ -0,0 +1,101 @@
1
+ // states/handlers/PsiAttackState.ts
2
+ // Controller PSI ranged channeled attack state.
3
+ //
4
+ // Phase pipeline (stored in ctx.state.psiPhase):
5
+ // CHANNEL — Controller stands still; emitPsiAttackStart() fires on enter for
6
+ // VFX/audio. Counts down psiChannelMs.
7
+ // Once complete: emit PSI damage via emitMeleeHit (weaponType-agnostic),
8
+ // then transition (tr.psiOnComplete).
9
+ //
10
+ // Early abort:
11
+ // - No visible enemy during channel → transition (tr.psiOnNoEnemy).
12
+ //
13
+ // All mutable state lives in INPCOnlineState.psiPhase so this handler is
14
+ // stateless and safe to share across all NPC entities.
15
+ import { createDefaultTransitionMap } from '../IStateTransitionMap';
16
+ /**
17
+ * Stateless Controller PSI attack handler.
18
+ *
19
+ * A single instance can be shared across all NPC entities.
20
+ */
21
+ export class PsiAttackState {
22
+ constructor(cfg, tr) {
23
+ this.cfg = cfg;
24
+ this.tr = createDefaultTransitionMap(tr);
25
+ }
26
+ enter(ctx) {
27
+ var _a;
28
+ const now = ctx.now();
29
+ // Update last known target position before channeling begins.
30
+ const enemies = ctx.perception?.getVisibleEnemies() ?? [];
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 PSI phase data if not yet present.
37
+ (_a = ctx.state).psiPhase ?? (_a.psiPhase = { active: false, channelStartMs: 0 });
38
+ ctx.state.psiPhase.active = true;
39
+ ctx.state.psiPhase.channelStartMs = now;
40
+ // Stand still while channeling.
41
+ ctx.halt();
42
+ // Face the target.
43
+ const dx = ctx.state.lastKnownEnemyX - ctx.x;
44
+ const dy = ctx.state.lastKnownEnemyY - ctx.y;
45
+ if (dx !== 0 || dy !== 0) {
46
+ ctx.setRotation(Math.atan2(dy, dx));
47
+ }
48
+ // Notify VFX/audio systems that PSI channel has begun.
49
+ ctx.emitPsiAttackStart(ctx.x, ctx.y);
50
+ }
51
+ update(ctx, _deltaMs) {
52
+ const now = ctx.now();
53
+ // -----------------------------------------------------------------------
54
+ // Abort: no visible enemy → psiOnNoEnemy
55
+ // -----------------------------------------------------------------------
56
+ const hasEnemy = ctx.perception?.hasVisibleEnemy() ?? false;
57
+ if (!hasEnemy) {
58
+ ctx.transition(this.tr.psiOnNoEnemy);
59
+ return;
60
+ }
61
+ // Refresh target position each frame during the channel.
62
+ const enemies = ctx.perception?.getVisibleEnemies() ?? [];
63
+ if (enemies.length > 0) {
64
+ ctx.state.lastKnownEnemyX = enemies[0].x;
65
+ ctx.state.lastKnownEnemyY = enemies[0].y;
66
+ ctx.state.targetId = enemies[0].id;
67
+ }
68
+ // -----------------------------------------------------------------------
69
+ // CHANNEL phase — stay still, face target, count down psiChannelMs
70
+ // -----------------------------------------------------------------------
71
+ const elapsed = now - ctx.state.psiPhase.channelStartMs;
72
+ // Face the target while channeling.
73
+ const dx = ctx.state.lastKnownEnemyX - ctx.x;
74
+ const dy = ctx.state.lastKnownEnemyY - ctx.y;
75
+ if (dx !== 0 || dy !== 0) {
76
+ ctx.setRotation(Math.atan2(dy, dx));
77
+ }
78
+ // Ensure NPC stays still during channel.
79
+ ctx.halt();
80
+ if (elapsed < this.cfg.psiChannelMs) {
81
+ // Still channeling.
82
+ return;
83
+ }
84
+ // -----------------------------------------------------------------------
85
+ // Channel complete — emit PSI damage and transition
86
+ // -----------------------------------------------------------------------
87
+ ctx.state.lastMeleeMs = now;
88
+ ctx.emitMeleeHit({
89
+ npcId: ctx.npcId,
90
+ targetId: ctx.state.targetId ?? '',
91
+ damage: this.cfg.meleeDamage,
92
+ });
93
+ ctx.transition(this.tr.psiOnComplete);
94
+ }
95
+ exit(ctx) {
96
+ if (ctx.state.psiPhase) {
97
+ ctx.state.psiPhase.active = false;
98
+ }
99
+ }
100
+ }
101
+ //# sourceMappingURL=PsiAttackState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PsiAttackState.js","sourceRoot":"","sources":["../../../src/states/handlers/PsiAttackState.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 retreat-state handler.
7
+ *
8
+ * A single instance can be shared across all NPC entities.
9
+ */
10
+ export declare class RetreatState 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=RetreatState.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RetreatState.d.ts","sourceRoot":"","sources":["../../../src/states/handlers/RetreatState.ts"],"names":[],"mappings":"AAoBA,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;AAGlE;;;;GAIG;AACH,qBAAa,YAAa,YAAW,mBAAmB;IACtD,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;IAmC7B,MAAM,CAAC,GAAG,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAiFhD,IAAI,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI;CAI7B"}
@@ -0,0 +1,131 @@
1
+ // states/handlers/RetreatState.ts
2
+ // NPC makes a tactical retreat to FAR cover while periodically firing
3
+ // suppressive shots toward the last known enemy position.
4
+ //
5
+ // Behaviour summary:
6
+ // enter() — find FAR cover via ctx.cover?.findCover('FAR', ...).
7
+ // Store cover destination in ctx.state.coverPointX/Y.
8
+ // update() — per frame:
9
+ // 1. If morale PANICKED → FLEE (panic overrides tactics).
10
+ // 2. Move toward the cover point at approachSpeed.
11
+ // 3. At cover: fire suppressive burst every retreatFireIntervalMs
12
+ // via ctx.emitShoot(); wait for morale to recover.
13
+ // 4. If morale recovers to STABLE while at cover → COMBAT.
14
+ // 5. If no visible enemy and at cover → SEARCH.
15
+ // 6. If no cover found: flee away from last known enemy.
16
+ // exit() — halt().
17
+ //
18
+ // State ID: 'RETREAT'
19
+ // Transitions: → 'FLEE' (panic) | 'COMBAT' (morale stable) | 'SEARCH' (no enemy)
20
+ import { createDefaultTransitionMap } from '../IStateTransitionMap';
21
+ import { moveToward, awayFrom } from './_utils';
22
+ /**
23
+ * Stateless retreat-state handler.
24
+ *
25
+ * A single instance can be shared across all NPC entities.
26
+ */
27
+ export class RetreatState {
28
+ constructor(cfg, tr) {
29
+ this.cfg = cfg;
30
+ this.tr = createDefaultTransitionMap(tr);
31
+ }
32
+ enter(ctx) {
33
+ // Determine enemy reference position for cover query.
34
+ const enemyX = ctx.state.lastKnownEnemyX;
35
+ const enemyY = ctx.state.lastKnownEnemyY;
36
+ // Find a FAR cover point — maximises distance from the known threat.
37
+ const coverPoint = ctx.cover?.findCover(ctx.x, ctx.y, enemyX, enemyY, 'FAR') ?? null;
38
+ if (coverPoint) {
39
+ // Lock the cover point; if contested, treat as no cover found.
40
+ const locked = ctx.cover?.lockLastFound?.(ctx.npcId) ?? true;
41
+ if (locked) {
42
+ ctx.state.coverPointX = coverPoint.x;
43
+ ctx.state.coverPointY = coverPoint.y;
44
+ ctx.state.hasTakenCover = false;
45
+ }
46
+ else {
47
+ ctx.state.hasTakenCover = false;
48
+ ctx.state.coverPointX = ctx.x;
49
+ ctx.state.coverPointY = ctx.y;
50
+ }
51
+ }
52
+ else {
53
+ // No cover found — mark as unavailable; update() will flee from threat.
54
+ ctx.state.hasTakenCover = false;
55
+ ctx.state.coverPointX = ctx.x;
56
+ ctx.state.coverPointY = ctx.y;
57
+ }
58
+ // Allow an immediate first suppressive burst on enter.
59
+ ctx.state.lastSupressiveFireMs = 0;
60
+ }
61
+ update(ctx, _deltaMs) {
62
+ // --- PANICKED: panic overrides all tactical behaviour → FLEE ---
63
+ if (ctx.state.moraleState === 'PANICKED') {
64
+ ctx.halt();
65
+ ctx.transition(this.tr.retreatOnPanicked);
66
+ return;
67
+ }
68
+ const now = ctx.now();
69
+ const dx = ctx.state.coverPointX - ctx.x;
70
+ const dy = ctx.state.coverPointY - ctx.y;
71
+ const distSq = dx * dx + dy * dy;
72
+ const arrived = distSq <= this.cfg.arriveThreshold * this.cfg.arriveThreshold;
73
+ if (!arrived) {
74
+ // --- Move toward the FAR cover point at normal approach speed ---
75
+ const hasCoverDest = ctx.state.coverPointX !== ctx.x || ctx.state.coverPointY !== ctx.y;
76
+ if (hasCoverDest) {
77
+ moveToward(ctx, ctx.state.coverPointX, ctx.state.coverPointY, this.cfg.approachSpeed);
78
+ }
79
+ else {
80
+ // No cover destination — run away from last known enemy.
81
+ awayFrom(ctx, ctx.state.lastKnownEnemyX, ctx.state.lastKnownEnemyY, this.cfg.approachSpeed);
82
+ }
83
+ return;
84
+ }
85
+ // --- Arrived at cover ---
86
+ ctx.halt();
87
+ // --- Suppressive fire: emit shoot every retreatFireIntervalMs ---
88
+ const timeSinceFire = now - ctx.state.lastSupressiveFireMs;
89
+ if (timeSinceFire >= this.cfg.retreatFireIntervalMs) {
90
+ ctx.state.lastSupressiveFireMs = now;
91
+ // Use visible enemy position or fall back to last known.
92
+ let targetX = ctx.state.lastKnownEnemyX;
93
+ let targetY = ctx.state.lastKnownEnemyY;
94
+ if (ctx.perception?.hasVisibleEnemy()) {
95
+ const enemies = ctx.perception.getVisibleEnemies();
96
+ if (enemies.length > 0) {
97
+ targetX = enemies[0].x;
98
+ targetY = enemies[0].y;
99
+ }
100
+ }
101
+ // Only emit shoot if we have a non-trivial direction.
102
+ const sdx = targetX - ctx.x;
103
+ const sdy = targetY - ctx.y;
104
+ if (sdx !== 0 || sdy !== 0) {
105
+ ctx.emitShoot({
106
+ npcId: ctx.npcId,
107
+ x: ctx.x,
108
+ y: ctx.y,
109
+ targetX,
110
+ targetY,
111
+ weaponType: ctx.state.primaryWeapon ?? 'rifle',
112
+ });
113
+ }
114
+ }
115
+ // --- Morale recovered while at cover → return to COMBAT ---
116
+ if (ctx.state.moraleState === 'STABLE') {
117
+ ctx.transition(this.tr.retreatOnStable);
118
+ return;
119
+ }
120
+ // --- No visible enemy while at cover → SEARCH ---
121
+ if (ctx.perception !== null && !ctx.perception.hasVisibleEnemy()) {
122
+ ctx.transition(this.tr.retreatOnNoEnemy);
123
+ return;
124
+ }
125
+ }
126
+ exit(ctx) {
127
+ ctx.halt();
128
+ ctx.cover?.unlockAll?.(ctx.npcId);
129
+ }
130
+ }
131
+ //# sourceMappingURL=RetreatState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RetreatState.js","sourceRoot":"","sources":["../../../src/states/handlers/RetreatState.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 search-state handler.
7
+ *
8
+ * A single instance can be shared across all NPC entities.
9
+ */
10
+ export declare class SearchState 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=SearchState.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SearchState.d.ts","sourceRoot":"","sources":["../../../src/states/handlers/SearchState.ts"],"names":[],"mappings":"AASA,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;AAGlE;;;;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;IAM7B,MAAM,CAAC,GAAG,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAsChD,IAAI,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI;CAG7B"}
@@ -0,0 +1,64 @@
1
+ // states/handlers/SearchState.ts
2
+ // NPC lost visual contact on the enemy and moves to the last known position
3
+ // to check if it is still there.
4
+ //
5
+ // Transitions out of SEARCH:
6
+ // - visible enemy spotted again → ALERT (re-escalate)
7
+ // - search timer (cfg.searchDuration) expired → IDLE (gave up)
8
+ // - arrived at last known position → wait in place until timer
9
+ import { createDefaultTransitionMap } from '../IStateTransitionMap';
10
+ import { moveToward } from './_utils';
11
+ /**
12
+ * Stateless search-state handler.
13
+ *
14
+ * A single instance can be shared across all NPC entities.
15
+ */
16
+ export class SearchState {
17
+ constructor(cfg, tr) {
18
+ this.cfg = cfg;
19
+ this.tr = createDefaultTransitionMap(tr);
20
+ }
21
+ enter(ctx) {
22
+ ctx.state.searchStartMs = ctx.now();
23
+ // Do not overwrite lastKnownEnemyX/Y here — the caller (e.g. CombatState
24
+ // transitioning to SEARCH) has already set the last confirmed position.
25
+ }
26
+ update(ctx, _deltaMs) {
27
+ // --- Perception: enemy becomes visible → re-escalate to ALERT ---
28
+ if (ctx.perception?.hasVisibleEnemy()) {
29
+ const enemies = ctx.perception.getVisibleEnemies();
30
+ const target = enemies[0];
31
+ ctx.state.lastKnownEnemyX = target.x;
32
+ ctx.state.lastKnownEnemyY = target.y;
33
+ ctx.transition(this.tr.searchOnEnemy);
34
+ return;
35
+ }
36
+ // --- Timer countdown ---
37
+ const elapsed = ctx.now() - ctx.state.searchStartMs;
38
+ if (elapsed >= this.cfg.searchDuration) {
39
+ // Gave up searching — clear target lock, return to idle.
40
+ ctx.state.targetId = null;
41
+ ctx.halt();
42
+ ctx.transition(this.tr.searchOnTimeout);
43
+ return;
44
+ }
45
+ // --- Move toward last known enemy position ---
46
+ const targetX = ctx.state.lastKnownEnemyX;
47
+ const targetY = ctx.state.lastKnownEnemyY;
48
+ const dx = targetX - ctx.x;
49
+ const dy = targetY - ctx.y;
50
+ const distSq = dx * dx + dy * dy;
51
+ const thresh = this.cfg.arriveThreshold;
52
+ if (distSq <= thresh * thresh) {
53
+ // Reached the last known position; nothing here — wait for timer.
54
+ ctx.halt();
55
+ }
56
+ else {
57
+ moveToward(ctx, targetX, targetY, this.cfg.approachSpeed);
58
+ }
59
+ }
60
+ exit(ctx) {
61
+ ctx.halt();
62
+ }
63
+ }
64
+ //# sourceMappingURL=SearchState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SearchState.js","sourceRoot":"","sources":["../../../src/states/handlers/SearchState.ts"],"names":[],"mappings":"AAAA,iCAAiC;AACjC,4EAA4E;AAC5E,iCAAiC;AACjC,EAAE;AACF,6BAA6B;AAC7B,sEAAsE;AACtE,mEAAmE;AACnE,2EAA2E;AAK3E,OAAO,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AAEpE,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtC;;;;GAIG;AACH,MAAM,OAAO,WAAW;IAItB,YAAY,GAAiB,EAAE,EAAiC;QAC9D,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;QACf,IAAI,CAAC,EAAE,GAAG,0BAA0B,CAAC,EAAE,CAAC,CAAC;IAC3C,CAAC;IAED,KAAK,CAAC,GAAgB;QACpB,GAAG,CAAC,KAAK,CAAC,aAAa,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC;QACpC,yEAAyE;QACzE,wEAAwE;IAC1E,CAAC;IAED,MAAM,CAAC,GAAgB,EAAE,QAAgB;QACvC,mEAAmE;QACnE,IAAI,GAAG,CAAC,UAAU,EAAE,eAAe,EAAE,EAAE,CAAC;YACtC,MAAM,OAAO,GAAG,GAAG,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC;YACnD,MAAM,MAAM,GAAI,OAAO,CAAC,CAAC,CAAC,CAAC;YAC3B,GAAG,CAAC,KAAK,CAAC,eAAe,GAAG,MAAM,CAAC,CAAC,CAAC;YACrC,GAAG,CAAC,KAAK,CAAC,eAAe,GAAG,MAAM,CAAC,CAAC,CAAC;YACrC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC;YACtC,OAAO;QACT,CAAC;QAED,0BAA0B;QAC1B,MAAM,OAAO,GAAG,GAAG,CAAC,GAAG,EAAE,GAAG,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC;QACpD,IAAI,OAAO,IAAI,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC;YACvC,yDAAyD;YACzD,GAAG,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC;YAC1B,GAAG,CAAC,IAAI,EAAE,CAAC;YACX,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC;YACxC,OAAO;QACT,CAAC;QAED,gDAAgD;QAChD,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,eAAe,CAAC;QAC1C,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,eAAe,CAAC;QAE1C,MAAM,EAAE,GAAO,OAAO,GAAG,GAAG,CAAC,CAAC,CAAC;QAC/B,MAAM,EAAE,GAAO,OAAO,GAAG,GAAG,CAAC,CAAC,CAAC;QAC/B,MAAM,MAAM,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC;QAExC,IAAI,MAAM,IAAI,MAAM,GAAG,MAAM,EAAE,CAAC;YAC9B,kEAAkE;YAClE,GAAG,CAAC,IAAI,EAAE,CAAC;QACb,CAAC;aAAM,CAAC;YACN,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;IAED,IAAI,CAAC,GAAgB;QACnB,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 sleep-state handler.
7
+ *
8
+ * A single instance can be shared across all NPC entities.
9
+ */
10
+ export declare class SleepState 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=SleepState.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SleepState.d.ts","sourceRoot":"","sources":["../../../src/states/handlers/SleepState.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;AAEpD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAMlE;;;;GAIG;AACH,qBAAa,UAAW,YAAW,mBAAmB;IACpD,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;IAS7B,MAAM,CAAC,GAAG,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IA0DhD,IAAI,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI;CAM7B"}