AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Code Snippets/Tutorials (https://forums.alliedmods.net/forumdisplay.php?f=83)
-   -   [SNIPPET] NPC DeathMSG (https://forums.alliedmods.net/showthread.php?t=332392)

Natsheh 05-09-2021 14:25

[SNIPPET] NPC DeathMSG
 
I've found a way to make an npc fake deathmsg, i thought i'd share since i had never found something similar on the web.

PHP Code:

#include <fakemeta>

#define TASK_NPC_DEATHMSG 11030

enum any:DEATHMSG_DATA (+=1) {
    
DEATHMSG_VICTIM_ID 0,
    
DEATHMSG_KILLER_ID,
    
bool:DEATHMSG_bHEADSHOT,
    
DEATHMSG_WEAPON_NAME[24],
    
DEATHMSG_VIC_NAME[32],
    
DEATHMSG_KILLER_NAME[32]
}

public 
NPC_ENTITY_KILLED_PRE(const id, const killer, const gibs)
{
    static 
szClass[32];
    
pev(idpev_classnameszClasscharsmax(szClass));

    
set_pev(idpev_deadflagDEAD_DYING);
    
set_pev(idpev_takedamageDAMAGE_NO);
    
set_pev(idpev_solidSOLID_NOT);

    
set_pev(idPEV_TASKNPC_DEATH);

    static 
szVicName[32];
    
pev(idpev_netnameszVicNamecharsmax(szVicName));
    
pev(idPEV_WEAPON_INFLICTORszClasscharsmax(szClass));

    if(!
szVicName[0])
    {
        
copy(szVicNamecharsmax(szVicName), "Unnamed");
        
set_pev(idpev_netnameszVicName);
    }

    new 
iPlayerPointer get_user_index(szVicName);

    if( 
iPlayerPointer )
    {
        
remove_taskiPlayerPointer TASK_NPC_DEATHMSG );
    }

    static 
iNPC_DeathMSG_Data[DEATHMSG_DATA];
    
iNPC_DeathMSG_Data[DEATHMSG_VICTIM_ID] = id;
    
iNPC_DeathMSG_Data[DEATHMSG_KILLER_ID] = killer;

    
iNPC_DeathMSG_Data[DEATHMSG_KILLER_NAME][0] = EOS;

    if(
IsPlayer(killer))
    {
        
get_user_name(killeriNPC_DeathMSG_Data[DEATHMSG_KILLER_NAME], charsmax(iNPC_DeathMSG_Data[DEATHMSG_KILLER_NAME]));
    }
    else if(
killer && (pev(killerpev_flags) & FL_MONSTER))
    {
        static 
szKillerName[32];
        
pev(killerpev_netnameszKillerNamecharsmax(szKillerName));

        if(!
szKillerName[0])
        {
            
copy(szKillerNamecharsmax(szKillerName), "Unnamed");
            
set_pev(killerpev_netnameszKillerName);
        }

        
copy(iNPC_DeathMSG_Data[DEATHMSG_KILLER_NAME], charsmax(iNPC_DeathMSG_Data[DEATHMSG_KILLER_NAME]), szKillerName);

        
iPlayerPointer get_user_index(szKillerName);

        if( 
iPlayerPointer )
        {
            
remove_taskiPlayerPointer TASK_NPC_DEATHMSG );
        }
    }

    
iNPC_DeathMSG_Data[DEATHMSG_bHEADSHOT] = false;
    
copy(iNPC_DeathMSG_Data[DEATHMSG_WEAPON_NAME], charsmax(iNPC_DeathMSG_Data[DEATHMSG_WEAPON_NAME]), szClass);
    
copy(iNPC_DeathMSG_Data[DEATHMSG_VIC_NAME], charsmax(iNPC_DeathMSG_Data[DEATHMSG_VIC_NAME]), szVicName);

    static 
xFuncIDiReturnVal;
    
pev(idpev_classnameszClasscharsmax(szClass));
    
TrieGetCell(g_trie_NPC_CLASS_DEATH_CALLBACKszClassxFuncID);
    if( 
xFuncID != INVALID_HANDLE )
    {
        
ExecuteForward(xFuncIDiReturnValidkillergibs);
    }

    
Initiate_NPC_DEATHMSG(iNPC_DeathMSG_Data);

    
// Lets call think
    
set_pev(idpev_nextthinkget_gametime() + NPC_THINK_LEN);
    
call_think(id);

    return 
HAM_SUPERCEDE;
}

stock Initiate_NPC_DEATHMSG(const iNPC_DeathMSG_Data[DEATHMSG_DATA])
{
    static 
szParam[16], Array:xArray;
    
ArrayPushArray((xArray ArrayCreate(DEATHMSG_DATA1)), iNPC_DeathMSG_Data);
    
num_to_str(_:xArrayszParamcharsmax(szParam));

    static const 
Float:fInterval_len 1.0;
    static 
Float:finterval 0.0Float:fGameTime;
    
fGameTime get_gametime();

    if(
finterval >= fGameTime)
        
finterval += fInterval_len;
    else
        
finterval fGameTime fInterval_len;

    
set_task((finterval fGameTime), "task_interval_NPC_DEATHMSG"iNPC_DeathMSG_Data[DEATHMSG_VICTIM_ID] + TASK_NPC_DEATHMSGszParamsizeof szParam);
}

public 
task_interval_NPC_DEATHMSG(const param[], taskid)
{
    static Array:
xArrayiNPC_DeathMSG_Data[DEATHMSG_DATA];
    
xArray any:str_to_num(param);
    
ArrayGetArray(xArray0iNPC_DeathMSG_Data);
    
ArrayDestroy(xArray);
    
Make_NPC_DeathMsg(iNPC_DeathMSG_Data[DEATHMSG_VICTIM_ID], iNPC_DeathMSG_Data[DEATHMSG_KILLER_ID],
        
iNPC_DeathMSG_Data[DEATHMSG_VIC_NAME], iNPC_DeathMSG_Data[DEATHMSG_KILLER_NAME],
        
iNPC_DeathMSG_Data[DEATHMSG_bHEADSHOT], iNPC_DeathMSG_Data[DEATHMSG_WEAPON_NAME]);
}

stock Make_NPC_DeathMsg(idkiller, const vicName[32], const killerName[32], const bool:bHeadshot, const weapon[24])
{
    if(!
id || vicName[0] == EOS)
    {
        
log_error(AMX_ERR_NATIVE"Attempting to create an NPC DeathMSG with invalid id or vicName!");
        return;
    }

    static 
iMsg_TeamInfo 0;
    if(!
iMsg_TeamInfoiMsg_TeamInfo get_user_msgid("TeamInfo");

    
enum (+=1) {
        
VICTIM_ID 0,
        
KILLER_ID
    
}

    new 
iTargets[2];
    
iTargets[VICTIM_ID] = id;
    
iTargets[KILLER_ID] = killer;

    static 
szRejectReason[128], szName[2][32];

    
copy(szName[VICTIM_ID], charsmax(szName[]), vicName);
    
copy(szName[KILLER_ID], charsmax(szName[]), killerName);

    if(
killerName[0] == EOS)
    {
        
copy(szName[KILLER_ID], charsmax(szName[]), "World");
    }

    for(new 
iiTarget2i++)
    {
        if(
szName[i][0] == EOS) continue;

        
iTarget iTargets[i];

        if(
get_user_index(szName[i]) != iTarget)
        {
            
iTarget iTargets[i] = get_user_index(szName[i]);
        }

        if( 
iTarget )
        {
            if( 
IsPlayer(iTarget) && (is_user_connected(iTarget) || is_user_connecting(iTarget)) )
            {
                
remove_taskiTarget TASK_NPC_DEATHMSG );
                continue;
            }
        }

        if( (
KILLER_ID == && iTargets[i] == iTargets[VICTIM_ID]) )
        {
            continue;
        }

        
iTargets[i] = iTarget engfunc(EngFunc_CreateFakeClientszName[i]);

        if(!
iTarget)
            continue;

        
engfunc(EngFunc_FreeEntPrivateDataiTarget);
        if(
dllfunc(DLLFunc_ClientConnectiTarget szName[i], "127.0.0.1"szRejectReason))
        {
            
dllfunc(DLLFunc_ClientPutInServeriTarget);
            
set_pev(iTargetpev_flagspev(iTargetpev_flags) | FL_FAKECLIENT);
            
set_pev(iTargetpev_deadflagDEAD_DISCARDBODY);

            
message_begin(MSG_BROADCASTiMsg_TeamInfo, {0,0,0}, 0);
            
write_byte(iTarget);
            
write_string("TERRORIST");
            
message_end();

            
set_rendering(iTargetkRenderFxNone000kRenderTransAlpha);
        }
    }

    new 
szParam[16], Array:xArrayiNPC_DeathMSG_Data[DEATHMSG_DATA];
    
iNPC_DeathMSG_Data[DEATHMSG_VICTIM_ID] = get_user_userid(iTargets[VICTIM_ID]);
    
iNPC_DeathMSG_Data[DEATHMSG_KILLER_ID] = get_user_userid(iTargets[KILLER_ID]);
    
iNPC_DeathMSG_Data[DEATHMSG_bHEADSHOT] = _:bHeadshot;
    
copy(iNPC_DeathMSG_Data[DEATHMSG_WEAPON_NAME], charsmax(iNPC_DeathMSG_Data[DEATHMSG_WEAPON_NAME]), weapon);
    
copy(iNPC_DeathMSG_Data[DEATHMSG_KILLER_NAME], charsmax(iNPC_DeathMSG_Data[DEATHMSG_KILLER_NAME]), killerName);
    
copy(iNPC_DeathMSG_Data[DEATHMSG_VIC_NAME], charsmax(iNPC_DeathMSG_Data[DEATHMSG_VIC_NAME]), vicName);
    
ArrayPushArray((xArray ArrayCreate(DEATHMSG_DATA,1)), iNPC_DeathMSG_Data);
    
num_to_str(_:xArrayszParamcharsmax(szParam));
    
set_task(0.5"declare_npc_deathmsg"id TASK_NPC_DEATHMSGszParamsizeof szParam);
}

public 
declare_npc_deathmsg(const szParam[16], const taskid)
{
    new Array:
xArray any:str_to_num(szParam), iNPC_DeathMSG_Data[DEATHMSG_DATA];
    
ArrayGetArray(xArray0iNPC_DeathMSG_Data);

    new 
victim find_player("k"iNPC_DeathMSG_Data[DEATHMSG_VICTIM_ID]),
    
killer find_player("k"iNPC_DeathMSG_Data[DEATHMSG_KILLER_ID]);

    if( !
is_user_connected(victim) && !is_user_connecting(victim) ||
        !
is_user_connected(killer) && !is_user_connecting(killer)  )
    {
        
ArrayDestroy(xArray);

        
remove_task(victim TASK_NPC_DEATHMSG);
        
remove_task(killer TASK_NPC_DEATHMSG);

        
iNPC_DeathMSG_Data[DEATHMSG_VICTIM_ID] = victim;
        
iNPC_DeathMSG_Data[DEATHMSG_KILLER_ID] = killer;
        
Initiate_NPC_DEATHMSG(iNPC_DeathMSG_Data);
        return;
    }

    new 
szNetName[2];
    
pev(victimpev_netnameszNetName1);
    if(
szNetName[0] == EOS)
    {
        
set_task(0.1"declare_npc_deathmsg"taskidszParamsizeof szParam);
        return;
    }

    
ArrayDestroy(xArray);

    
make_deathmsg(killervictim,  iNPC_DeathMSG_Data[DEATHMSG_bHEADSHOT], iNPC_DeathMSG_Data[DEATHMSG_WEAPON_NAME]);

    if(
killer && pev(killerpev_flags) & FL_FAKECLIENT)
    {
        
remove_task(killer TASK_NPC_DEATHMSG);
        
set_task(1.0"task_kick_bot"killer TASK_NPC_DEATHMSG);
    }

    if(
victim && pev(victimpev_flags) & FL_FAKECLIENT)
    {
        
remove_task(victim TASK_NPC_DEATHMSG);
        
set_task(1.0"task_kick_bot"victim TASK_NPC_DEATHMSG);
    }
}

public 
task_kick_bot(id)
{
    
id -= TASK_NPC_DEATHMSG;

    if(
is_user_bot(id))
    {
        
server_cmd("kick #%d;"get_user_userid(id));
    }



basically what this function do is it creates a bot if an npc entity id was passed into either the killer or id ( victim ) parameters or both, and it kicks the bot/s once the fake deathmsg is sent.

NPC entity name must be set into globalname keyvalue, or you can change that if you're using one npc name for all.

Adding a delay of 1.0 second to Make_NPC_DeathMsg is recommended if you're going to call it many times per second.

Natsheh 12-11-2022 19:52

Re: [SNIPPET] NPC DeathMSG
 
Code Updated, fixed several bugs now it works better :) !


It had been tested with players with a High ping, the delay task of 0.5 seems more than enough :)


All times are GMT -4. The time now is 22:27.

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