Raised This Month: $51 Target: $400
 12% 

[L4D2] Replacing charger with hunter ( trap )


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
eyal282
Veteran Member
Join Date: Aug 2011
Old 05-03-2017 , 16:34   [L4D2] Replacing charger with hunter ( trap )
Reply With Quote #1

I made a simple plugin that allows the hunter to steal the charger's target by pressing LSHIFT + Punching the charger. When I set m_pounceVictim and Attacker, although it traps him with damage being dealt, there is an animation issue for both the hunter and the survivor. Also the hunter can be one hit even when I set his health to 50000.

That's my code so far:

Code:
#include <sourcemod>
#include <sdktools>
#include <sdkhooks>

#define IsPlayer(%1) ( 1 <= %1 <= MAXPLAYERS ) // Players have the index of one and above and the last index is taken with MAXPLAYERS.

new const ZC_HUNTER = 3, ZC_CHARGER = 6; // Permanent values.

public Plugin:myinfo = 
{
	name = "Hunter Steal From Charger",
	author = "FuckTheSchool ( Eyal282 )",
	description = "Allows a hunter to steal from charger by punching the survivor while holding LSHIFT.",
	version = "1.0",
	url = "<- URL ->"
}

public OnPluginStart()
{
	HookEvent("player_hurt", Event_Hurt, EventHookMode_Post); // We need to check when the hunter punches a charger that holds a survivor.
	
	RegConsoleCmd("sm_test", Test);
}

public Action Test(Hunter, int Args)
{
	//new AbilityEnt = GetEntPropEnt(Hunter, Prop_Send, "m_customAbility"); // Get the property of the hunter's custom ability ( pounce ).
	
	//if(AbilityEnt == 0) // This is extremely unlikely to be 0.
	//	return Plugin_Continue;
		
		
//	SetEntPropEnt(2, Prop_Send, "m_pounceAttacker", Hunter); // Sets the trapping of the survivor to the hunter.
	//SetEntPropEnt(Hunter, Prop_Send, "m_pounceVictim", 2); // Sets the trapping of the hunter to the survivor.
	new String:Name[32], String:Name2[32];
	new Att = GetEntProp(Hunter, Prop_Send, "m_nSequence")
	new Att2 = GetEntPropEnt(Hunter, Prop_Send, "m_pounceAttacker")
	if(IsPlayer(Att))
		GetClientName(Att, Name, 31);
	
	else
	{
		new Att11 = GetClientOfUserId(Att);
		if(IsPlayer(Att11))
			GetClientName(Att11, Name, 31);
	}
	if(IsPlayer(Att2))
		 GetClientName(Att2, Name2, 31);
	
	else
	{
		new Att22 = GetClientOfUserId(Att2);
		if(IsPlayer(Att22))
			GetClientName(Att22, Name2, 31);
	}
	PrintToChat(Hunter, "%s|%i  %s|%i", Name, Att, Name2, Att2);

	return Plugin_Continue;
}

public Action Event_Hurt(Handle hEvent, const char[] sEventName, bool bDontBroadcast) // The event of a player hurting another one.
{
	int Charger = GetClientOfUserId(GetEventInt(hEvent, "userid")); // Gets the ID of the victim of the attack.
	int Hunter = GetClientOfUserId(GetEventInt(hEvent, "attacker")); // Gets the ID of the attacker

	if(!IsPlayer(Hunter) || !IsPlayer(Charger)) // Mostly debug, testing if the Hunter and the Charger are actual players ( bots included ).
		return Plugin_Continue;
	
	if(!IsClientInfected(Hunter) || GetClientClass(Hunter) != ZC_HUNTER) // Is the attacker an hunter?
		return Plugin_Continue;
	
	if(!(GetClientButtons(Hunter) & IN_SPEED) || GetClientButtons(Hunter) & IN_DUCK) // bind SHIFT "+speed" is default. Duck seems to bug the player so I'll prevent it.
		return Plugin_Continue;
		
	if(!(GetEntityFlags(Hunter) & FL_ONGROUND)) // This one also bugs it, I would love to know how to simply set a pounce victim with it actually working...
		return Plugin_Continue;

	if(GetClientClass(Charger) != ZC_CHARGER) // Is the victim of the attack a charger?
		return Plugin_Continue;

	new Survivor = GetEntPropEnt(Charger, Prop_Send, "m_pummelVictim"); // Find the survivor the Charger is grabbing.
	
	if(!IsPlayer(Survivor)) // Does the charger have a victim?
		return Plugin_Continue;
	
	if(!IsClientSurvivor(Survivor)) // Is the victim a survivor? Obviously yes but who knows...
		return Plugin_Continue;
	
	SetEntPropEnt(Survivor, Prop_Send, "m_pummelAttacker", -1); // Removes the player from being owned by the Charger.
	SetEntPropEnt(Charger, Prop_Send, "m_pummelVictim", -1); // Removes the Charger from owning the player.
	//SetEntProp(Survivor, Prop_Send, "m_nSequence", 0); // This and the line below it are meant to remove the animation of getting up from charger.
	//SetEntProp(Survivor, Prop_Send, "m_flAnimTime", 0); // This and line above allow the player to be pounced immidiately.
	//SetEntProp(Hunter, Prop_Send, "m_nSequence", 0); // To be sure...
	//SetEntProp(Hunter, Prop_Send, "m_flAnimTime", 0); // To be sure...
	
	new AbilityEnt = GetEntPropEnt(Hunter, Prop_Send, "m_customAbility"); // Get the property of the hunter's custom ability ( pounce ).
	
	if(AbilityEnt == 0) // This is extremely unlikely to be 0.
		return Plugin_Continue;
	
		SetEntProp(AbilityEnt, Prop_Send, "m_isLunging", 1); // Confuses the game to think the hunter is pouncing.
	SetEntProp(Hunter, Prop_Send, "m_isAttemptingToPounce", 1); // Sets the trapping of the hunter to the survivor
	
	SetEntPropEnt(Survivor, Prop_Send, "m_pounceAttacker", Hunter); // Sets the trapping of the survivor to the hunter.
	SetEntPropEnt(Hunter, Prop_Send, "m_pounceVictim", Survivor); // Sets the trapping of the hunter to the survivor.
	
	SetEntProp(AbilityEnt, Prop_Send, "m_hasBeenUsed", 1);
	SetEntProp(AbilityEnt, Prop_Send, "m_isLunging", 0); // Confuses the game to think the hunter is pouncing.
	SetEntProp(Hunter, Prop_Send, "m_isAttemptingToPounce", 0); // Sets the trapping of the hunter to the survivor
	
	//SetEntProp(Hunter, Prop_Send, "m_nSequence", 38);
	
	//Handle datapack;
	//CreateDataTimer(5.0, Nigga, datapack);
	
	//WritePackCell(datapack, GetClientUserId(Hunter));
	//WritePackCell(datapack, GetClientUserId(Survivor));

	/*
	
	new Float:Origin[3], Float:OriginForCharger[3];
	SetEntProp(Hunter, Prop_Send, "m_isAttemptingToPounce", 1); // Simulates in the code the attempt of pouncing ( if player touches a survivor with this as 1, pounce will innitiate )
	GetEntPropVector(Survivor, Prop_Send, "m_vecOrigin", Origin); // Get the Survivor's origin to teleport him and the hunter to it later.
	GetEntPropVector(Hunter, Prop_Send, "m_vecOrigin", OriginForCharger); // Get the Hunter's origin so to teleport the charger to it to prevent being stuck.
	
	
	TeleportEntity(Survivor, Float:{ 0.0, 0.0, 50000.0 }, NULL_VECTOR, Float:{ 0.0, 0.0, 0.0 } ); // Teleports the survivor into the sky with 0 velocity to be still.
	
	TeleportEntity(Hunter, Float:{ 0.0, 0.0, 50100.0 }, NULL_VECTOR, Float:{ 0.0, 0.0, -1500.0 } ); // Teleports the hunter above the player at exactly 1500 units with fall velocity of 1000 ( normal fall velocity is probably 250 { atleast in CS 1.6 it is } )

	Handle pack;
	
	
	SetEntPropFloat(Charger, Prop_Send, "m_duration", 5.0);
	SetEntPropFloat(Charger, Prop_Send, "m_timestamp", GetGameTime() + 5.0); // To prevent issues. Hopefully no survivor will catch him by then.
	CreateDataTimer(0.0001, Teleport, pack); // After 0.1 seconds ( enough for the hunter to pounce the survivor ) both are teleported to the location of the player
	
	WritePackCell(pack, GetClientUserId(Hunter)); // In all the writings we add information to the teleportation.
	WritePackCell(pack, GetClientUserId(Survivor));
	WritePackCell(pack, GetClientUserId(Charger));
	for(new i;i < 3;i++)
	{
		WritePackFloat(pack, Origin[i]);
		WritePackFloat(pack, OriginForCharger[i]);
	}
	SetEntityFlags(Hunter, GetEntityFlags(Hunter) &~ FL_ONGROUND); // Might be useless. Used to remove the flag of the hunter being on ground. This to count the m_pounceStartPosition change.
	
	SetEntProp(Hunter, Prop_Send, "m_isAttemptingToPounce", 1); // The first one was a back up. This is the more important one.
	
	GetEntPropVector(Survivor, Prop_Send, "m_vecOrigin", Origin); // Already used it as we need.
	SetEntPropVector(Hunter, Prop_Send, "m_pounceStartPosition", Origin );
	*/
	return Plugin_Continue;
	
}

public Action:Nigga(Handle timer, Handle datapack)
{
	ResetPack(datapack);
	new Hunter = GetClientOfUserId(ReadPackCell(datapack));
	new Survivor = GetClientOfUserId(ReadPackCell(datapack));
	
	SetEntPropEnt(Hunter, Prop_Send, "m_pounceVictim", Survivor); // Sets the trapping of the hunter to the survivor.
	SetEntPropEnt(Survivor, Prop_Send, "m_pounceAttacker", Hunter); // Sets the trapping of the survivor to the hunter.
}
public Action:Teleport(Handle timer, Handle pack)
{
	ResetPack(pack); // I actually have no idea what's that needed for, but I am not going to argue.
	
	new Hunter = GetClientOfUserId(ReadPackCell(pack)) // Get the ID of the Hunter.
	new Survivor = GetClientOfUserId(ReadPackCell(pack)) // Get the ID of the already pounced Survivor.
	new Charger = GetClientOfUserId(ReadPackCell(pack)); // Get the ID of the Charger that lost his prey.
	new Float:Origin[3], Float:OriginForCharger[3];
	
	for(new i;i < 3;i++)
	{
		Origin[i] = ReadPackFloat(pack); // Get the origin needed to teleport the Hunter and the Survivor.
		OriginForCharger[i] = ReadPackFloat(pack); // Get the origin needed to teleport the Charger to.
	}
	
	if(!IsClientInGame(Hunter) || !IsPlayerAlive(Hunter))
	{
		if(IsClientInGame(Survivor) && IsPlayerAlive(Survivor))
		{
			TeleportEntity(Survivor, Origin, Float:{ 0.0, 0.0, 0.0 }, Float:{ 0.0, 0.0, 0.0 } ); // Teleports the Survivor back to the original Origin.
			return;
		}
	}
	
	if(!IsClientInGame(Survivor) || !IsPlayerAlive(Survivor))
	{
		if(IsClientInGame(Hunter) && IsPlayerAlive(Hunter))
		{
			TeleportEntity(Hunter, Origin, Float:{ 0.0, 0.0, 0.0 }, Float:{ 0.0, 0.0, 0.0 } ); // Teleports the Hunter back to the original Origin.
			return;
		}
	}
	
	if(GetEntProp(Hunter, Prop_Send, "m_pounceVictim") == 0 || GetEntProp(Survivor, Prop_Send, "m_pounceAttacker") == 0)
	{	
		CreateDataTimer(0.001, Teleport, pack); // The whole proccess here is to teleport them back as soon as possible with the minimum pounce damage.
		
		WritePackCell(pack, GetClientUserId(Hunter)); // In all the writings we add information to the teleportation.
		WritePackCell(pack, GetClientUserId(Survivor));
		WritePackCell(pack, GetClientUserId(Charger));
		for(new i;i < 3;i++)
		{
			WritePackFloat(pack, Origin[i]);
			WritePackFloat(pack, OriginForCharger[i]);
		}
		
		new Float:FakeOrigin[3];
		
		GetEntPropVector(Survivor, Prop_Send, "m_vecOrigin", FakeOrigin);
		
		SetEntPropVector(Hunter, Prop_Send, "m_pounceStartPosition", FakeOrigin);

		return;
	}
	
	if(IsClientInGame(Charger))
		TeleportEntity(Charger, OriginForCharger, NULL_VECTOR, NULL_VECTOR); // In order to prevent collision between Charger and Hunter, we teleport him to the Hunter's old origin.
	
	TeleportEntity(Hunter, Origin, Float:{ 0.0, 0.0, 0.0 }, Float:{ 0.0, 0.0, 0.0 } ); // Teleports the Hunter back to the original Origin.
	
	TeleportEntity(Survivor, Origin, Float:{ 0.0, 0.0, 0.0 }, Float:{ 0.0, 0.0, 0.0 } ); // Teleports the Survivor back to the original Origin.
	
}

stock bool:IsClientInfected(index) // Bolean stock to check if a client is infected.
{
	if(index <= 0)
		return false;
	
	if(!IsClientInGame(index))
		return false;
	
	return GetClientTeam(index) == 3;
}

stock bool:IsClientSurvivor(index) // Bolean stock to check if a client is survivor.
{
	if(index <= 0)
		return false;
	
	if(!IsClientInGame(index))
		return false;
	
	return GetClientTeam(index) == 2;
}

/*
stock bool:IsTrapperZombie(index)
{
	if(index <= 0)
		return false;
	
	if(!IsindexInGame(index))
		return false;
	
	new class = GetEntProp(index, Prop_Send, "m_zombieClass");
	return ( class == ZC_CHARGER || class == ZC_HUNTER || class == ZC_JOCKEY || class == ZC_SMOKER );
}
*/
stock GetClientClass(index) // Gets the zombie class of a player.
{
	if(index <= 0)
		return false;
	
	if(!IsClientInGame(index))
		return false;
	
	return GetEntProp(index, Prop_Send, "m_zombieClass");
}
eyal282 is offline
eyal282
Veteran Member
Join Date: Aug 2011
Old 05-05-2017 , 08:55   Re: [L4D2] Replacing charger with hunter ( trap )
Reply With Quote #2

Bump
eyal282 is offline
Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 07:44.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode