Jump to content

? servers

? players online

[ZE] Molotov Lag

Recommended Posts


  • Content Count:  1534
  • Joined:  07/27/09
  • Status:  Offline

I have noticed anytime multiple players throw Molotov's into a large enough group of players the server latency goes to shit... Depending on the map being played it can happen more often but in general I think its a major issue (there can be a 5-10 second delay before server processes something).

 

Can we possibly code our own Molotov / grenade plugin to replace this? I'm certain this could use less resources using some other method to slow the zombies.

 

 

Edit: Plugin is finished - [sM] GreNade Kick

 

 

#pragma semicolon 1

#include 
#include 
#include 
#include 
   
#pragma newdecls required

//Create ConVar handles
ConVar g_ConVar_Enabled;
ConVar g_ConVar_Debug;
ConVar g_ConVar_pDistance;
ConVar g_ConVar_vKnockback;
ConVar g_ConVar_hKnockback;
ConVar g_ConVar_StamPenalty;
ConVar g_ConVar_dmgCap;
ConVar g_ConVar_iTime;
ConVar g_ConVar_ringSize;
//Separate ConVar variables to prevent looping in hooks
bool g_Enabled = true;
bool g_Debug = false;
float g_pDistance = 1.0;
float g_vKnockback = 1.0;
float g_hKnockback = 1.0;
float g_StamPenalty = 0.0;
float g_dmgCap = 50.0;
float g_iTime = 0.0;
float g_ringSize = 0.0;
int g_StaminaOffset = -1;
int g_beamsprite = 0;
int g_halosprite = 0;
//Create our hash map handles
StringMap hMapDirection;
StringMap hMapOrigin;

public Plugin myinfo =  {
name = "Nade_Kick",
author = "AgentWesker",
description = "Zombie knockback plugin.",
version = "1.7",
url = "http://steam-gamers.net"
};

public void OnPluginStart()
{

//Get stamina offset
g_StaminaOffset = FindSendPropInfo("CCSPlayer", "m_flStamina");
if (g_StaminaOffset == -1) {  
	SetFailState("CCSPlayer::m_flStamina could not be found.");
}

//Stamina ConVar
g_ConVar_StamPenalty = CreateConVar("sm_nadekick_stampenalty", "100.0", "How much to slow the player. Default = 100.0", _, true, 0.0, true, 100.0);
g_StamPenalty = GetConVarFloat(g_ConVar_StamPenalty);
HookConVarChange(g_ConVar_StamPenalty, OnConVarChanged);

//Damage Cap ConVar
g_ConVar_dmgCap = CreateConVar("sm_nadekick_dmgcap", "30.0", "How much damage can affect velocity. Default = 50.0", _, true, 1.0, true, 100.0);
g_dmgCap = GetConVarFloat(g_ConVar_dmgCap);
HookConVarChange(g_ConVar_dmgCap, OnConVarChanged);

//Enabled ConVar
g_ConVar_Enabled = CreateConVar("sm_nadekick_enabled", "1", "Enable/Disable the plugin. Enable = 1", _, true, 0.0, true, 1.0);
g_Enabled = GetConVarBool(g_ConVar_Enabled);
HookConVarChange(g_ConVar_Enabled, OnConVarChanged);

//Debug ConVar
g_ConVar_Debug = CreateConVar("sm_nadekick_debug", "0", "Print debug to chat. Enable = 1", _, true, 0.0, true, 1.0);
g_Debug = GetConVarBool(g_ConVar_Debug);
HookConVarChange(g_ConVar_Debug, OnConVarChanged);

//Distance ConVars
g_ConVar_pDistance = CreateConVar("sm_nadekick_pdistance", "115.0", "How far to measure in front of attacker. Default = 115.0", _, true, 0.1, true, 1500.0);
g_pDistance = GetConVarFloat(g_ConVar_pDistance);
HookConVarChange(g_ConVar_pDistance, OnConVarChanged);

//Ignite ConVar
g_ConVar_iTime = CreateConVar("sm_nadekick_itime", "5.0", "How long to ignite the victim. Disabled = 0", _, true, 0.0, true, 15.0);
g_iTime = GetConVarFloat(g_ConVar_iTime);
HookConVarChange(g_ConVar_iTime, OnConVarChanged);

//Grenade Ring ConVar
g_ConVar_ringSize = CreateConVar("sm_nadekick_ringSize", "375.0", "How large to make the ring effect. Disabled = 0", _, true, 0.0, true, 800.0);
g_ringSize = GetConVarFloat(g_ConVar_ringSize);
HookConVarChange(g_ConVar_ringSize, OnConVarChanged);

//Knockback ConVars
g_ConVar_vKnockback = CreateConVar("sm_nadekick_vknockback", "20.0", "Vertical knockback multiplier. Default = 20.0", _, true, 0.1, true, 1000.0);
g_ConVar_hKnockback = CreateConVar("sm_nadekick_hknockback", "30.0", "Horizontal knockback multiplier. Default = 30.0", _, true, 0.1, true, 1000.0);
g_vKnockback = GetConVarFloat(g_ConVar_vKnockback);
g_hKnockback = GetConVarFloat(g_ConVar_hKnockback);
HookConVarChange(g_ConVar_vKnockback, OnConVarChanged);
HookConVarChange(g_ConVar_hKnockback, OnConVarChanged);

//Hook events
HookEvent("player_death", OnPlayerDeath);
if (g_ringSize > 10.0) {
	HookEvent("hegrenade_detonate", OnHeDetonate);
}

//Create our hash maps
hMapDirection = new StringMap();
hMapOrigin = new StringMap();

//Execute the config and create if not yet made
AutoExecConfig(true, "nade_kick");

//Late plugin load (or reload)
for (int i = 1; i 	{
	if (IsClientInGame(i))
	{
		OnClientPutInServer(i);
	}
}
}

public void OnMapStart() 
{
g_beamsprite = PrecacheModel("materials/sprites/laserbeam.vmt");
g_halosprite = PrecacheModel("materials/sprites/halo.vmt");
}

public void OnConVarChanged(ConVar convar, const char[] oldVal, const char[] newVal)
{
if (convar == g_ConVar_Enabled) {
	if (StringToInt(newVal) == 1) {
		g_Enabled = true;
		HookClients();
	} else {
		g_Enabled = false;
		UnHookClients();
	}
} else if (convar == g_ConVar_Debug) {
	if (StringToInt(newVal) == 1) {
		g_Debug = true;
	} else {
		g_Debug = false;
	}
} else if (convar == g_ConVar_pDistance) {
	g_pDistance = StringToFloat(newVal);
} else if (convar == g_ConVar_vKnockback) {
	g_vKnockback = StringToFloat(newVal);
} else if (convar == g_ConVar_hKnockback) {
	g_hKnockback = StringToFloat(newVal);
} else if (convar == g_ConVar_StamPenalty) {
	g_StamPenalty = StringToFloat(newVal);
} else if (convar == g_ConVar_dmgCap) {
	g_dmgCap = StringToFloat(newVal);
} else if (convar == g_ConVar_iTime) {
	g_iTime = StringToFloat(newVal);
} else if (convar == g_ConVar_ringSize) {
	g_ringSize = StringToFloat(newVal);
	if (g_ringSize > 10.0) {
		HookEvent("hegrenade_detonate", OnHeDetonate);
	} else {
		UnhookEvent("hegrenade_detonate", OnHeDetonate);
	}
}
}

public void HookClients()
{
for (int i = 1; i 	{
	if(IsClientInGame(i))
	{
		SDKHook(i, SDKHook_OnTakeDamagePost, OnTakeDamagePost);
	}
}
}

public void UnHookClients()
{
for (int i = 1; i 	{
	if(IsClientInGame(i))
	{
		SDKUnhook(i, SDKHook_OnTakeDamagePost, OnTakeDamagePost);
	}
}
}

public void OnClientPutInServer(int client)
{
//dont hook stuff that isnt needed 
if(!g_Enabled)
	return;

//Use an SDKHook for inflictor index
SDKHook(client, SDKHook_OnTakeDamagePost, OnTakeDamagePost);
}

public void OnClientDisconnect(int client)
{
//Get rid of this timer (?)
if (IsClientInGame(client)) {
	ExtinguishEntity(client);
}
}

public void OnPlayerDeath(Event event, const char[] name, bool dontBroadcast)
{
OnClientDisconnect(GetClientOfUserId(GetEventInt(event, "userid")));
}

public void OnEntityCreated(int entity, const char[] classname)
{
//Is the plugin enabled? Otherwise don't continue
if (!g_Enabled) {
	return;
}
//Is this a valid entity?
if (IsValidEdict(entity)) {
	char class_name[32];
	GetEdictClassname(entity, class_name, 32);
	//Only hook projectiles if they are valid
	if (StrContains(class_name, "hegrenade_projectile", false) != -1 && IsValidEntity(entity)) {
		if (g_Debug) {
			PrintToChatAll("[sM]Nade Kick: Hooked projectile %d", entity);
		}
		if (g_iTime > 0.0) {
			IgniteEntity(entity, 2.0);
		}
		//Hook the entity, we must wait until post spawn
		SDKHook(entity, SDKHook_SpawnPost, OnEntitySpawned);
	}
}
}

public void OnEntitySpawned(int entity)
{
if(!g_Enabled)
	return;

int owner = GetEntPropEnt(entity, Prop_Data, "m_hOwnerEntity"); //The client
  
//Origin vectors define position (X, Y, Z)
//Angle vectors define orientation (Pitch, Yaw, Roll)
//Magnitude vectors define direction (X, Y, Z) anything from zero is distance
  
//Create vector from player
float pEyeOrigin[3], pEyeAngles[3];
GetClientEyePosition(owner, pEyeOrigin); //Player origin
GetClientEyeAngles(owner, pEyeAngles); //Player angles

//Flatten player angles along Z axis
pEyeAngles[0] = 0.0; //Set pitch
pEyeAngles[2] = 0.0; //Set roll

if (g_Debug) {
	PrintToChatAll("[sM]Nade Kick: %N angle is %f", owner, pEyeAngles[1]);
}

//Get direction
GetAngleVectors(pEyeAngles, pEyeAngles, NULL_VECTOR, NULL_VECTOR); //Transform into vector
NormalizeVector(pEyeAngles, pEyeAngles); //Clamp vector
ScaleVector(pEyeAngles, g_pDistance); //How far ahead of player we go
AddVectors(pEyeOrigin, pEyeAngles, pEyeOrigin); //Move origin along vector

//Save pgVector to hash
char entStr[12];
IntToString(entity, entStr, 12);
hMapDirection.SetArray(entStr, pEyeAngles, 3, true);
hMapOrigin.SetArray(entStr, pEyeOrigin, 3, true);
}

public void OnTakeDamagePost(int victim, int attacker, int inflictor, float damage, int damagetype, int weapon, 
	const float damageForce[3], const float damagePosition[3], int damagecustom)
{
//Stop if disabled
if (!g_Enabled) {
	return;
}

//Is player alive?
if (!IsClientInGame(attacker)) {
	return;
} else {
	if (!IsPlayerAlive(attacker)) {
		return;
	}
}

char sWeapon[32];
GetEdictClassname(inflictor, sWeapon, sizeof(sWeapon));

// If the player is a zombie and it is hurt with a grenade
if ((ZR_IsClientZombie(victim) && ZR_IsClientHuman(attacker)) && StrContains("hegrenade_projectile", sWeapon, false) != -1 && damage >= 2.0) {

	//Initialize vector handles, aForward and aVictim directions
	float victimOrigin[3], attackerOrigin[3], grenadeOrigin[3], afVector[3], avVector[3];
	
	if (g_Debug) {
		char nameentname[225];
		GetEdictClassname(inflictor, nameentname, sizeof(nameentname));
		PrintToChatAll("[sM]Nade Kick: Inflictor ent %d, %s", inflictor, nameentname);
	}
	
	//Use entity index as key and grab afVector from hash
	char inflictorStr[12];
	IntToString(inflictor, inflictorStr, 12);
	
	//Check that hash values return successfully otherwise call the cops
	if (!hMapDirection.GetArray(inflictorStr, afVector, 3, _)) {
		ThrowError("Attacker has no direction vector, inflictor not found!");
	}
	else if (!hMapOrigin.GetArray(inflictorStr, attackerOrigin, 3, _)) {
		ThrowError("Attacker has no origin vector, inflictor not found!");
	}
	
	//Get the origin vector for victim
	GetEntPropVector(victim, Prop_Send, "m_vecOrigin", victimOrigin);
	
	//Make new vector from player to victim
	MakeVectorFromPoints(attackerOrigin, victimOrigin, avVector);
	NormalizeVector(avVector, avVector);
	
	//Re-normalize the attacker forward vector
	NormalizeVector(afVector, afVector);
	
	//Get the angle between player forward view and player viewing victim
	float dot = GetVectorDotProduct(afVector, avVector); //Get initial dot product
	dot = (dot / FloatMul(GetVectorLength(avVector, true), GetVectorLength(afVector, true))); //Divide by vector magnitude
	float vectorAngle = RadToDeg(ArcCosine(dot)); //Get angle in radians, then convert to degrees


	if (g_Debug) {
		PrintToChatAll("[sM]Nade Kick: %N angle is %f", victim, vectorAngle);
		PrintToChatAll("[sM]Nade Kick: %N took %f damage", victim, damage);
	}
	
	float dmgMulti = damage;
	if (damage >= g_dmgCap) {
		dmgMulti = g_dmgCap;
	}
	
	//Check if victim is behind attacker
	if (vectorAngle 			GetEntPropVector(inflictor, Prop_Send, "m_vecOrigin", grenadeOrigin);
		
		MakeVectorFromPoints(grenadeOrigin, victimOrigin, avVector);
		NormalizeVector(avVector, avVector);
		
		dot = GetVectorDotProduct(afVector, avVector); //Get initial dot product
		dot = (dot / FloatMul(GetVectorLength(avVector, true), GetVectorLength(afVector, true))); //Divide by vector magnitude
		vectorAngle = RadToDeg(ArcCosine(dot)); //Get angle in radians, then convert to degrees
		
		if (vectorAngle 				afVector[0] = avVector[0];
			afVector[1] = avVector[1];
		}
		
		//Scale original values to maintain direction
		ScaleVector(afVector, g_hKnockback); //Scale by multiplier
		ScaleVector(afVector, dmgMulti); //Scale by damage
	} else {
		//Only go vertical
		afVector[0] = 0.0;
		afVector[1] = 0.0;
	}
	
	afVector[2] = FloatMul(g_vKnockback, dmgMulti); //Set vertical velocity

	//Only ignite if we have time
	if (g_iTime > 0.0) {
		//Don't double ignite
		ExtinguishEntity(victim);
		IgniteEntity(victim, g_iTime);
	}
	
	// Apply the directional push
	TeleportEntity(victim, NULL_VECTOR, NULL_VECTOR, afVector);
	//Slow the player
	if (g_StamPenalty > 0.0) {
		SetEntDataFloat(victim, g_StaminaOffset, g_StamPenalty, true);
	}
}
}

public void OnHeDetonate(Event event, const char[] name, bool dontBroadcast) {
//Stop if disabled
if ((!g_Enabled) || (g_ringSize 		return;
}

//Get the origin for the ring
float origin[3];
origin[0] = GetEventFloat(event, "x");
origin[1] = GetEventFloat(event, "y");
origin[2] = GetEventFloat(event, "z");

//Color the ring
int fragColor[4] = {255,75,75,255};
//Set the life time
float ringLife = FloatDiv(g_ringSize, 1000.0);
if (ringLife 		ringLife = 0.1;
}

TE_SetupBeamRingPoint(origin, 10.0, g_ringSize, g_beamsprite, g_halosprite, 1, 1, ringLife, 100.0, 1.0, fragColor, 0, 0);
TE_SendToAll();
}

 

  • Like 1
Edited by Wesker
Link to comment

  • Content Count:  1747
  • Joined:  03/17/12
  • Status:  Offline

Can we possibly code our own Molotov / grenade plugin to replace this? I'm certain this could use less resources using some other method to slow the zombies.

 

The issue is that there really isnt another method to do the same effect.

Link to comment

  • Content Count:  1534
  • Joined:  07/27/09
  • Status:  Offline

The issue is that there really isnt another method to do the same effect.

 

Can we edit the grenade boost plugin to automatically apply a 5 second stamina reduction to any zombies that are boosted?

 

One time application of stamina vs constant knockback for the duration of molotov?

 

Edit: Or rather than stamina set player speed to half until they reach the ground again

 

grenadeboost.sp : This plugin makes HE grenades have vertical knockback only, sending zombies upwards when they’re hit by a grenade. It makes failnades happen less while still slowing zombies down but without causing a huge fps drop form the burning particle effects. Of course, Z:R grenade knockback is expected to be set to zero although low values for it might be interesting too.

 

Cvars:

 

zr_vertical_nade_kb [DEFAULT : 7.0 ] – Amount of vertical knockback to apply by multiplying it with the damage dealt when hurt by a grenade.

 

 

inf_knockback_hook.sp : This plugin will let you have knockback coming from these inferno entities that push zombies outwards of the fire’s center. It will also let you decide whether you want them to push upwards or not (that is, have knockback as an sphere or as a circle/cylinder).

 

Cvars:

 

zr_inferno_novertical [DEFAULT : 1 ] – Whether to allow vertical knockback on inferno-based damage or not.

zr_inferno_knockscale [DEFAULT: 112.0 ] – Amount of knockback to apply on these inferno entities. Perhaps a bit high by default, so toy around with it.

Edited by Wesker
Link to comment

  • Content Count:  1747
  • Joined:  03/17/12
  • Status:  Offline

Can we edit the grenade boost plugin to automatically apply a 5 second stamina reduction to any zombies that are boosted?

 

One time application of stamina vs constant knockback for the duration of molotov?

 

Edit: Or rather than stamina set player speed to half until they reach the ground again

 

We used to use stamina penalty to repoduce old molotov grenades from css and it caused even more lag than the current inferno knockback ones.

Link to comment

  • Content Count:  1534
  • Joined:  07/27/09
  • Status:  Offline

Here is the Molotov plugin:

 

 

[color="#FFFFFF"]public OnTakeDamagePost(client, attacker, entity, Float:damage, damagetype, weapon, const Float:damageForce[3], const Float:damagePosition[3])
{
// If the player hit isn't a zombie
if(!ZR_IsClientZombie(client))
{
	return;
}

// If we don't smell the BBQ then we'll pass
if (!(damagetype & DMG_BURN))
{
	return;
}

// Get the whole vector thing rolling
new Float:playerLoc[3];
new Float:infernoLoc[3];

GetEntPropVector(client, Prop_Send, "m_vecOrigin", playerLoc);	
GetEntPropVector(entity, Prop_Send, "m_vecOrigin", infernoLoc);

new Float:pushVector[3];		
MakeVectorFromPoints(infernoLoc, playerLoc, pushVector);

// If we don't want fire to push us upwards (which doesn't make sense anyway)
// We set the Z-component of the vector to 0
if(noVertical){
	pushVector[2] = 0.0;
}

// Normalize the vector so that the length is 1 and the scaling is uniform
NormalizeVector(pushVector, pushVector);
		
// Scale the vector (ideally, when merged with Z:R, this'd be the weapon multiplier)
// It would need to be upscaled too since flames deal (too) low damage.
ScaleVector(pushVector, knockback);
		
// Apply velocity on client
// In Z:R, this would be integrated in knockback.inc 
// and we'd make use of the call to ToolsClientVelocity in tools_functions.inc
TeleportEntity(client, NULL_VECTOR, NULL_VECTOR, pushVector);	
}[/color]

 

 

Here is the old napalm grenade plugin:

 

 

[color="#FFFFFF"]
public OnTakeDamagePost(client, attacker, inflictor, Float:damage, damagetype)
{
if (!(damagetype & DMG_BURN))
{
	return;
}

if (attacker >= 1 && attacker 	{
	if (g_NapalmOnly == true)
	{
		return;
	}
}

if (!IsClientOnObject(client))
{	
	return;
}


SetEntDataFloat(client, g_StaminaOffset, g_Penalty, true);
return;
}[/color]

 

 

And finally the grenade plugin that pushes zombies upward:

 

 

[color="#FFFFFF"]
public Event_HandleNadeDamage(Handle:event, const String:name[], bool:dontBroadcast){ 
new clientid = GetEventInt(event, "userid");
new client = GetClientOfUserId(clientid);
new damage = GetEventInt(event,"dmg_health");
decl String:weapon[32];
GetEventString(event, "weapon", weapon, sizeof(weapon));

// If the player is a zombie and it is hurt with a grenade
if(GetClientTeam(client)==2 && StrEqual("hegrenade", weapon)){
	// Generate the vector
	new Float:vector[3];
	vector[0] = 0.0;
	vector[1] = 0.0;
	vector[2] = knockback*damage;

	// Apply the push
	TeleportEntity(client, NULL_VECTOR, NULL_VECTOR, vector);
}
}[/color]

 

 

 

The last one only processes one time, so theoretically if we change the players stamina in there and modify sv_staminarecoveryrate to a low value the plugin does very little impact...?

Edited by Wesker
Link to comment

  • Content Count:  1747
  • Joined:  03/17/12
  • Status:  Offline

Here is the Molotov plugin:

 

 

 

Here is the old napalm grenade plugin:

 

 

 

And finally the grenade plugin that pushes zombies upward:

 

 

 

 

The last one only processes one time, so theoretically if we change the players stamina in there and modify sv_staminarecoveryrate to a low value the plugin does very little impact...

I know the sourcecode of all of them, and while theoretically it should be lighter, in actual live testing that i did about a 6 to 9 months ago demonstrated the opposite

Link to comment

  • Content Count:  1534
  • Joined:  07/27/09
  • Status:  Offline

Well then I'm pretty much out of ideas.

 

Only one I got left is to remove molotov's entirely - Then make the knockback nades push zombies in the direction the player looked when the grenade was thrown (at an upwards angle)

 

5trtyv.jpg

Edited by Wesker
Link to comment

  • Content Count:  2262
  • Joined:  02/05/12
  • Status:  Offline

Well then I'm pretty much out of ideas.

 

Only one I got left is to remove molotov's entirely - Then make the knockback nades push zombies in the direction the player looked when the grenade was thrown (at an upwards angle)

 

5trtyv.jpg

 

I hope you didn't forget about people nading the zombie ahead when they spawn ahead of them

Link to comment

  • Content Count:  1468
  • Joined:  06/27/10
  • Status:  Offline

I hope you didn't forget about people nading the zombie ahead when they spawn ahead of them

 

As it boosts them in the direction you face, they would have to be behind them. If they're going to troll this method, they may as well FailKnife them forward in the first place.

Link to comment

  • Content Count:  954
  • Joined:  05/29/12
  • Status:  Offline

As it boosts them in the direction you face, they would have to be behind them. If they're going to troll this method, they may as well FailKnife them forward in the first place.

 

Bouncing it off a wall back into the zombies.

You underestimate the ingenuity of the people trying to teamkill.

Link to comment

Reply to Thread

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...