Advertisement
Guest User

Untitled

a guest
May 22nd, 2023
282
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.52 KB | None | 0 0
  1. #include <sourcemod>
  2. #include <sdktools>
  3.  
  4. #include <actions>
  5. #include <left4dhooks>
  6.  
  7. public Plugin myinfo =
  8. {
  9. name = "[L4D2] info_goal_infected_chase out of nav ignore",
  10. author = "BHaType",
  11. version = "0.1"
  12. }
  13.  
  14. methodmap InfectedAttack < BehaviorAction
  15. {
  16. property int m_hTargetHandle // Current infected target handle
  17. {
  18. public get()
  19. {
  20. return this.Get(0x34);
  21. }
  22.  
  23. public set(int target)
  24. {
  25. this.Set(0x34, target);
  26. }
  27. }
  28.  
  29. property int m_hTarget // Current infected target (simple wrapper to convert from handle to entindex)
  30. {
  31. public get()
  32. {
  33. int target = this.m_hTargetHandle;
  34.  
  35. if (target == -1)
  36. return -1;
  37.  
  38. return target & 0xFFF;
  39. }
  40.  
  41. public set(int target)
  42. {
  43. this.m_hTargetHandle = GetEntityHandle(target);
  44. }
  45. }
  46. }
  47.  
  48. methodmap ChaseVictim < BehaviorAction
  49. {
  50. /*
  51. * ChaseVictim stores InfectedAttack action at 0x34
  52. */
  53. property InfectedAttack m_pAttack
  54. {
  55. public get()
  56. {
  57. return this.Get(0x34);
  58. }
  59. }
  60.  
  61. /*
  62. * Used to store number of updates where common fails to build path
  63. */
  64. property int m_failedPathThreshold
  65. {
  66. public get()
  67. {
  68. return this.GetUserData("m_failedPathThreshold");
  69. }
  70. public set(int i)
  71. {
  72. this.SetUserData("m_failedPathThreshold", i);
  73. }
  74. }
  75.  
  76. /*
  77. * Used to store last target of common infected
  78. * If there are more than 2 vomitjars then infected will switch between them each update
  79. */
  80. property int m_nLastTarget
  81. {
  82. public get()
  83. {
  84. return this.GetUserData("m_nLastTarget");
  85. }
  86. public set(int target)
  87. {
  88. this.SetUserData("m_nLastTarget", target);
  89. }
  90. }
  91.  
  92. /*
  93. * Check if infected has changed target
  94. */
  95. public bool HasTargetChanged()
  96. {
  97. return this.m_nLastTarget != this.m_pAttack.m_hTargetHandle;
  98. }
  99. }
  100.  
  101. ConVar sm_infected_vomitjar_failed_path_threshold;
  102.  
  103. public void OnPluginStart()
  104. {
  105. sm_infected_vomitjar_failed_path_threshold = CreateConVar("sm_infected_vomitjar_failed_path_threshold", "6");
  106. }
  107.  
  108. public void OnActionCreated(BehaviorAction action, int actor, const char[] name)
  109. {
  110. if (strcmp(name, "ChaseVictim") == 0)
  111. {
  112. action.OnStart = ChaseVictim_OnStart;
  113. action.OnResume = ChaseVictim_OnResume;
  114. action.OnUpdatePost = ChaseVictim_OnUpdatePost;
  115. }
  116. }
  117.  
  118. /**
  119. * Whenever infected starts ChaseVictim
  120. * Reset failed path
  121. * Set last target to first target so OnUpdate doesn't reset failed path
  122. */
  123. public Action ChaseVictim_OnStart(ChaseVictim chase, int actor, float interval, ActionResult result)
  124. {
  125. chase.m_failedPathThreshold = 0;
  126. chase.m_nLastTarget = chase.m_pAttack.m_hTargetHandle;
  127. return Plugin_Continue;
  128. }
  129.  
  130. /**
  131. * Whenever infected resumes ChaseVictim
  132. * This could happen if infected was shoved or punching victim
  133. */
  134. public Action ChaseVictim_OnResume(ChaseVictim chase, int actor, float interval, ActionResult result)
  135. {
  136. chase.m_failedPathThreshold = 0;
  137. return Plugin_Continue;
  138. }
  139.  
  140. /**
  141. * Whenever infected ChaseVictim updates
  142. * Every update we check infected animation and if infected plays "lost target" animation then increase failed path count
  143. * If failed path count hits threshold, remove current target and change it to invalid
  144. */
  145. public Action ChaseVictim_OnUpdatePost(ChaseVictim chase, int actor, float interval, ActionResult result)
  146. {
  147. /* if infected changed target we need to reset count of failed path */
  148. /* but there is a thing, if there are 2 or more info_goal_infected_chase */
  149. /* infected could switch between them every update so we keep count of failed path's for info_goal_infected_chase */
  150. if (chase.HasTargetChanged())
  151. {
  152. // PrintToChatAll("%i: Changed target from %i to %i", actor, chase.m_nLastTarget & 0xFFF, chase.m_pAttack.m_hTargetHandle & 0xFFF);
  153.  
  154. if (!ClassMatchesComplex(chase.m_pAttack.m_hTarget, "info_goal_infected_chase"))
  155. {
  156. chase.m_failedPathThreshold = 0;
  157. }
  158. }
  159.  
  160. /* check if path failed more than threshold */
  161. int threshold = sm_infected_vomitjar_failed_path_threshold.IntValue;
  162. if (chase.m_failedPathThreshold > threshold)
  163. {
  164. /* InfectedAttack stores target infected current target and we need it*/
  165. InfectedAttack attack = chase.m_pAttack;
  166.  
  167. /* I don't think this check is necessary but... */
  168. if (attack)
  169. {
  170. int target = attack.m_hTarget;
  171.  
  172. if (ClassMatchesComplex(target, "info_goal_infected_chase"))
  173. {
  174. attack.m_hTargetHandle = -1;
  175. RemoveEntity(target);
  176. }
  177. }
  178.  
  179. return Plugin_Continue;
  180. }
  181.  
  182. /* If he plays "lost target" animation then increase failed path */
  183. if (IsMatchedActivity(actor))
  184. {
  185. chase.m_failedPathThreshold++;
  186. }
  187.  
  188. /* Save current target as last known */
  189. chase.m_nLastTarget = chase.m_pAttack.m_hTargetHandle;
  190. return Plugin_Continue;
  191. }
  192.  
  193. bool ClassMatchesComplex(int entity, const char[] match)
  194. {
  195. if (entity == -1 || !IsValidEntity(entity))
  196. return false;
  197.  
  198. char name[36];
  199. if (!GetEntityClassname(entity, name, sizeof name))
  200. return false;
  201.  
  202. return strcmp(name, match, false) == 0;
  203. }
  204.  
  205. stock bool IsMatchedActivity(int entity)
  206. {
  207. char activity[64];
  208.  
  209. int sequence = GetEntProp(entity, Prop_Send, "m_nSequence");
  210. if (!AnimGetActivity(sequence, activity, sizeof activity))
  211. return false;
  212.  
  213. return IsActivityLostTarget(activity);
  214. }
  215.  
  216. stock bool IsActivityLostTarget(const char[] activity)
  217. {
  218. return strcmp(activity, "ACT_TURN_RIGHT", false) == 0 ||
  219. strcmp(activity, "ACT_TURN_LEFT", false) == 0 ||
  220. strcmp(activity, "ACT_ROLL_LEFT", false) == 0 ||
  221. strcmp(activity, "ACT_ROLL_RIGHT", false) == 0;
  222. }
  223.  
  224. stock int GetEntityHandle( int entity )
  225. {
  226. return EntIndexToEntRef(entity) & ~(1 << 31);
  227. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement