DeathChaos25

[L4D2] Survivor Animation Fix Pack

Sep 12th, 2015
484
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 6.50 KB | None | 0 0
  1. #include <sourcemod>
  2. #include <dhooks>
  3. #include <sdktools>
  4.  
  5. static bool:incapped[MAXPLAYERS + 1] = false;
  6.  
  7. static bool:IsIncapEnabled;
  8. static bool:IsCoachEnabled;
  9. static bool:IsMeleeEnabled;
  10.  
  11. new Handle:sdkDoAnim;
  12. new Handle:hSequenceSet;
  13. static clienthook[MAXPLAYERS + 1] = -1;
  14.  
  15. public Plugin:myinfo =
  16. {
  17.     name = "[L4D2] Survivor Animation Fix Pack",
  18.     author = "DeathChaos25",
  19.     description = "A few quality of life animation fixes for the survivors",
  20.     version = "1.0",
  21.     url = ""
  22. }
  23.  
  24. public OnPluginStart()
  25. {
  26.     HookEvent("player_incapacitated", Event_Incap);
  27.     HookEvent("revive_end", Event_Interrupt);
  28.     PrepSDKCall();
  29.    
  30.     new Handle:IncapAnims = CreateConVar("enable_l4d1_incap_anims_fix", "1", "Fix missing collapse_to_incap missing animation for Louis/Bill/Francis?", FCVAR_PLUGIN, true, 0.0, true, 1.0);
  31.     HookConVarChange(IncapAnims, ConVarIncapAnims);
  32.     IsIncapEnabled = GetConVarBool(IncapAnims);
  33.    
  34.     new Handle:CoachEnabled = CreateConVar("enable_coach_anim_fix", "1", "Fix Coach's Single Pistol/Magnum running animation?", FCVAR_PLUGIN, true, 0.0, true, 1.0);
  35.     HookConVarChange(CoachEnabled, ConVarCoachEnabled);
  36.     IsCoachEnabled = GetConVarBool(CoachEnabled);
  37.    
  38.     new Handle:MeleeEnabled = CreateConVar("enable_hurtidlemelee_anim_fix", "1", "Fix broken L4D1 survivors hurt_idle_melee animations?", FCVAR_PLUGIN, true, 0.0, true, 1.0);
  39.     HookConVarChange(MeleeEnabled, ConVarMeleeEnabled);
  40.     IsMeleeEnabled = GetConVarBool(MeleeEnabled);
  41.    
  42.     AutoExecConfig(true, "l4d2_animations_fix");
  43.     LoadOffset();
  44. }
  45.  
  46. public Action:Event_Incap(Handle:event, const String:name[], bool:dontBroadcast)
  47. {
  48.     new client = GetClientOfUserId(GetEventInt(event, "userid"));
  49.     if (IsSurvivor(client) && !IsPlayerHeld(client))
  50.     {
  51.         incapped[client] = true;
  52.         CreateTimer(3.3, SETFALSE, client);
  53.     }
  54. }
  55.  
  56. public Action:Event_Interrupt(Handle:event, const String:name[], bool:dontBroadcast)
  57. {
  58.     new client = GetClientOfUserId(GetEventInt(event, "subject"));
  59.     if (IsSurvivor(client) && !IsPlayerHeld(client))
  60.     {
  61.         incapped[client] = false;
  62.         SDKCall(sdkDoAnim, client, 92, 0);
  63.     }
  64. }
  65.  
  66. public Action:SETFALSE(Handle:Timer, client)
  67. {
  68.     incapped[client] = false;
  69.     SDKCall(sdkDoAnim, client, 20, 0);
  70. }
  71.  
  72. public MRESReturn:OnSequenceSet(pThis, Handle:hReturn, Handle:hParams)
  73. {
  74.     new client = pThis;
  75.     if (IsSurvivor(client) && IsPlayerAlive(client) && !IsPlayerHeld(client))
  76.     {
  77.         new sequence = DHookGetReturn(hReturn);
  78.         //PrintToChat(client, "m_nSequence %i", sequence);
  79.         if (IsIncapacitated(client) && IsIncapEnabled && incapped[client])
  80.         {
  81.             new incap = GetIncapSequence(client);
  82.             if (incap != -1)
  83.             {
  84.                 DHookSetReturn(hReturn, incap);
  85.                 return MRES_Override;
  86.             }
  87.         }
  88.         else if (sequence == 581 && IsMeleeEnabled)
  89.         {
  90.             decl String:model[64];
  91.             GetEntPropString(client, Prop_Data, "m_ModelName", model, sizeof(model));
  92.             if (StrEqual(model, "models/survivors/survivor_teenangst.mdl", false))
  93.             {
  94.                 DHookSetReturn(hReturn, 571);
  95.                 return MRES_Override;
  96.             }
  97.         }
  98.         else if (!IsIncapacitated(client) && IsCoachEnabled)
  99.         {
  100.             decl String:model[64];
  101.             GetEntPropString(client, Prop_Data, "m_ModelName", model, sizeof(model));
  102.             if (StrContains(model, "coach", false) != -1)
  103.             {
  104.                 if (sequence == 202 && IsCoachEnabled)
  105.                 {
  106.                     DHookSetReturn(hReturn, 227); //Run_SMG
  107.                     return MRES_Override;
  108.                 }
  109.             }
  110.         }
  111.     }
  112.     return MRES_Ignored;
  113. }
  114.  
  115. bool:IsSurvivor(client)
  116. {
  117.     return (client > 0 && client <= MaxClients && IsClientInGame(client) && GetClientTeam(client) == 2);
  118. }
  119.  
  120. LoadOffset()
  121. {
  122.     new Handle:temp = LoadGameConfigFile("l4d2_sequence");
  123.    
  124.     if (temp == INVALID_HANDLE)
  125.     {
  126.         SetFailState("Error: Gamedata not found");
  127.     }
  128.    
  129.     new offset;
  130.     offset = GameConfGetOffset(temp, "CTerrorPlayer::SelectWeightedSequence");
  131.     if (offset == -1)
  132.     {
  133.         CloseHandle(temp);
  134.         LogError("Unable to get offset for CTerrorPlayer::SelectWeightedSequence");
  135.         return;
  136.     }
  137.     hSequenceSet = DHookCreate(offset, HookType_Entity, ReturnType_Int, ThisPointer_CBaseEntity, OnSequenceSet);
  138.     DHookAddParam(hSequenceSet, HookParamType_Int);
  139. }
  140.  
  141. stock bool:IsPlayerHeld(client)
  142. {
  143.     new jockey = GetEntPropEnt(client, Prop_Send, "m_jockeyAttacker");
  144.     new charger = GetEntPropEnt(client, Prop_Send, "m_pummelAttacker");
  145.     new hunter = GetEntPropEnt(client, Prop_Send, "m_pounceAttacker");
  146.     new smoker = GetEntPropEnt(client, Prop_Send, "m_tongueOwner");
  147.     if (jockey > 0 || charger > 0 || hunter > 0 || smoker > 0)
  148.     {
  149.         return true;
  150.     }
  151.     return false;
  152. }
  153. stock bool:IsIncapacitated(client)
  154. {
  155.     if (GetEntProp(client, Prop_Send, "m_isIncapacitated", 1) > 0)
  156.         return true;
  157.     return false;
  158. }
  159.  
  160. public OnAllPluginsLoaded() //late loading
  161. {
  162.     for (new client = 1; client <= MaxClients; client++)
  163.     {
  164.         if (IsSurvivor(client))
  165.         {
  166.             clienthook[client] = DHookEntity(hSequenceSet, true, client);
  167.         }
  168.     }
  169. }
  170.  
  171. public OnClientPutInServer(client)
  172. {
  173.     clienthook[client] = DHookEntity(hSequenceSet, true, client);
  174. }
  175.  
  176. stock GetIncapSequence(client)
  177. {
  178.     if (IsSurvivor(client))
  179.     {
  180.         decl String:model[64];
  181.         GetEntPropString(client, Prop_Data, "m_ModelName", model, sizeof(model));
  182.         if (StrContains(model, "namvet", false) != -1)
  183.         {
  184.             return 518;
  185.         }
  186.         else if (StrContains(model, "biker", false) != -1)
  187.         {
  188.             return 521;
  189.         }
  190.         else if (StrContains(model, "manager", false) != -1)
  191.         {
  192.             return 518;
  193.         }
  194.     }
  195.     return -1;
  196. }
  197.  
  198. public ConVarIncapAnims(Handle:convar, const String:oldValue[], const String:newValue[])
  199. {
  200.     IsIncapEnabled = GetConVarBool(convar);
  201. }
  202.  
  203. public ConVarCoachEnabled(Handle:convar, const String:oldValue[], const String:newValue[])
  204. {
  205.     IsCoachEnabled = GetConVarBool(convar);
  206. }
  207.  
  208. public ConVarMeleeEnabled(Handle:convar, const String:oldValue[], const String:newValue[])
  209. {
  210.     IsMeleeEnabled = GetConVarBool(convar);
  211. }
  212.  
  213. static PrepSDKCall()
  214. {
  215.     new Handle:config = LoadGameConfigFile("l4d2_sequence");
  216.    
  217.     if (config == INVALID_HANDLE)
  218.     {
  219.         SetFailState("Error: Why do you not have this extension's gamedata file?!");
  220.     }
  221.    
  222.     StartPrepSDKCall(SDKCall_Player);
  223.    
  224.     if (!PrepSDKCall_SetFromConf(config, SDKConf_Virtual, "CTerrorPlayer::DoAnimationEvent"))
  225.     {
  226.         CloseHandle(config);
  227.         SetFailState("Cant find CTerrorPlayer::DoAnimationEvent Signature in gamedata file");
  228.     }
  229.     PrepSDKCall_AddParameter(SDKType_PlainOldData, SDKPass_Plain);
  230.     PrepSDKCall_AddParameter(SDKType_PlainOldData, SDKPass_Plain);
  231.     CloseHandle(config);
  232.     sdkDoAnim = EndPrepSDKCall();
  233.     if (sdkDoAnim == INVALID_HANDLE)
  234.     {
  235.         SetFailState("Cant initialize CTerrorPlayer::DoAnimationEvent SDKCall, Signature broken");
  236.     }
  237. }
Advertisement
Add Comment
Please, Sign In to add comment