#include #include #include #include #pragma semicolon 1 #pragma newdecls required ConVar g_hCVar_PushNadesEnabled; ConVar g_hCVar_PushStrength; ConVar g_hCVar_PushScale; int g_iToolsActiveWeapon; int g_iToolsVelocity; //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Plugin myinfo = { name = "PushNades", author = "Neon", description = "Push Zombies away from the Human that threw the HE-Grenade", version = "2.0", url = "https://steamcommunity.com/id/n3ontm" } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void OnPluginStart() { g_hCVar_PushNadesEnabled = CreateConVar("sm_hegrenade_push_enabled", "0", "Enable PushBack for HE-Grenades", 0, true, 0.0, true, 1.0); g_hCVar_PushScale = CreateConVar("sm_hegrenade_push_scale", "0", "Make the push scale with the distance to the explosion", 0, true, 0.0, true, 1.0); g_hCVar_PushStrength = CreateConVar("sm_hegrenade_push_strength", "500", "How strong the HE-Grenade pushes back"); g_iToolsActiveWeapon = FindSendPropInfo("CBasePlayer", "m_hActiveWeapon"); g_iToolsVelocity = FindDataMapInfo(0, "m_vecAbsVelocity"); AutoExecConfig(); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void OnClientPutInServer(int client) { SDKHook(client, SDKHook_OnTakeDamageAlivePost, DamageOnTakeDamageAlivePost); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public void DamageOnTakeDamageAlivePost(int victim, int attacker, int inflictor, float damage, int damagetype, int weapon, const float damageForce[3], const float damagePosition[3], int damagecustom) { char sWeapon[64]; if (inflictor == attacker) { weapon = WeaponsGetActiveWeaponIndex(attacker); if (weapon > 0) GetEdictClassname(weapon, sWeapon, sizeof(sWeapon)); } else GetEdictClassname(inflictor, sWeapon, sizeof(sWeapon)); if (!StrEqual(sWeapon, "hegrenade_projectile")) return; if (!g_hCVar_PushNadesEnabled.BoolValue) return; if (!IsValidClient(attacker, false) || !IsValidClient(victim, false)) return; if (!IsPlayerAlive(attacker) || !ZR_IsClientHuman(attacker)) return; if (!IsPlayerAlive(victim) || !ZR_IsClientZombie(victim)) return; float fVictimLoc[3]; float fAttackerLoc[3]; GetClientAbsOrigin(victim, fVictimLoc); GetClientAbsOrigin(attacker, fAttackerLoc); float fPushVector[3]; MakeVectorFromPoints(fAttackerLoc, fVictimLoc, fPushVector); NormalizeVector(fPushVector, fPushVector); ScaleVector(fPushVector, g_hCVar_PushStrength.FloatValue); float fVelocity[3]; GetEntDataVector(victim, g_iToolsVelocity, fVelocity); AddVectors(fPushVector, fVelocity, fVelocity); SetEntDataVector(victim, g_iToolsVelocity, fVelocity); } /* //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public Action OnHEDetonate(Event hEvent, const char[] sEvent, bool bDontBroadcast) { if (!GetConVarBool(g_hCVar_PushNadesEnabled)) return Plugin_Continue; float fNadeOrigin[3]; fNadeOrigin[0] = hEvent.GetFloat("x"); fNadeOrigin[1] = hEvent.GetFloat("y"); fNadeOrigin[2] = hEvent.GetFloat("z"); int iOwner = GetClientOfUserId(hEvent.GetInt("userid")); if (!IsValidClient(iOwner, false)) return Plugin_Continue; if (!IsPlayerAlive(iOwner) || !ZR_IsClientHuman(iOwner)) return Plugin_Continue; for (int client = 1; client <= MaxClients; client++) { if (IsValidClient(client, false)) { if (IsPlayerAlive(client) && ZR_IsClientZombie(client)) { float fZombieOrigin[3]; GetClientAbsOrigin(client, fZombieOrigin); float fDistance = GetVectorDistance(fZombieOrigin, fNadeOrigin, false); float fMaxRange = GetConVarFloat(g_hCVar_PushRange); if (fDistance <= fMaxRange) { float fOwnerOrigin[3]; GetClientAbsOrigin(iOwner, fOwnerOrigin); float fPushVector[3]; MakeVectorFromPoints(fOwnerOrigin, fZombieOrigin, fPushVector); float fCurrentVector[3]; //GetEntPropVector(iOwner, Prop_Data, "m_vecVelocity", fCurrentVector); float fPushStrength = GetConVarFloat(g_hCVar_PushStrength); float fDistanceScalingFactor = 1.0; if (GetConVarBool(g_hCVar_PushScale)) fDistanceScalingFactor = 1.0 - ((1.0/fMaxRange) * fDistance); NormalizeVector(fPushVector, fPushVector); fPushVector[0] *= fPushStrength * fDistanceScalingFactor; fPushVector[1] *= fPushStrength * fDistanceScalingFactor; fPushVector[2] *= fPushStrength * fDistanceScalingFactor; fPushVector[0] += fCurrentVector[0]; fPushVector[1] += fCurrentVector[1]; fPushVector[2] += fCurrentVector[2]; TeleportEntity(client, NULL_VECTOR, NULL_VECTOR, fPushVector); } } } } return Plugin_Continue; } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public int KnockbackFindExplodingGrenade(float fLoc[3]) { char sClassname[64]; int iMaxEntities = GetMaxEntities(); for (int i = MaxClients; i <= iMaxEntities; i++) { if (!IsValidEdict(i)) continue; GetEdictClassname(i, sClassname, sizeof(sClassname)); if (!StrEqual(sClassname, "hegrenade_projectile", false)) continue; int iTakeDamage = GetEntProp(i, Prop_Data, "m_takedamage"); if (iTakeDamage == 0) { GetEntPropVector(i, Prop_Send, "m_vecOrigin", fLoc); return i; } } return -1; } */ //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- stock int IsValidClient(int client, bool nobots = true) { if (client <= 0 || client > MaxClients || !IsClientConnected(client) || (nobots && IsFakeClient(client))) return false; return IsClientInGame(client); } //---------------------------------------------------------------------------------------------------- // Purpose: //---------------------------------------------------------------------------------------------------- public int WeaponsGetActiveWeaponIndex(int client) { return GetEntDataEnt2(client, g_iToolsActiveWeapon); }