AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Plugin/Gameplay Ideas and Requests (https://forums.alliedmods.net/forumdisplay.php?f=60)
-   -   L4d / Prevent Smokers from smoking last survivor (https://forums.alliedmods.net/showthread.php?t=317363)

finishlast 07-09-2019 09:31

L4d / Prevent Smokers from smoking last survivor
 
Hi,

I'm pretty sure I saw that one on a russian server a while ago but I wasn't able to find the plugin.
Anyway what I would like to see is a plugin that checks if all survivors -1 are at least dead, pounced, hanging on ledge or incapped and then prevent the smoker from smoking last.
Preferable make it possible to set a value for chat or hud in cfg to show a message like "You are not allowed to smoke last!" and the option to slay that smoker instantly (or disable the tongue).

*******
As it is now it should support +8 Player servers with multiple smoker.
*******

Slapping the player by SlapPlayer command didn't work 100% to break tongue but thanks to xZk I just alter the smoker position and that seems to break the tongue now.

Code:

/********************************************************************************************
* Plugin        : L4DNoSmoking
* Version        : 1.0.0
* Game                : Left 4 Dead
* Author        : Finishlast
* Parts taken from:
* [L4D, L4D2] No Death Check Until Dead
* https://forums.alliedmods.net/showthread.php?t=142432
* [L4D & L4D2] Survivor Bot Takeover v0.8
* https://forums.alliedmods.net/showthread.php?p=1192594
* And TeleportEntity suggestion by xZk
* Testers        : Myself
* Website        : www.l4d.com
* Purpose        : Prevents smoker from smoking last survivor.
********************************************************************************************/
#include <sourcemod>
#include <sdktools>

#define CVAR_FLAGS FCVAR_NOTIFY
#define CVAR_FLAGS_PLUGIN_VERSION    FCVAR_NOTIFY|FCVAR_DONTRECORD|FCVAR_SPONLY
#define PLUGIN_NAME "L4DNoSmoking"
#define PLUGIN_VERSION "1.0.0"
#define IS_VALID_CLIENT(%1) (%1 > 0 && %1 <= MaxClients)
#define IS_CONNECTED_INGAME(%1) (IsClientConnected(%1) && IsClientInGame(%1))
#define IS_SURVIVOR(%1) (GetClientTeam(%1) == 2)
#define IS_INFECTED(%1) (GetClientTeam(%1) == 3)
#define IS_VALID_INGAME(%1) (IS_VALID_CLIENT(%1) && IS_CONNECTED_INGAME(%1))
#define IS_VALID_SURVIVOR(%1) (IS_VALID_INGAME(%1) && IS_SURVIVOR(%1))
#define IS_VALID_INFECTED(%1) (IS_VALID_INGAME(%1) && IS_INFECTED(%1))
#define IS_SURVIVOR_ALIVE(%1) (IS_VALID_SURVIVOR(%1) && IsPlayerAlive(%1))
#define IS_INFECTED_ALIVE(%1) (IS_VALID_INFECTED(%1) && IsPlayerAlive(%1))
new Handle:cvar_killorslap;
new Handle:cvar_displaykillmessage;
new survivorslotscount = 0;
new l4dver;

public Plugin myinfo =
{
        name = PLUGIN_NAME,
        author = "Finishlast",
        description = "Prevents smoker from smoking last survivor.",
        version = PLUGIN_VERSION,
        url = "www.l4d.com"
}

public OnPluginStart()
{
        CreateConVar("L4DNoSmoking_version", PLUGIN_VERSION, "L4DNoSmoking_version", CVAR_FLAGS_PLUGIN_VERSION);
        cvar_killorslap = CreateConVar("killorslap", "1", "1 kill smoker or 2 slap smoker", CVAR_FLAGS);
        cvar_displaykillmessage = CreateConVar("displaykillmessage", "3", " 0 - Disabled; 1 - small HUD Hint; 2 - big HUD Hint; 3 - Chat Notification ", CVAR_FLAGS);
        AutoExecConfig(true, "L4DNoSmoking");
        HookEvent("tongue_grab", tongue_grab);
        HookEvent("player_spawn", PlayerSpawn);
        char GameName[12];
        GetGameFolderName(GameName, sizeof(GameName));
        if (StrEqual(GameName, "left4dead2", false))
        {
                l4dver = 2;
        }
        else
        {
                l4dver = 1;
        }
}

public Action:PlayerSpawn(Handle:event, const String:name[], bool:dontBroadcast)
{
        survivorslotscount = 0
        for (new i = 1; i <= MaxClients; i++)
        {
                if (IS_VALID_SURVIVOR(i))
                {
                        survivorslotscount++;
                }
        }
        return Plugin_Continue;
}

public Action:tongue_grab(Handle:event, const String:name[], bool:dontBroadcast)
{
        new displaykillmessage = GetConVarInt(cvar_displaykillmessage);
        new killorslap = GetConVarInt(cvar_killorslap);
        new id = GetClientOfUserId(GetEventInt(event, "userid"));
        if (IS_INFECTED_ALIVE(id))
        {
        new survivors = 0;
        for (new i = 1; i <= MaxClients; i++)
        {
                if (IS_SURVIVOR_ALIVE(i) && GetClientHealth(i) > 0 )
                {
                        survivors++;
                }
        }
        new incappedsurvivors = 0;
        for (new i = 1; i <= MaxClients; i++)
        {
                if (IS_VALID_SURVIVOR(i))
                {
                        if (l4dver == 1)
                        {
                                if (IsClientIncapacitatedl4d1(i) == true)
                                {
                                        incappedsurvivors++;
                                }
                        }
                        else
                        {
                                if (IsClientIncapacitatedl4d2(i) == true)
                                {
                                        incappedsurvivors++;
                                }
                        }

                }
        }
        new dead = survivorslotscount - survivors;
        new lastmanstanding = survivorslotscount - incappedsurvivors - dead;
        if(lastmanstanding == 0)
        {
                        new String:PlayerName[200];
                        GetClientName(id, PlayerName, sizeof(PlayerName));
                        switch (killorslap)
                        {
                                case 1:
                                PerformKill(id, displaykillmessage,PlayerName);

                                case 2:
                                PerformSlap(id, displaykillmessage,PlayerName);                               
                        }       
        }
        }
        return Plugin_Continue;
}

stock bool:IsClientIncapacitatedl4d1(client)
{
        return GetEntProp(client, Prop_Send, "m_isIncapacitated") != 0 ||        // incap
        GetEntProp(client, Prop_Send, "m_isHangingFromLedge") != 0 ||                // incap ledge
        GetEntProp(client, Prop_Send, "m_isFallingFromLedge") != 0 ||                // incap fall
        GetEntProp(client, Prop_Send, "m_isHangingFromTongue") != 0 ||                // smoker ledge
        GetEntProp(client, Prop_Send, "m_tongueOwner") > 0 ||                        // smoker
        GetEntProp(client, Prop_Send, "m_pounceAttacker") > 0 ;                        // hunter
}

stock bool:IsClientIncapacitatedl4d2(client)
{
        return GetEntProp(client, Prop_Send, "m_isIncapacitated") != 0 ||        // incap
        GetEntProp(client, Prop_Send, "m_isHangingFromLedge") != 0 ||                // incap ledge
        GetEntProp(client, Prop_Send, "m_isFallingFromLedge") != 0 ||                // incap fall
        GetEntProp(client, Prop_Send, "m_isHangingFromTongue") != 0 ||                // smoker ledge
        GetEntProp(client, Prop_Send, "m_carryAttacker") > 0 ||                        // charger
        GetEntProp(client, Prop_Send, "m_pummelAttacker") > 0 ||                // charger
        GetEntProp(client, Prop_Send, "m_jockeyAttacker") > 0 ||                // jockey
        GetEntProp(client, Prop_Send, "m_tongueOwner") > 0 ||                        // smoker
        GetEntProp(client, Prop_Send, "m_pounceAttacker") > 0 ;                        // hunter
}

void PerformKill(int id, int displaykillmessage, const char[] PlayerName)
{
        ForcePlayerSuicide(id);       
        switch (displaykillmessage)
        {
        case 1:
        PrintCenterTextAll("[SM] %s was socked for smoking last.", PlayerName);

        case 2:
        PrintHintTextToAll("[SM] %s was socked for smoking last.", PlayerName);
                                       
        case 3:
        PrintToChatAll("\x01\x04[SM] \x03%s \x01was socked for smoking last.", PlayerName);
        }
}

void PerformSlap(int id, int displaykillmessage, const char[] PlayerName)
{
        new Float:vpos[3];
        new Float:vec[3];
        GetEntPropVector(id, Prop_Data, "m_vecOrigin", vpos);
        vec[0] = vpos[0]+0.0;
        vec[1] = vpos[1]+0.0;
        vec[2] = vpos[2]+30.0;
        TeleportEntity(id, vec, NULL_VECTOR, NULL_VECTOR);       
        switch (displaykillmessage)
        {
        case 1:
        PrintCenterTextAll("[SM] %s was slapped for smoking last.", PlayerName);

        case 2:
        PrintHintTextToAll("[SM] %s was slapped for smoking last.", PlayerName);
                                       
        case 3:
        PrintToChatAll("\x01\x04[SM] \x03%s \x01was slapped for smoking last.", PlayerName);
        }
}


xZk 07-14-2019 12:51

Re: L4d / Prevent Smokers from smoking last survivor
 
Apparently, the slap method does not allow the smoker to move enough to leave the survivor. So the most effective solution I think it would be to use this method if it's for l4d2:
PHP Code:

stock void L4D2_Stagger(int iClientfloat fPos[3]=NULL_VECTOR) {

    
/**
    * Stagger a client (Credit to Timocop)
    *
    * @param iClient    Client to stagger
    * @param fPos        Vector to stagger
    * @return void
    */

    
L4D2_RunScript(
        
"GetPlayerFromUserID(%d).Stagger(Vector(%d,%d,%d))",
        
GetClientUserId(iClient),
        
RoundFloat(fPos[0]),
        
RoundFloat(fPos[1]),
        
RoundFloat(fPos[2])
    );


source: https://forums.alliedmods.net/showthread.php?t=303635

finishlast 07-14-2019 13:04

Re: L4d / Prevent Smokers from smoking last survivor
 
Only for l4d2? I wrote it for l4d1.

I looked in other scripts and everyone seems to use slapplayer to break the tongue.

Like the [L4D] SmokeIT Plugin.


********
if (distance>TongueMaxStretch)
{
SlapPlayer(Smoker, 0, false);
//PrintToChatAll("\x03BREAK");
}
return Plugin_Continue;

******

In my plugin the slapplayer command actually breaks the tongue too but not reliable.
On first smoke it breaks the tongue (sometimes even on second smoke), every other time it seems to do nothing but I see the text message so it *should* do something, that's what I don't understand.

******

But thanks man, because you gave me the hint to alter the entity position, I am now able to break the tongue by literally kicking the smoker vertical pos +30 in the butt. :D

new Float:vPos[3];
new Float:vec[3];
GetEntPropVector(id, Prop_Data, "m_vecOrigin", vPos);
vec[0] = vPos[0]+0.0;
vec[1] = vPos[1]+0.0;
vec[2] = vPos[2]+30.0;
// now break tongue
TeleportEntity(id, vec, NULL_VECTOR, NULL_VECTOR);

+10 didn't work, +20 wasn't reliable, now with +30 the tongue seems to break everytime.

xZk 07-14-2019 15:08

Re: L4d / Prevent Smokers from smoking last survivor
 
then it is because SlapPlayer does not push the smoker correctly in the direction it should to break the tongue, since according to the method i understand it does so in a random direction.
you should look for some method that pushes the smoker in the direction up or with more push force.
maybe some method of this plugin can help you, sorry for not being of great help but my understanding about vectors is poor :/
https://forums.alliedmods.net/showthread.php?p=2347689

finishlast 07-14-2019 16:16

Re: L4d / Prevent Smokers from smoking last survivor
 
Nono you were indeed help.
With teleportentity up +30 it is working now.
Thank you!

Unfortunatelly I can't test it on left4dead2. I 'm running it on my l4d1 server with no issues so far.
So maybe someone with l4d2 is willing to give it a shot and test it.

Newest version here:
https://forums.alliedmods.net/showthread.php?t=317582


All times are GMT -4. The time now is 09:23.

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