Raised This Month: $ Target: $400
 0% 

[L4D] Cloud Damage


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
Beatles
Senior Member
Join Date: Feb 2014
Old 11-08-2021 , 02:12   [L4D] Cloud Damage
Reply With Quote #1

Can someone help me with this please, I am using this plugin on my server, but for some reason it causes crashes, a kind of fps loss, I'm not sure what it really is.

PHP Code:
#pragma semicolon 1
#include <sourcemod>
#include <sdktools>

#define PLUGIN_VERSION "2.22"
#define CVAR_FLAGS FCVAR_SPONLY|FCVAR_NONE

#define DEBUG 0

static const Float:TRACE_TOLERANCE 25.0;

new 
Handle:CloudEnabled INVALID_HANDLE;
new 
Handle:CloudDuration INVALID_HANDLE;
new 
Handle:CloudRadius INVALID_HANDLE;
new 
Handle:CloudDamage INVALID_HANDLE;
new 
Handle:CloudShake INVALID_HANDLE;
new 
Handle:CloudBlocksRevive INVALID_HANDLE;
new 
Handle:SoundPath INVALID_HANDLE;
new 
Handle:CloudMeleeSlowEnabled INVALID_HANDLE;

static 
Handle:cvarGameModeActive INVALID_HANDLE;
static 
bool:isAllowedGameMode false;

new 
meleeentinfo;
new 
bool:isincloud[MAXPLAYERS+1];
new 
bool:swappedTeams[MAXPLAYERS+1];
new 
bool:MeleeDelay[MAXPLAYERS+1];
new 
propinfoghost;

public 
Plugin:myinfo 
{
    
name "l4d_cloud_damage",
    
author "AtomicStryker",
    
description "Left 4 Dead Cloud Damage",
    
version PLUGIN_VERSION,
    
url "http://forums.alliedmods.net/showthread.php?t=96665"
}

public 
OnPluginStart()
{
    
HookEvent("player_death"PlayerDeathEventHookMode_Pre);
    
AddNormalSoundHook(NormalSHook:HookSound_Callback);
    
HookEvent("player_team"PlayerTeam);
    
HookEvent("round_start"RoundStart);
    
    
CloudEnabled CreateConVar("l4d_cloud_damage_enabled""1""Enable/Disable the Cloud Damage plugin"CVAR_FLAGS);
    
CloudDamage CreateConVar("l4d_cloud_damage_damage""5.0""Amount of damage the cloud deals every 1 seconds"CVAR_FLAGS);
    
CloudDuration CreateConVar("l4d_cloud_damage_time""17.0""How long the cloud damage persists"CVAR_FLAGS);
    
CloudRadius CreateConVar("l4d_cloud_damage_radius""250""Radius of gas cloud damage"CVAR_FLAGS);
    
SoundPath CreateConVar("l4d_cloud_damage_sound""player/survivor/voice/choke_5.wav""Path to the Soundfile being played on each damaging Interval"CVAR_FLAGS);
    
CloudMeleeSlowEnabled CreateConVar("l4d_cloud_meleeslow_enabled""1""Enable/Disable the Cloud Melee Slow Effect"CVAR_FLAGS);
    
CloudShake CreateConVar("l4d_cloud_shake_enabled""1""Enable/Disable the Cloud Damage Shake"CVAR_FLAGS);
    
CloudBlocksRevive CreateConVar("l4d_cloud_blocks_revive""0""Enable/Disable the Cloud Damage Stopping Reviving"CVAR_FLAGS);
    
    
cvarGameModeActive CreateConVar("l4d2_cloud_gamemodesactive""coop,versus,teamversus,realism""Set the gamemodes for which the plugin should be activated separated by comma"CVAR_FLAGS);
    
    
HookConVarChange(FindConVar("mp_gamemode"), GameModeChanged);
    
CheckGamemode();
    
    
CreateConVar("l4d_cloud_damage_version"PLUGIN_VERSION" Version of L4D Cloud Damage on this server "FCVAR_SPONLY|FCVAR_DONTRECORD);
    
    
AutoExecConfig(true"l4d_cloud_damage");
    
    
meleeentinfo FindSendPropInfo("CTerrorPlayer""m_iShovePenalty");
    
propinfoghost FindSendPropInfo("CTerrorPlayer""m_isGhost");
    
    
decl String:gamename[128];
    
GetGameFolderName(gamenamesizeof(gamename));
    if (
StrContains(gamename"left4dead") < 0)
    {
        
SetFailState("This Plugin only supports L4D or L4D2");
    }
}

public 
GameModeChanged(Handle:convar, const String:oldValue[], const String:newValue[])
{
    
CheckGamemode();
}

public 
Action:RoundStart(Handle:event, const String:name[], bool:dontBroadcast)
{
    
CheckGamemode();
}

static 
CheckGamemode()
{
    
decl String:gamemode[PLATFORM_MAX_PATH];
    
GetConVarString(FindConVar("mp_gamemode"), gamemodesizeof(gamemode));
    
decl String:convarsetting[PLATFORM_MAX_PATH];
    
GetConVarString(cvarGameModeActiveconvarsettingsizeof(convarsetting));
    
    
isAllowedGameMode ListContainsString(convarsetting","gamemode);
}

stock bool:ListContainsString(const String:list[], const String:separator[], const String:string[])
{
    
decl String:buffer[64][15];
    
    new 
count ExplodeString(list, separatorbuffer14sizeof(buffer));
    for (new 
0counti++)
    {
        if (
StrEqual(stringbuffer[i], false))
        {
            return 
true;
        }
    }
    
    return 
false;
}

public 
Action:PlayerDeath(Handle:event, const String:name[], bool:dontBroadcast)
{
    new 
client GetClientOfUserId(GetEventInt(event"userid"));
    
    if (!
client || !isAllowedGameMode || !IsClientInGame(client) || GetClientTeam(client) !=|| IsPlayerSpawnGhost(client))
    {
        return 
Plugin_Continue;
    }
    
    
decl String:class[100];
    
GetClientModel(client, class, sizeof(class));
    
    if (
StrContains(class, "smoker"false) != -1)
    {
        if (
GetConVarBool(CloudEnabled))
        {
            
#if DEBUG
            
PrintToChatAll("Smokerdeath caught, Plugin running");
            
#endif
            
            
decl Float:g_pos[3];
            
GetClientEyePosition(clientg_pos);
            
            
CreateGasCloud(clientg_pos);
        }
    }
    return 
Plugin_Continue;
}

static 
CreateGasCloud(clientFloat:g_pos[3])
{
    
#if DEBUG
    
PrintToChatAll("Action GasCloud running");
    
#endif
    
    
new Float:targettime GetEngineTime() + GetConVarFloat(CloudDuration);
    
    new 
Handle:data CreateDataPack();
    
WritePackCell(dataclient);
    
WritePackFloat(datag_pos[0]);
    
WritePackFloat(datag_pos[1]);
    
WritePackFloat(datag_pos[2]);
    
WritePackFloat(datatargettime);
    
    
CreateTimer(1.0Point_HurtdataTIMER_REPEAT);
}

public 
Action:PlayerTeam(Handle:event, const String:name[], bool:dontBroadcast)
{
    new 
client GetClientOfUserId(GetEventInt(event"userid"));
    
swappedTeams[client] = true;
    
CreateTimer(2.0EraseGhostExploitclient);
}

public 
Action:EraseGhostExploit(Handle:timerany:client)
{    
    
swappedTeams[client] = false;
}

public 
Action:Point_Hurt(Handle:timerHandle:hurt)
{
    
ResetPack(hurt);
    new 
client ReadPackCell(hurt);
    
decl Float:g_pos[3];
    
g_pos[0] = ReadPackFloat(hurt);
    
g_pos[1] = ReadPackFloat(hurt);
    
g_pos[2] = ReadPackFloat(hurt);
    new 
Float:targettime ReadPackFloat(hurt);
    
    if (
targettime GetEngineTime() < 0)
    {
        
#if DEBUG
        
PrintToChatAll("Target Time reached Action PointHurter killing itself");
        
#endif
    
        
CloseHandle(hurt);
        return 
Plugin_Stop;
    }
    
    
#if DEBUG
    
PrintToChatAll("Action PointHurter running");
    
#endif
    
    
if (!IsClientInGame(client)) client = -1;
    
    
decl Float:targetVector[3];
    
decl Float:distance;
    new 
Float:radiussetting GetConVarFloat(CloudRadius);
    
decl String:soundFilePath[256];
    
GetConVarString(SoundPathsoundFilePathsizeof(soundFilePath));
    new 
bool:shakeenabled GetConVarBool(CloudShake);
    new 
damage GetConVarInt(CloudDamage);
    new 
bool:slowenabled GetConVarBool(CloudMeleeSlowEnabled);
    
    for (new 
target 1target <= MaxClientstarget++)
    {
        if (!
target || !IsClientInGame(target) || !IsPlayerAlive(target) || GetClientTeam(target) != 2)
        {
            continue;
        }
        
        
GetClientEyePosition(targettargetVector);
        
distance GetVectorDistance(targetVectorg_pos);
        
        if (
distance radiussetting || !IsVisibleTo(g_postargetVector)) continue;
        
        
EmitSoundToClient(targetsoundFilePath);
        
        if (
shakeenabled)
        {
            new 
Handle:hBf StartMessageOne("Shake"target);
            
BfWriteByte(hBf0);
            
BfWriteFloat(hBf,6.0);
            
BfWriteFloat(hBf,1.0);
            
BfWriteFloat(hBf,1.0);
            
EndMessage();
            
CreateTimer(1.0StopShaketarget);
        }
        
        if (
slowenabled && !IsFakeClient(target))
        {
            
isincloud[target] = true;
            
CreateTimer(2.0ClearMeleeBlocktarget);
        }
        
applyDamage(damagetargetclient);
    }
    return 
Plugin_Continue;
}

public 
Action:HookSound_Callback(Clients[64], &NumClientsString:StrSample[PLATFORM_MAX_PATH], &Entity)
{
    if (
StrContains(StrSample"Swish"false) == -1) return Plugin_Continue;
    
    if (
Entity MAXPLAYERS) return Plugin_Continue;
    
    if (
MeleeDelay[Entity]) return Plugin_Continue;
    
MeleeDelay[Entity] = true;
    
CreateTimer(1.0ResetMeleeDelayEntity);
    
    
#if DEBUG
    
PrintToChatAll("Melee detected via soundhook.");
    
#endif
    
    
if (isincloud[Entity]) SetEntData(Entitymeleeentinfo1.54);    
    
    return 
Plugin_Continue;
}

public 
Action:ResetMeleeDelay(Handle:timerany:client)
{
    
MeleeDelay[client] = false;
}

public 
Action:ClearMeleeBlock(Handle:timerHandle:target)
{
    
isincloud[target] = false;
}

public 
Action:StopShake(Handle:timerany:target)
{
    if (!
target || !IsClientInGame(target)) return;
    
    new 
Handle:hBf StartMessageOne("Shake"target);
    
BfWriteByte(hBf0);
    
BfWriteFloat(hBf0.0);
    
BfWriteFloat(hBf0.0);
    
BfWriteFloat(hBf0.0);
    
EndMessage();
}

stock bool:IsPlayerSpawnGhost(client)
{
    if (
GetEntData(clientpropinfoghost1)) return true;
    return 
false;
}

stock bool:IsPlayerIncapped(client)
{
    if (
GetEntProp(clientProp_Send"m_isIncapacitated"1)) return true;
    return 
false;
}

static 
applyDamage(damagevictimattacker)

    new 
Handle:dataPack CreateDataPack();
    
WritePackCell(dataPackdamage);  
    
WritePackCell(dataPackvictim);
    
WritePackCell(dataPackattacker);
    
    
CreateTimer(0.10timer_stock_applyDamagedataPack);
}

public 
Action:timer_stock_applyDamage(Handle:timerHandle:dataPack)
{
    
ResetPack(dataPack);
    new 
damage ReadPackCell(dataPack);  
    new 
victim ReadPackCell(dataPack);
    new 
attacker ReadPackCell(dataPack);
    
CloseHandle(dataPack);
    
    
decl Float:victimPos[3], String:strDamage[16], String:strDamageTarget[16];
    
    if (!
IsClientInGame(victim)) return;
    
GetClientEyePosition(victimvictimPos);
    
IntToString(damagestrDamagesizeof(strDamage));
    
Format(strDamageTargetsizeof(strDamageTarget), "hurtme%d"victim);
    
    new 
entPointHurt CreateEntityByName("point_hurt");
    if(!
entPointHurt) return;
    
    new 
bool:reviveblock GetConVarBool(CloudBlocksRevive);
    
    
DispatchKeyValue(victim"targetname"strDamageTarget);
    
DispatchKeyValue(entPointHurt"DamageTarget"strDamageTarget);
    
DispatchKeyValue(entPointHurt"Damage"strDamage);
    
DispatchKeyValue(entPointHurt"DamageType"reviveblock "65536" "263168");
    
DispatchSpawn(entPointHurt);
    
    
TeleportEntity(entPointHurtvictimPosNULL_VECTORNULL_VECTOR);
    
AcceptEntityInput(entPointHurt"Hurt", (attacker && attacker MaxClients && IsClientInGame(attacker)) ? attacker : -1);
    
    
DispatchKeyValue(entPointHurt"classname""point_hurt");
    
DispatchKeyValue(victim"targetname""null");
    
RemoveEdict(entPointHurt);
}

static 
bool:IsVisibleTo(Float:position[3], Float:targetposition[3])
{
    
decl Float:vAngles[3], Float:vLookAt[3];
    
    
MakeVectorFromPoints(positiontargetpositionvLookAt);
    
GetVectorAngles(vLookAtvAngles);
    
    new 
Handle:trace TR_TraceRayFilterEx(positionvAnglesMASK_SHOTRayType_Infinite_TraceFilter);
    
    new 
bool:isVisible false;
    if (
TR_DidHit(trace))
    {
        
decl Float:vStart[3];
        
TR_GetEndPosition(vStarttrace);
        
        if ((
GetVectorDistance(positionvStartfalse) + TRACE_TOLERANCE) >= GetVectorDistance(positiontargetposition))
        {
            
isVisible true;
        }
    }
    else
    {
        
LogError("Tracer Bug: Player-Zombie Trace did not hit anything, WTF");
        
isVisible true;
    }
    
CloseHandle(trace);
    
    return 
isVisible;
}

public 
bool:_TraceFilter(entitycontentsMask)
{
    if (!
entity || !IsValidEntity(entity))
    {
        return 
false;
    }
    return 
true;

I would greatly appreciate your help.
Beatles is offline
Dragokas
Veteran Member
Join Date: Nov 2017
Location: Ukraine on fire
Old 11-08-2021 , 17:36   Re: [L4D] Cloud Damage
Reply With Quote #2

Nothing specific which may cause crash, except the lot of places for optimization. Possibly, just not precached sound.

Update:
Quote:
* 2.22.1 (Dragokas)
- Converted to new SM & MM
- Some optimizations
- Security enhancements
- Fixed handles leak
- Simplified damage code (point_hurt replaced by SDKHooks_TakeDamage).
- Removed Stop shake since it's already defined with timeout
- Removed "swapped teams" timers / events since the flag is unused.
- Added sound precache.
- Added ConVar values caching.
- ConVar "l4d2_cloud_gamemodesactive" ranamed into "l4d_cloud_modes"; added ConVars "l4d_cloud_modes_off" and "l4d_cloud_modes_tog".
- ConVar "l4d_cloud_damage_sound" moved to define DAMAGE_SOUND.
- Added ConVar "l4d_cloud_damage_ingame" - Damage client only when smoker still in-game (usually ~ 5 sec after kill) (1 - Yes, 0 - while cloud lifetime)
For further speed up, you may also want to set l4d_cloud_meleeslow_enabled to 0.

I'm not sure about l4d_cloud_blocks_revive, is it work. You may need to replace DMG_ENERGYBEAM | DMG_RADIATION with something like DMG_GENERIC.

Good luck!
Attached Files
File Type: sp Get Plugin or Get Source (l4d_cloud_damage.sp - 89 views - 14.3 KB)
__________________
Expert of CMD/VBS/VB6. Malware analyst. L4D fun (Bloody Witch & FreeZone)
[My plugins] [My tools] [GitHub] [Articles] [HiJackThis+] [Donate]

Last edited by Dragokas; 11-08-2021 at 17:39.
Dragokas 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 03:50.


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