@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,94 @@
1
+ // states/handlers/SleepState.ts
2
+ // NPC is asleep — minimal perception, very delayed reactions.
3
+ //
4
+ // Sleep behavior (scheme@sleep analogue):
5
+ // - Visual perception is intentionally NOT checked (eyes closed).
6
+ // - Sound/nearby enemies detected via perception → cfg.campSleepReactionDelayMs
7
+ // delay → ALERT (NPC wakes up slowly).
8
+ // - NPC inside a restricted/danger zone → ALERT (immediate — physical threat).
9
+ //
10
+ // Transitions out of SLEEP:
11
+ // - sound/nearby threat (after campSleepReactionDelayMs delay) → ALERT
12
+ // - NPC inside an inaccessible/danger zone → ALERT (immediate)
13
+ import { createDefaultTransitionMap } from '../IStateTransitionMap';
14
+ import { moveToward } from './_utils';
15
+ // Sentinel: no pending reaction timer.
16
+ const NO_PENDING = 0;
17
+ /**
18
+ * Stateless sleep-state handler.
19
+ *
20
+ * A single instance can be shared across all NPC entities.
21
+ */
22
+ export class SleepState {
23
+ constructor(cfg, tr) {
24
+ this.cfg = cfg;
25
+ this.tr = createDefaultTransitionMap(tr);
26
+ }
27
+ enter(ctx) {
28
+ ctx.halt();
29
+ // Clear any stale delayed reaction from a previous SLEEP activation.
30
+ // We repurpose woundedStartMs as the sleep-reaction-start timestamp.
31
+ ctx.state.woundedStartMs = NO_PENDING;
32
+ // Slightly dim the NPC to indicate sleep visually.
33
+ ctx.setAlpha(0.8);
34
+ }
35
+ update(ctx, _deltaMs) {
36
+ const now = ctx.now();
37
+ // --- Pending delayed-reaction processing ---
38
+ const reactionStart = ctx.state.woundedStartMs;
39
+ if (reactionStart !== NO_PENDING) {
40
+ if (now - reactionStart >= this.cfg.campSleepReactionDelayMs) {
41
+ ctx.state.woundedStartMs = NO_PENDING;
42
+ ctx.transition(this.tr.sleepOnEnemy);
43
+ return;
44
+ }
45
+ // Still waking up — do nothing else.
46
+ return;
47
+ }
48
+ // --- Sound / nearby threat (non-visual perception) → queue delayed ALERT ---
49
+ // Note: visual enemies are intentionally NOT checked here (NPC eyes closed).
50
+ if (ctx.perception !== null) {
51
+ const allies = ctx.perception.getVisibleAllies(); // unused, but good guard
52
+ void allies;
53
+ const enemies = ctx.perception.getVisibleEnemies();
54
+ // We DO check getVisibleEnemies because the perception system may only
55
+ // include sound-detected entities in this list when used properly by the
56
+ // host. If only visual enemies appear here and the host disables visual
57
+ // perception for sleeping NPCs, this list will be empty — which is the
58
+ // correct behaviour. We keep the check simple and host-driven.
59
+ if (enemies.length > 0) {
60
+ const target = enemies[0];
61
+ ctx.state.lastKnownEnemyX = target.x;
62
+ ctx.state.lastKnownEnemyY = target.y;
63
+ ctx.state.woundedStartMs = now;
64
+ return;
65
+ }
66
+ }
67
+ // --- Restricted zone check (immediate wake-up — physical danger) ---
68
+ if (ctx.restrictedZones !== null && !ctx.restrictedZones.isAccessible(ctx.x, ctx.y)) {
69
+ const step = this.cfg.approachSpeed * 2;
70
+ const candidates = [
71
+ { x: ctx.x + step, y: ctx.y },
72
+ { x: ctx.x - step, y: ctx.y },
73
+ { x: ctx.x, y: ctx.y + step },
74
+ { x: ctx.x, y: ctx.y - step },
75
+ ];
76
+ const safe = ctx.restrictedZones.filterAccessible(candidates);
77
+ if (safe.length > 0) {
78
+ const dest = safe[0];
79
+ ctx.state.lastKnownEnemyX = dest.x;
80
+ ctx.state.lastKnownEnemyY = dest.y;
81
+ moveToward(ctx, dest.x, dest.y, this.cfg.approachSpeed);
82
+ }
83
+ ctx.transition(this.tr.sleepOnEnemy);
84
+ return;
85
+ }
86
+ }
87
+ exit(ctx) {
88
+ // Restore full alpha when waking up.
89
+ ctx.setAlpha(1);
90
+ // Clear any pending delayed reaction.
91
+ ctx.state.woundedStartMs = NO_PENDING;
92
+ }
93
+ }
94
+ //# sourceMappingURL=SleepState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SleepState.js","sourceRoot":"","sources":["../../../src/states/handlers/SleepState.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,8DAA8D;AAC9D,EAAE;AACF,0CAA0C;AAC1C,oEAAoE;AACpE,kFAAkF;AAClF,2CAA2C;AAC3C,iFAAiF;AACjF,EAAE;AACF,4BAA4B;AAC5B,yEAAyE;AACzE,oFAAoF;AAKpF,OAAO,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AAEpE,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtC,uCAAuC;AACvC,MAAM,UAAU,GAAG,CAAC,CAAC;AAErB;;;;GAIG;AACH,MAAM,OAAO,UAAU;IAIrB,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,IAAI,EAAE,CAAC;QACX,qEAAqE;QACrE,qEAAqE;QACrE,GAAG,CAAC,KAAK,CAAC,cAAc,GAAG,UAAU,CAAC;QACtC,mDAAmD;QACnD,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IACpB,CAAC;IAED,MAAM,CAAC,GAAgB,EAAE,QAAgB;QACvC,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC;QAEtB,8CAA8C;QAC9C,MAAM,aAAa,GAAG,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC;QAC/C,IAAI,aAAa,KAAK,UAAU,EAAE,CAAC;YACjC,IAAI,GAAG,GAAG,aAAa,IAAI,IAAI,CAAC,GAAG,CAAC,wBAAwB,EAAE,CAAC;gBAC7D,GAAG,CAAC,KAAK,CAAC,cAAc,GAAG,UAAU,CAAC;gBACtC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC;gBACrC,OAAO;YACT,CAAC;YACD,qCAAqC;YACrC,OAAO;QACT,CAAC;QAED,8EAA8E;QAC9E,6EAA6E;QAC7E,IAAI,GAAG,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;YAC5B,MAAM,MAAM,GAAG,GAAG,CAAC,UAAU,CAAC,gBAAgB,EAAE,CAAC,CAAC,yBAAyB;YAC3E,KAAK,MAAM,CAAC;YACZ,MAAM,OAAO,GAAG,GAAG,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC;YACnD,uEAAuE;YACvE,yEAAyE;YACzE,wEAAwE;YACxE,uEAAuE;YACvE,+DAA+D;YAC/D,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvB,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;gBAC1B,GAAG,CAAC,KAAK,CAAC,eAAe,GAAG,MAAM,CAAC,CAAC,CAAC;gBACrC,GAAG,CAAC,KAAK,CAAC,eAAe,GAAG,MAAM,CAAC,CAAC,CAAC;gBACrC,GAAG,CAAC,KAAK,CAAC,cAAc,GAAG,GAAG,CAAC;gBAC/B,OAAO;YACT,CAAC;QACH,CAAC;QAED,sEAAsE;QACtE,IAAI,GAAG,CAAC,eAAe,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACpF,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,GAAG,CAAC,CAAC;YACxC,MAAM,UAAU,GAAG;gBACjB,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE;gBAC7B,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE;gBAC7B,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,EAAS,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,IAAI,EAAE;gBACpC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,EAAS,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,IAAI,EAAE;aACrC,CAAC;YAEF,MAAM,IAAI,GAAG,GAAG,CAAC,eAAe,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC;YAC9D,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACpB,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;gBACrB,GAAG,CAAC,KAAK,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC,CAAC;gBACnC,GAAG,CAAC,KAAK,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC,CAAC;gBACnC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;YAC1D,CAAC;YAED,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC;YACrC,OAAO;QACT,CAAC;IACH,CAAC;IAED,IAAI,CAAC,GAAgB;QACnB,qCAAqC;QACrC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QAChB,sCAAsC;QACtC,GAAG,CAAC,KAAK,CAAC,cAAc,GAAG,UAAU,CAAC;IACxC,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 bloodsucker stalk-approach handler.
7
+ *
8
+ * A single instance can be shared across all NPC entities.
9
+ */
10
+ export declare class StalkState 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=StalkState.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StalkState.d.ts","sourceRoot":"","sources":["../../../src/states/handlers/StalkState.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;AAIlE;;;;GAIG;AACH,qBAAa,UAAW,YAAW,mBAAmB;IAIlD,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;IAU7B,MAAM,CAAC,GAAG,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IA4ChD,IAAI,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI;CAQ7B"}
@@ -0,0 +1,82 @@
1
+ // states/handlers/StalkState.ts
2
+ // Bloodsucker near-invisibility approach state.
3
+ //
4
+ // Phase pipeline (stored in ctx.state.stalkPhase):
5
+ // APPROACH — entity alpha drops to stalkAlphaInvisible; moves toward enemy
6
+ // at approachSpeed × stalkSpeedMultiplier. Transitions to uncloak
7
+ // when distance < stalkUnclockDistance.
8
+ // UNCLOAK — alpha restored to 1.0, then transition to COMBAT for the melee strike.
9
+ //
10
+ // exit() always restores full alpha (1.0) so the bloodsucker is never permanently
11
+ // invisible if the state is interrupted (e.g. takes damage → COMBAT).
12
+ //
13
+ // All mutable state lives in INPCOnlineState.stalkPhase so this handler is
14
+ // stateless and safe to share across all NPC entities.
15
+ import { createDefaultTransitionMap } from '../IStateTransitionMap';
16
+ import { moveToward, distanceTo } from './_utils';
17
+ /**
18
+ * Stateless bloodsucker stalk-approach handler.
19
+ *
20
+ * A single instance can be shared across all NPC entities.
21
+ */
22
+ export class StalkState {
23
+ constructor(cfg, tr) {
24
+ this.cfg = cfg;
25
+ this.tr = createDefaultTransitionMap(tr);
26
+ }
27
+ enter(ctx) {
28
+ var _a;
29
+ // Go invisible immediately on enter.
30
+ ctx.setAlpha(this.cfg.stalkAlphaInvisible);
31
+ // Lazy-initialise stalk phase data if not yet present.
32
+ (_a = ctx.state).stalkPhase ?? (_a.stalkPhase = { active: false, approaching: false });
33
+ ctx.state.stalkPhase.active = true;
34
+ ctx.state.stalkPhase.approaching = false;
35
+ }
36
+ update(ctx, _deltaMs) {
37
+ // -----------------------------------------------------------------------
38
+ // No visible enemy during stalk → transition to SEARCH
39
+ // -----------------------------------------------------------------------
40
+ const enemies = ctx.perception?.getVisibleEnemies() ?? [];
41
+ const hasEnemy = enemies.length > 0;
42
+ if (!hasEnemy) {
43
+ ctx.transition(this.tr.stalkOnNoEnemy);
44
+ return;
45
+ }
46
+ // Update last known position.
47
+ const enemy = enemies[0];
48
+ ctx.state.lastKnownEnemyX = enemy.x;
49
+ ctx.state.lastKnownEnemyY = enemy.y;
50
+ ctx.state.targetId = enemy.id;
51
+ const dist = distanceTo(ctx.x, ctx.y, enemy.x, enemy.y);
52
+ // -----------------------------------------------------------------------
53
+ // APPROACH phase — close distance invisibly
54
+ // -----------------------------------------------------------------------
55
+ if (!ctx.state.stalkPhase.approaching) {
56
+ if (dist <= this.cfg.stalkUnclockDistance) {
57
+ // Close enough — flag as approaching (uncloak next frame).
58
+ ctx.state.stalkPhase.approaching = true;
59
+ return;
60
+ }
61
+ // Move toward enemy at reduced stalk speed.
62
+ const stalkSpeed = this.cfg.approachSpeed * this.cfg.stalkSpeedMultiplier;
63
+ moveToward(ctx, enemy.x, enemy.y, stalkSpeed);
64
+ return;
65
+ }
66
+ // -----------------------------------------------------------------------
67
+ // UNCLOAK phase — restore alpha and attack
68
+ // -----------------------------------------------------------------------
69
+ ctx.setAlpha(1.0);
70
+ ctx.halt();
71
+ ctx.transition(this.tr.stalkOnAttack);
72
+ }
73
+ exit(ctx) {
74
+ // Always restore full visibility on exit — prevents permanent invisibility
75
+ // if the state is interrupted by damage or an external transition.
76
+ ctx.setAlpha(1.0);
77
+ if (ctx.state.stalkPhase) {
78
+ ctx.state.stalkPhase.active = false;
79
+ }
80
+ }
81
+ }
82
+ //# sourceMappingURL=StalkState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StalkState.js","sourceRoot":"","sources":["../../../src/states/handlers/StalkState.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 take-cover state handler.
7
+ *
8
+ * A single instance can be shared across all NPC entities.
9
+ */
10
+ export declare class TakeCoverState 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=TakeCoverState.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TakeCoverState.d.ts","sourceRoot":"","sources":["../../../src/states/handlers/TakeCoverState.ts"],"names":[],"mappings":"AAiBA,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,cAAe,YAAW,mBAAmB;IACxD,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;IAiD7B,MAAM,CAAC,GAAG,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAsJhD,IAAI,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI;CAK7B"}
@@ -0,0 +1,208 @@
1
+ // states/handlers/TakeCoverState.ts
2
+ // NPC shelters at a cover point and uses a loophole peek-fire cycle.
3
+ //
4
+ // Loophole phase cycle:
5
+ // WAIT — NPC halts behind cover. Duration: random [loopholeWaitMinMs, loopholeWaitMaxMs].
6
+ // PEEK — NPC moves toward cover point. Duration: loopholePeekDurationMs.
7
+ // FIRE — NPC emits shoot, stays in place. Duration: loopholeFireDurationMs.
8
+ // RETURN — NPC moves back / waits to return. Duration: loopholeReturnDurationMs.
9
+ //
10
+ // Transitions out:
11
+ // - No visible enemy → SEARCH
12
+ // - Morale PANICKED → FLEE
13
+ // - Morale SHAKEN → RETREAT
14
+ //
15
+ // enter: find cover, set coverPointX/Y, init loophole state
16
+ // exit: clear hasTakenCover + loophole
17
+ import { createDefaultTransitionMap } from '../IStateTransitionMap';
18
+ import { moveToward } from './_utils';
19
+ /**
20
+ * Stateless take-cover state handler.
21
+ *
22
+ * A single instance can be shared across all NPC entities.
23
+ */
24
+ export class TakeCoverState {
25
+ constructor(cfg, tr) {
26
+ this.cfg = cfg;
27
+ this.tr = createDefaultTransitionMap(tr);
28
+ }
29
+ enter(ctx) {
30
+ // Attempt to find a cover point using the cover subsystem.
31
+ const enemies = ctx.perception?.getVisibleEnemies() ?? [];
32
+ const enemy = enemies[0] ?? null;
33
+ let coverPt = null;
34
+ if (ctx.cover !== null && enemy !== null) {
35
+ coverPt = ctx.cover.findCover(ctx.x, ctx.y, enemy.x, enemy.y);
36
+ }
37
+ else if (ctx.cover !== null) {
38
+ // No enemy visible, find any nearby cover.
39
+ coverPt = ctx.cover.findCover(ctx.x, ctx.y, ctx.x, ctx.y);
40
+ }
41
+ if (coverPt !== null) {
42
+ // Lock the cover point; if contested, clear the selection so the NPC
43
+ // does not march into a point already occupied by another NPC.
44
+ const locked = ctx.cover?.lockLastFound?.(ctx.npcId) ?? true;
45
+ if (locked) {
46
+ ctx.state.coverPointX = coverPt.x;
47
+ ctx.state.coverPointY = coverPt.y;
48
+ }
49
+ else {
50
+ coverPt = null;
51
+ }
52
+ }
53
+ // If no cover found, we still enter — the NPC will try to move to last
54
+ // known coverPointX/Y (which may be 0,0 as fallback).
55
+ ctx.state.hasTakenCover = false;
56
+ // Initialise the loophole cycle starting in WAIT phase.
57
+ const waitDuration = this.cfg.loopholeWaitMinMs +
58
+ ctx.random() * (this.cfg.loopholeWaitMaxMs - this.cfg.loopholeWaitMinMs);
59
+ ctx.state.loophole = {
60
+ phase: 'WAIT',
61
+ phaseStartMs: ctx.now(),
62
+ };
63
+ // Store wait duration as a scratch value in phaseStartMs offset.
64
+ // We re-use phaseStartMs + phase duration to know when to advance.
65
+ // The actual wait end is computed as: phaseStartMs + waitDuration.
66
+ // Save waitDuration separately via a small trick: store -(waitDuration) in
67
+ // lastGrenadeMs as a per-NPC scratch. This avoids adding new fields.
68
+ // Instead, simpler: store the wait-end timestamp directly in lastGrenadeMs.
69
+ ctx.state.lastGrenadeMs = ctx.now() + waitDuration;
70
+ }
71
+ update(ctx, _deltaMs) {
72
+ const now = ctx.now();
73
+ // -------------------------------------------------------------------------
74
+ // Morale + perception exit checks
75
+ // -------------------------------------------------------------------------
76
+ if (ctx.state.moraleState === 'PANICKED') {
77
+ ctx.transition(this.tr.takeCoverOnPanicked);
78
+ return;
79
+ }
80
+ if (ctx.state.moraleState === 'SHAKEN') {
81
+ ctx.transition(this.tr.takeCoverOnShaken);
82
+ return;
83
+ }
84
+ const enemies = ctx.perception?.getVisibleEnemies() ?? [];
85
+ const hasEnemy = enemies.length > 0;
86
+ if (!hasEnemy) {
87
+ ctx.transition(this.tr.takeCoverOnNoEnemy);
88
+ return;
89
+ }
90
+ // Update last known enemy position.
91
+ const enemy = enemies[0];
92
+ ctx.state.lastKnownEnemyX = enemy.x;
93
+ ctx.state.lastKnownEnemyY = enemy.y;
94
+ // -------------------------------------------------------------------------
95
+ // Ensure loophole state is initialised (safety guard).
96
+ // -------------------------------------------------------------------------
97
+ if (ctx.state.loophole === null) {
98
+ const waitDuration = this.cfg.loopholeWaitMinMs +
99
+ ctx.random() * (this.cfg.loopholeWaitMaxMs - this.cfg.loopholeWaitMinMs);
100
+ ctx.state.loophole = { phase: 'WAIT', phaseStartMs: now };
101
+ ctx.state.lastGrenadeMs = now + waitDuration;
102
+ }
103
+ // -------------------------------------------------------------------------
104
+ // Move to cover point if not yet there.
105
+ // -------------------------------------------------------------------------
106
+ if (!ctx.state.hasTakenCover) {
107
+ const dx = ctx.state.coverPointX - ctx.x;
108
+ const dy = ctx.state.coverPointY - ctx.y;
109
+ const dist = Math.sqrt(dx * dx + dy * dy);
110
+ if (dist > this.cfg.arriveThreshold) {
111
+ moveToward(ctx, ctx.state.coverPointX, ctx.state.coverPointY, this.cfg.approachSpeed);
112
+ return;
113
+ }
114
+ ctx.state.hasTakenCover = true;
115
+ ctx.halt();
116
+ }
117
+ // -------------------------------------------------------------------------
118
+ // Loophole phase state machine.
119
+ // -------------------------------------------------------------------------
120
+ const loophole = ctx.state.loophole;
121
+ switch (loophole.phase) {
122
+ // -----------------------------------------------------------------------
123
+ // WAIT: NPC crouches behind cover.
124
+ // -----------------------------------------------------------------------
125
+ case 'WAIT': {
126
+ ctx.halt();
127
+ // ctx.state.lastGrenadeMs stores the wait-end timestamp.
128
+ if (now >= ctx.state.lastGrenadeMs) {
129
+ loophole.phase = 'PEEK';
130
+ loophole.phaseStartMs = now;
131
+ }
132
+ break;
133
+ }
134
+ // -----------------------------------------------------------------------
135
+ // PEEK: NPC moves toward the cover peek position (= cover centre for now).
136
+ // -----------------------------------------------------------------------
137
+ case 'PEEK': {
138
+ const elapsed = now - loophole.phaseStartMs;
139
+ if (elapsed >= this.cfg.loopholePeekDurationMs) {
140
+ ctx.halt();
141
+ loophole.phase = 'FIRE';
142
+ loophole.phaseStartMs = now;
143
+ }
144
+ else {
145
+ // Move toward enemy slightly — simulate peeking out of cover.
146
+ moveToward(ctx, enemy.x, enemy.y, this.cfg.approachSpeed * 0.5);
147
+ }
148
+ break;
149
+ }
150
+ // -----------------------------------------------------------------------
151
+ // FIRE: NPC holds and fires at enemy.
152
+ // -----------------------------------------------------------------------
153
+ case 'FIRE': {
154
+ const elapsed = now - loophole.phaseStartMs;
155
+ ctx.halt();
156
+ // Face the enemy.
157
+ const dx = enemy.x - ctx.x;
158
+ const dy = enemy.y - ctx.y;
159
+ if (dx !== 0 || dy !== 0) {
160
+ ctx.setRotation(Math.atan2(dy, dx));
161
+ }
162
+ // Fire at fire rate.
163
+ if (now - ctx.state.lastShootMs >= this.cfg.fireRateMs) {
164
+ ctx.state.lastShootMs = now;
165
+ ctx.emitShoot({
166
+ npcId: ctx.npcId,
167
+ x: ctx.x,
168
+ y: ctx.y,
169
+ targetX: enemy.x,
170
+ targetY: enemy.y,
171
+ weaponType: ctx.state.primaryWeapon ?? 'rifle',
172
+ });
173
+ }
174
+ if (elapsed >= this.cfg.loopholeFireDurationMs) {
175
+ loophole.phase = 'RETURN';
176
+ loophole.phaseStartMs = now;
177
+ }
178
+ break;
179
+ }
180
+ // -----------------------------------------------------------------------
181
+ // RETURN: NPC moves back to cover centre.
182
+ // -----------------------------------------------------------------------
183
+ case 'RETURN': {
184
+ const elapsed = now - loophole.phaseStartMs;
185
+ if (elapsed >= this.cfg.loopholeReturnDurationMs) {
186
+ ctx.halt();
187
+ // Start next WAIT phase.
188
+ const waitDuration = this.cfg.loopholeWaitMinMs +
189
+ ctx.random() * (this.cfg.loopholeWaitMaxMs - this.cfg.loopholeWaitMinMs);
190
+ loophole.phase = 'WAIT';
191
+ loophole.phaseStartMs = now;
192
+ ctx.state.lastGrenadeMs = now + waitDuration;
193
+ }
194
+ else {
195
+ // Move back toward cover point.
196
+ moveToward(ctx, ctx.state.coverPointX, ctx.state.coverPointY, this.cfg.approachSpeed);
197
+ }
198
+ break;
199
+ }
200
+ }
201
+ }
202
+ exit(ctx) {
203
+ ctx.state.hasTakenCover = false;
204
+ ctx.state.loophole = null;
205
+ ctx.cover?.unlockAll?.(ctx.npcId);
206
+ }
207
+ }
208
+ //# sourceMappingURL=TakeCoverState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TakeCoverState.js","sourceRoot":"","sources":["../../../src/states/handlers/TakeCoverState.ts"],"names":[],"mappings":"AAAA,oCAAoC;AACpC,qEAAqE;AACrE,EAAE;AACF,wBAAwB;AACxB,8FAA8F;AAC9F,6EAA6E;AAC7E,gFAAgF;AAChF,mFAAmF;AACnF,EAAE;AACF,mBAAmB;AACnB,gCAAgC;AAChC,8BAA8B;AAC9B,iCAAiC;AACjC,EAAE;AACF,4DAA4D;AAC5D,wCAAwC;AAKxC,OAAO,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AAEpE,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtC;;;;GAIG;AACH,MAAM,OAAO,cAAc;IAIzB,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,2DAA2D;QAC3D,MAAM,OAAO,GAAG,GAAG,CAAC,UAAU,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC;QAC1D,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;QAEjC,IAAI,OAAO,GAAoC,IAAI,CAAC;QAEpD,IAAI,GAAG,CAAC,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACzC,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;QAChE,CAAC;aAAM,IAAI,GAAG,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;YAC9B,2CAA2C;YAC3C,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;QAC5D,CAAC;QAED,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;YACrB,qEAAqE;YACrE,+DAA+D;YAC/D,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,EAAE,aAAa,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC;YAC7D,IAAI,MAAM,EAAE,CAAC;gBACX,GAAG,CAAC,KAAK,CAAC,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC;gBAClC,GAAG,CAAC,KAAK,CAAC,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC;YACpC,CAAC;iBAAM,CAAC;gBACN,OAAO,GAAG,IAAI,CAAC;YACjB,CAAC;QACH,CAAC;QACD,uEAAuE;QACvE,sDAAsD;QAEtD,GAAG,CAAC,KAAK,CAAC,aAAa,GAAG,KAAK,CAAC;QAEhC,wDAAwD;QACxD,MAAM,YAAY,GAChB,IAAI,CAAC,GAAG,CAAC,iBAAiB;YAC1B,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,iBAAiB,GAAG,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;QAE3E,GAAG,CAAC,KAAK,CAAC,QAAQ,GAAG;YACnB,KAAK,EAAE,MAAM;YACb,YAAY,EAAE,GAAG,CAAC,GAAG,EAAE;SACxB,CAAC;QAEF,iEAAiE;QACjE,mEAAmE;QACnE,mEAAmE;QACnE,2EAA2E;QAC3E,qEAAqE;QACrE,4EAA4E;QAC5E,GAAG,CAAC,KAAK,CAAC,aAAa,GAAG,GAAG,CAAC,GAAG,EAAE,GAAG,YAAY,CAAC;IACrD,CAAC;IAED,MAAM,CAAC,GAAgB,EAAE,QAAgB;QACvC,MAAM,GAAG,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC;QAEtB,4EAA4E;QAC5E,kCAAkC;QAClC,4EAA4E;QAC5E,IAAI,GAAG,CAAC,KAAK,CAAC,WAAW,KAAK,UAAU,EAAE,CAAC;YACzC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,mBAAmB,CAAC,CAAC;YAC5C,OAAO;QACT,CAAC;QAED,IAAI,GAAG,CAAC,KAAK,CAAC,WAAW,KAAK,QAAQ,EAAE,CAAC;YACvC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC;YAC1C,OAAO;QACT,CAAC;QAED,MAAM,OAAO,GAAG,GAAG,CAAC,UAAU,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC;QAC1D,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;QAEpC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,kBAAkB,CAAC,CAAC;YAC3C,OAAO;QACT,CAAC;QAED,oCAAoC;QACpC,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QACzB,GAAG,CAAC,KAAK,CAAC,eAAe,GAAG,KAAK,CAAC,CAAC,CAAC;QACpC,GAAG,CAAC,KAAK,CAAC,eAAe,GAAG,KAAK,CAAC,CAAC,CAAC;QAEpC,4EAA4E;QAC5E,uDAAuD;QACvD,4EAA4E;QAC5E,IAAI,GAAG,CAAC,KAAK,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;YAChC,MAAM,YAAY,GAChB,IAAI,CAAC,GAAG,CAAC,iBAAiB;gBAC1B,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,iBAAiB,GAAG,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;YAC3E,GAAG,CAAC,KAAK,CAAC,QAAQ,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,CAAC;YAC1D,GAAG,CAAC,KAAK,CAAC,aAAa,GAAG,GAAG,GAAG,YAAY,CAAC;QAC/C,CAAC;QAED,4EAA4E;QAC5E,wCAAwC;QACxC,4EAA4E;QAC5E,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC;YAC7B,MAAM,EAAE,GAAG,GAAG,CAAC,KAAK,CAAC,WAAW,GAAG,GAAG,CAAC,CAAC,CAAC;YACzC,MAAM,EAAE,GAAG,GAAG,CAAC,KAAK,CAAC,WAAW,GAAG,GAAG,CAAC,CAAC,CAAC;YACzC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;YAE1C,IAAI,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC;gBACpC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;gBACtF,OAAO;YACT,CAAC;YACD,GAAG,CAAC,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC;YAC/B,GAAG,CAAC,IAAI,EAAE,CAAC;QACb,CAAC;QAED,4EAA4E;QAC5E,gCAAgC;QAChC,4EAA4E;QAC5E,MAAM,QAAQ,GAAG,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC;QAEpC,QAAQ,QAAQ,CAAC,KAAK,EAAE,CAAC;YAEvB,0EAA0E;YAC1E,mCAAmC;YACnC,0EAA0E;YAC1E,KAAK,MAAM,CAAC,CAAC,CAAC;gBACZ,GAAG,CAAC,IAAI,EAAE,CAAC;gBACX,yDAAyD;gBACzD,IAAI,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,aAAa,EAAE,CAAC;oBACnC,QAAQ,CAAC,KAAK,GAAG,MAAM,CAAC;oBACxB,QAAQ,CAAC,YAAY,GAAG,GAAG,CAAC;gBAC9B,CAAC;gBACD,MAAM;YACR,CAAC;YAED,0EAA0E;YAC1E,2EAA2E;YAC3E,0EAA0E;YAC1E,KAAK,MAAM,CAAC,CAAC,CAAC;gBACZ,MAAM,OAAO,GAAG,GAAG,GAAG,QAAQ,CAAC,YAAY,CAAC;gBAC5C,IAAI,OAAO,IAAI,IAAI,CAAC,GAAG,CAAC,sBAAsB,EAAE,CAAC;oBAC/C,GAAG,CAAC,IAAI,EAAE,CAAC;oBACX,QAAQ,CAAC,KAAK,GAAG,MAAM,CAAC;oBACxB,QAAQ,CAAC,YAAY,GAAG,GAAG,CAAC;gBAC9B,CAAC;qBAAM,CAAC;oBACN,8DAA8D;oBAC9D,UAAU,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,aAAa,GAAG,GAAG,CAAC,CAAC;gBAClE,CAAC;gBACD,MAAM;YACR,CAAC;YAED,0EAA0E;YAC1E,sCAAsC;YACtC,0EAA0E;YAC1E,KAAK,MAAM,CAAC,CAAC,CAAC;gBACZ,MAAM,OAAO,GAAG,GAAG,GAAG,QAAQ,CAAC,YAAY,CAAC;gBAC5C,GAAG,CAAC,IAAI,EAAE,CAAC;gBAEX,kBAAkB;gBAClB,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;gBAC3B,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;gBAC3B,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;oBACzB,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;gBACtC,CAAC;gBAED,qBAAqB;gBACrB,IAAI,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,WAAW,IAAI,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC;oBACvD,GAAG,CAAC,KAAK,CAAC,WAAW,GAAG,GAAG,CAAC;oBAC5B,GAAG,CAAC,SAAS,CAAC;wBACZ,KAAK,EAAE,GAAG,CAAC,KAAK;wBAChB,CAAC,EAAE,GAAG,CAAC,CAAC;wBACR,CAAC,EAAE,GAAG,CAAC,CAAC;wBACR,OAAO,EAAE,KAAK,CAAC,CAAC;wBAChB,OAAO,EAAE,KAAK,CAAC,CAAC;wBAChB,UAAU,EAAE,GAAG,CAAC,KAAK,CAAC,aAAa,IAAI,OAAO;qBAC/C,CAAC,CAAC;gBACL,CAAC;gBAED,IAAI,OAAO,IAAI,IAAI,CAAC,GAAG,CAAC,sBAAsB,EAAE,CAAC;oBAC/C,QAAQ,CAAC,KAAK,GAAG,QAAQ,CAAC;oBAC1B,QAAQ,CAAC,YAAY,GAAG,GAAG,CAAC;gBAC9B,CAAC;gBACD,MAAM;YACR,CAAC;YAED,0EAA0E;YAC1E,0CAA0C;YAC1C,0EAA0E;YAC1E,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACd,MAAM,OAAO,GAAG,GAAG,GAAG,QAAQ,CAAC,YAAY,CAAC;gBAE5C,IAAI,OAAO,IAAI,IAAI,CAAC,GAAG,CAAC,wBAAwB,EAAE,CAAC;oBACjD,GAAG,CAAC,IAAI,EAAE,CAAC;oBACX,yBAAyB;oBACzB,MAAM,YAAY,GAChB,IAAI,CAAC,GAAG,CAAC,iBAAiB;wBAC1B,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,iBAAiB,GAAG,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;oBAC3E,QAAQ,CAAC,KAAK,GAAG,MAAM,CAAC;oBACxB,QAAQ,CAAC,YAAY,GAAG,GAAG,CAAC;oBAC5B,GAAG,CAAC,KAAK,CAAC,aAAa,GAAG,GAAG,GAAG,YAAY,CAAC;gBAC/C,CAAC;qBAAM,CAAC;oBACN,gCAAgC;oBAChC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;gBACxF,CAAC;gBACD,MAAM;YACR,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,CAAC,GAAgB;QACnB,GAAG,CAAC,KAAK,CAAC,aAAa,GAAG,KAAK,CAAC;QAChC,GAAG,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC;QAC1B,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACpC,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 wounded-state handler.
7
+ *
8
+ * A single instance can be shared across all NPC entities.
9
+ */
10
+ export declare class WoundedState 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=WoundedState.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WoundedState.d.ts","sourceRoot":"","sources":["../../../src/states/handlers/WoundedState.ts"],"names":[],"mappings":"AAmBA,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;IAI7B,MAAM,CAAC,GAAG,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IA6ChD,IAAI,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI;CAG9B"}
@@ -0,0 +1,71 @@
1
+ // states/handlers/WoundedState.ts
2
+ // NPC is critically wounded: crawls away from threats, attempts to heal with
3
+ // medkits, and may panic-flee when hopeless.
4
+ //
5
+ // Behaviour summary:
6
+ // enter() — record ctx.now() in ctx.state.woundedStartMs.
7
+ // update() — per frame:
8
+ // 1. Check duration limit: if elapsed > woundedMaxDurationMs → FLEE.
9
+ // 2. If medkit available AND HP still critically low:
10
+ // heal(maxHp × medkitHealRatio), consume one medkit.
11
+ // If HP recovers above woundedHpThreshold → COMBAT.
12
+ // 3. If morale PANICKED AND no medkits left → FLEE immediately.
13
+ // 4. Move away from last known enemy at crawl speed
14
+ // (approachSpeed × woundedCrawlMultiplier).
15
+ // exit() — nothing (no cleanup state needed).
16
+ //
17
+ // State ID: 'WOUNDED'
18
+ // Transitions: → 'COMBAT' (healed) | 'FLEE' (time limit / panic)
19
+ import { createDefaultTransitionMap } from '../IStateTransitionMap';
20
+ import { awayFrom } from './_utils';
21
+ /**
22
+ * Stateless wounded-state handler.
23
+ *
24
+ * A single instance can be shared across all NPC entities.
25
+ */
26
+ export class WoundedState {
27
+ constructor(cfg, tr) {
28
+ this.cfg = cfg;
29
+ this.tr = createDefaultTransitionMap(tr);
30
+ }
31
+ enter(ctx) {
32
+ ctx.state.woundedStartMs = ctx.now();
33
+ }
34
+ update(ctx, _deltaMs) {
35
+ const now = ctx.now();
36
+ const elapsed = now - ctx.state.woundedStartMs;
37
+ // --- Time limit: give up and flee after woundedMaxDurationMs ---
38
+ if (elapsed >= this.cfg.woundedMaxDurationMs) {
39
+ ctx.transition(this.tr.woundedOnTimeout);
40
+ return;
41
+ }
42
+ // --- Medkit healing ---
43
+ if (ctx.state.medkitCount > 0 && ctx.health !== null) {
44
+ const hpPercent = ctx.health.hpPercent;
45
+ if (hpPercent < this.cfg.woundedHpThreshold) {
46
+ // Apply heal.
47
+ const healAmount = ctx.health.maxHp * this.cfg.medkitHealRatio;
48
+ ctx.health.heal(healAmount);
49
+ ctx.state.medkitCount -= 1;
50
+ // Re-check HP after heal.
51
+ if (ctx.health.hpPercent >= this.cfg.woundedHpThreshold) {
52
+ ctx.transition(this.tr.woundedOnHealed);
53
+ return;
54
+ }
55
+ }
56
+ }
57
+ // --- Morale PANICKED with no medkits left → flee immediately ---
58
+ if (ctx.state.moraleState === 'PANICKED' && ctx.state.medkitCount <= 0) {
59
+ ctx.transition(this.tr.woundedOnPanic);
60
+ return;
61
+ }
62
+ // --- Crawl away from last known enemy position ---
63
+ const crawlSpeed = this.cfg.approachSpeed * this.cfg.woundedCrawlMultiplier;
64
+ awayFrom(ctx, ctx.state.lastKnownEnemyX, ctx.state.lastKnownEnemyY, crawlSpeed);
65
+ }
66
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
67
+ exit(_ctx) {
68
+ // No cleanup required.
69
+ }
70
+ }
71
+ //# sourceMappingURL=WoundedState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WoundedState.js","sourceRoot":"","sources":["../../../src/states/handlers/WoundedState.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAClC,6EAA6E;AAC7E,6CAA6C;AAC7C,EAAE;AACF,qBAAqB;AACrB,6DAA6D;AAC7D,0BAA0B;AAC1B,kFAAkF;AAClF,mEAAmE;AACnE,qEAAqE;AACrE,oEAAoE;AACpE,6EAA6E;AAC7E,iEAAiE;AACjE,4DAA4D;AAC5D,kDAAkD;AAClD,EAAE;AACF,sBAAsB;AACtB,iEAAiE;AAKjE,OAAO,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AAEpE,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEpC;;;;GAIG;AACH,MAAM,OAAO,YAAY;IAIvB,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,cAAc,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC;IACvC,CAAC;IAED,MAAM,CAAC,GAAgB,EAAE,QAAgB;QACvC,MAAM,GAAG,GAAO,GAAG,CAAC,GAAG,EAAE,CAAC;QAC1B,MAAM,OAAO,GAAG,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC;QAE/C,kEAAkE;QAClE,IAAI,OAAO,IAAI,IAAI,CAAC,GAAG,CAAC,oBAAoB,EAAE,CAAC;YAC7C,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC;YACzC,OAAO;QACT,CAAC;QAED,yBAAyB;QACzB,IAAI,GAAG,CAAC,KAAK,CAAC,WAAW,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;YACrD,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC;YAEvC,IAAI,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,kBAAkB,EAAE,CAAC;gBAC5C,cAAc;gBACd,MAAM,UAAU,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC;gBAC/D,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;gBAC5B,GAAG,CAAC,KAAK,CAAC,WAAW,IAAI,CAAC,CAAC;gBAE3B,0BAA0B;gBAC1B,IAAI,GAAG,CAAC,MAAM,CAAC,SAAS,IAAI,IAAI,CAAC,GAAG,CAAC,kBAAkB,EAAE,CAAC;oBACxD,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,eAAe,CAAC,CAAC;oBACxC,OAAO;gBACT,CAAC;YACH,CAAC;QACH,CAAC;QAED,kEAAkE;QAClE,IAAI,GAAG,CAAC,KAAK,CAAC,WAAW,KAAK,UAAU,IAAI,GAAG,CAAC,KAAK,CAAC,WAAW,IAAI,CAAC,EAAE,CAAC;YACvE,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC;YACvC,OAAO;QACT,CAAC;QAED,oDAAoD;QACpD,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,sBAAsB,CAAC;QAC5E,QAAQ,CACN,GAAG,EACH,GAAG,CAAC,KAAK,CAAC,eAAe,EACzB,GAAG,CAAC,KAAK,CAAC,eAAe,EACzB,UAAU,CACX,CAAC;IACJ,CAAC;IAED,6DAA6D;IAC7D,IAAI,CAAC,IAAiB;QACpB,uBAAuB;IACzB,CAAC;CACF"}
@@ -0,0 +1,55 @@
1
+ import type { INPCContext } from '../INPCContext';
2
+ import { createDefaultSteeringConfig } from '../../navigation/SteeringBehaviors';
3
+ import type { ISteeringConfig } from '../../navigation/SteeringBehaviors';
4
+ /**
5
+ * Return the Euclidean distance between two world positions.
6
+ */
7
+ export declare function distanceTo(ax: number, ay: number, bx: number, by: number): number;
8
+ /**
9
+ * Return the angle in radians from (ax, ay) toward (bx, by).
10
+ * 0 = right, π/2 = down (screen-space Y is positive downward).
11
+ */
12
+ export declare function angleToward(ax: number, ay: number, bx: number, by: number): number;
13
+ /**
14
+ * Set the NPC's velocity so it moves toward (targetX, targetY) at the given
15
+ * speed (px/s). Also updates the NPC's rotation to face the target.
16
+ *
17
+ * If the NPC is already within 0.5 px of the target, velocity is zeroed to
18
+ * avoid jitter; no rotation change is applied.
19
+ */
20
+ export declare function moveToward(ctx: INPCContext, targetX: number, targetY: number, speed: number): void;
21
+ /**
22
+ * Set the NPC's velocity so it moves directly away from (fromX, fromY) at the
23
+ * given speed (px/s). Also updates the NPC's rotation to face away.
24
+ *
25
+ * If the NPC is exactly on top of (fromX, fromY), a default escape direction
26
+ * (positive X) is used instead.
27
+ */
28
+ export declare function awayFrom(ctx: INPCContext, fromX: number, fromY: number, speed: number): void;
29
+ /**
30
+ * Opt-in convenience helper: computes pack steering (separation + cohesion) from
31
+ * nearby ally positions and blends it with a primary movement direction before
32
+ * calling `ctx.setVelocity()` and `ctx.setRotation()`.
33
+ *
34
+ * State handlers that want group-aware movement call this instead of
35
+ * `moveToward()` when allies are visible.
36
+ *
37
+ * For advanced scenarios (custom forces, alignment, formation) use the
38
+ * composable primitives directly:
39
+ * `computePackSteering() + combineForces() + blendWithPrimary()`
40
+ *
41
+ * @param ctx - NPC context (provides position and setVelocity/setRotation).
42
+ * @param allies - Nearby ally positions (e.g. from ctx.perception.getVisibleAllies()).
43
+ * @param config - Steering configuration.
44
+ * @param primaryVx - Normalised X component of the desired movement direction.
45
+ * @param primaryVy - Normalised Y component of the desired movement direction.
46
+ * @param speed - Base movement speed (px/s).
47
+ * @param weight - Blend weight for the steering force [0..1]. @default 0.35
48
+ */
49
+ export declare function applyPackSteering(ctx: INPCContext, allies: ReadonlyArray<{
50
+ x: number;
51
+ y: number;
52
+ }>, config: ISteeringConfig, primaryVx: number, primaryVy: number, speed: number, weight?: number): void;
53
+ export { createDefaultSteeringConfig };
54
+ export type { ISteeringConfig };
55
+ //# sourceMappingURL=_utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_utils.d.ts","sourceRoot":"","sources":["../../../src/states/handlers/_utils.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAyC,2BAA2B,EAAE,MAAM,oCAAoC,CAAC;AACxH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAE1E;;GAEG;AACH,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAIjF;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAElF;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,WAAW,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,GACZ,IAAI,CAYN;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,CACtB,GAAG,EAAE,WAAW,EAChB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,GACZ,IAAI,CAcN;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,aAAa,CAAC;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,EAC/C,MAAM,EAAE,eAAe,EACvB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,MAAM,SAAO,GACZ,IAAI,CAMN;AAID,OAAO,EAAE,2BAA2B,EAAE,CAAC;AACvC,YAAY,EAAE,eAAe,EAAE,CAAC"}