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