Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <sourcemod>
- #include <sdktools>
- #include <actions>
- #include <left4dhooks>
- public Plugin myinfo =
- {
- name = "[L4D2] info_goal_infected_chase out of nav ignore",
- author = "BHaType",
- version = "0.1"
- }
- methodmap InfectedAttack < BehaviorAction
- {
- property int m_hTargetHandle // Current infected target handle
- {
- public get()
- {
- return this.Get(0x34);
- }
- public set(int target)
- {
- this.Set(0x34, target);
- }
- }
- property int m_hTarget // Current infected target (simple wrapper to convert from handle to entindex)
- {
- public get()
- {
- int target = this.m_hTargetHandle;
- if (target == -1)
- return -1;
- return target & 0xFFF;
- }
- public set(int target)
- {
- this.m_hTargetHandle = GetEntityHandle(target);
- }
- }
- }
- methodmap ChaseVictim < BehaviorAction
- {
- /*
- * ChaseVictim stores InfectedAttack action at 0x34
- */
- property InfectedAttack m_pAttack
- {
- public get()
- {
- return this.Get(0x34);
- }
- }
- /*
- * Used to store number of updates where common fails to build path
- */
- property int m_failedPathThreshold
- {
- public get()
- {
- return this.GetUserData("m_failedPathThreshold");
- }
- public set(int i)
- {
- this.SetUserData("m_failedPathThreshold", i);
- }
- }
- /*
- * Used to store last target of common infected
- * If there are more than 2 vomitjars then infected will switch between them each update
- */
- property int m_nLastTarget
- {
- public get()
- {
- return this.GetUserData("m_nLastTarget");
- }
- public set(int target)
- {
- this.SetUserData("m_nLastTarget", target);
- }
- }
- /*
- * Check if infected has changed target
- */
- public bool HasTargetChanged()
- {
- return this.m_nLastTarget != this.m_pAttack.m_hTargetHandle;
- }
- }
- ConVar sm_infected_vomitjar_failed_path_threshold;
- public void OnPluginStart()
- {
- sm_infected_vomitjar_failed_path_threshold = CreateConVar("sm_infected_vomitjar_failed_path_threshold", "6");
- }
- public void OnActionCreated(BehaviorAction action, int actor, const char[] name)
- {
- if (strcmp(name, "ChaseVictim") == 0)
- {
- action.OnStart = ChaseVictim_OnStart;
- action.OnResume = ChaseVictim_OnResume;
- action.OnUpdatePost = ChaseVictim_OnUpdatePost;
- }
- }
- /**
- * Whenever infected starts ChaseVictim
- * Reset failed path
- * Set last target to first target so OnUpdate doesn't reset failed path
- */
- public Action ChaseVictim_OnStart(ChaseVictim chase, int actor, float interval, ActionResult result)
- {
- chase.m_failedPathThreshold = 0;
- chase.m_nLastTarget = chase.m_pAttack.m_hTargetHandle;
- return Plugin_Continue;
- }
- /**
- * Whenever infected resumes ChaseVictim
- * This could happen if infected was shoved or punching victim
- */
- public Action ChaseVictim_OnResume(ChaseVictim chase, int actor, float interval, ActionResult result)
- {
- chase.m_failedPathThreshold = 0;
- return Plugin_Continue;
- }
- /**
- * Whenever infected ChaseVictim updates
- * Every update we check infected animation and if infected plays "lost target" animation then increase failed path count
- * If failed path count hits threshold, remove current target and change it to invalid
- */
- public Action ChaseVictim_OnUpdatePost(ChaseVictim chase, int actor, float interval, ActionResult result)
- {
- /* if infected changed target we need to reset count of failed path */
- /* but there is a thing, if there are 2 or more info_goal_infected_chase */
- /* infected could switch between them every update so we keep count of failed path's for info_goal_infected_chase */
- if (chase.HasTargetChanged())
- {
- // PrintToChatAll("%i: Changed target from %i to %i", actor, chase.m_nLastTarget & 0xFFF, chase.m_pAttack.m_hTargetHandle & 0xFFF);
- if (!ClassMatchesComplex(chase.m_pAttack.m_hTarget, "info_goal_infected_chase"))
- {
- chase.m_failedPathThreshold = 0;
- }
- }
- /* check if path failed more than threshold */
- int threshold = sm_infected_vomitjar_failed_path_threshold.IntValue;
- if (chase.m_failedPathThreshold > threshold)
- {
- /* InfectedAttack stores target infected current target and we need it*/
- InfectedAttack attack = chase.m_pAttack;
- /* I don't think this check is necessary but... */
- if (attack)
- {
- int target = attack.m_hTarget;
- if (ClassMatchesComplex(target, "info_goal_infected_chase"))
- {
- attack.m_hTargetHandle = -1;
- RemoveEntity(target);
- }
- }
- return Plugin_Continue;
- }
- /* If he plays "lost target" animation then increase failed path */
- if (IsMatchedActivity(actor))
- {
- chase.m_failedPathThreshold++;
- }
- /* Save current target as last known */
- chase.m_nLastTarget = chase.m_pAttack.m_hTargetHandle;
- return Plugin_Continue;
- }
- bool ClassMatchesComplex(int entity, const char[] match)
- {
- if (entity == -1 || !IsValidEntity(entity))
- return false;
- char name[36];
- if (!GetEntityClassname(entity, name, sizeof name))
- return false;
- return strcmp(name, match, false) == 0;
- }
- stock bool IsMatchedActivity(int entity)
- {
- char activity[64];
- int sequence = GetEntProp(entity, Prop_Send, "m_nSequence");
- if (!AnimGetActivity(sequence, activity, sizeof activity))
- return false;
- return IsActivityLostTarget(activity);
- }
- stock bool IsActivityLostTarget(const char[] activity)
- {
- return strcmp(activity, "ACT_TURN_RIGHT", false) == 0 ||
- strcmp(activity, "ACT_TURN_LEFT", false) == 0 ||
- strcmp(activity, "ACT_ROLL_LEFT", false) == 0 ||
- strcmp(activity, "ACT_ROLL_RIGHT", false) == 0;
- }
- stock int GetEntityHandle( int entity )
- {
- return EntIndexToEntRef(entity) & ~(1 << 31);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement