Veteran Member
|

05-09-2021
, 15:25
[SNIPPET] NPC DeathMSG
|
#1
|
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(id, pev_classname, szClass, charsmax(szClass));
set_pev(id, pev_deadflag, DEAD_DYING); set_pev(id, pev_takedamage, DAMAGE_NO); set_pev(id, pev_solid, SOLID_NOT);
set_pev(id, PEV_TASK, NPC_DEATH);
static szVicName[32]; pev(id, pev_netname, szVicName, charsmax(szVicName)); pev(id, PEV_WEAPON_INFLICTOR, szClass, charsmax(szClass));
if(!szVicName[0]) { copy(szVicName, charsmax(szVicName), "Unnamed"); set_pev(id, pev_netname, szVicName); }
new iPlayerPointer = get_user_index(szVicName);
if( iPlayerPointer ) { remove_task( iPlayerPointer + 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(killer, iNPC_DeathMSG_Data[DEATHMSG_KILLER_NAME], charsmax(iNPC_DeathMSG_Data[DEATHMSG_KILLER_NAME])); } else if(killer && (pev(killer, pev_flags) & FL_MONSTER)) { static szKillerName[32]; pev(killer, pev_netname, szKillerName, charsmax(szKillerName));
if(!szKillerName[0]) { copy(szKillerName, charsmax(szKillerName), "Unnamed"); set_pev(killer, pev_netname, szKillerName); }
copy(iNPC_DeathMSG_Data[DEATHMSG_KILLER_NAME], charsmax(iNPC_DeathMSG_Data[DEATHMSG_KILLER_NAME]), szKillerName);
iPlayerPointer = get_user_index(szKillerName);
if( iPlayerPointer ) { remove_task( iPlayerPointer + 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 xFuncID, iReturnVal; pev(id, pev_classname, szClass, charsmax(szClass)); TrieGetCell(g_trie_NPC_CLASS_DEATH_CALLBACK, szClass, xFuncID); if( xFuncID != INVALID_HANDLE ) { ExecuteForward(xFuncID, iReturnVal, id, killer, gibs); }
Initiate_NPC_DEATHMSG(iNPC_DeathMSG_Data);
// Lets call think set_pev(id, pev_nextthink, get_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_DATA, 1)), iNPC_DeathMSG_Data); num_to_str(_:xArray, szParam, charsmax(szParam));
static const Float:fInterval_len = 1.0; static Float:finterval = 0.0, Float: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_DEATHMSG, szParam, sizeof szParam); }
public task_interval_NPC_DEATHMSG(const param[], taskid) { static Array:xArray, iNPC_DeathMSG_Data[DEATHMSG_DATA]; xArray = any:str_to_num(param); ArrayGetArray(xArray, 0, iNPC_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(id, killer, 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_TeamInfo) iMsg_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 i, iTarget; i < 2; i++) { 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 > 0 ) { if( IsPlayer(iTarget) && (is_user_connected(iTarget) || is_user_connecting(iTarget)) ) { remove_task( iTarget + TASK_NPC_DEATHMSG ); continue; } }
if( (KILLER_ID == i && iTargets[i] == iTargets[VICTIM_ID]) ) { continue; }
iTargets[i] = iTarget = engfunc(EngFunc_CreateFakeClient, szName[i]);
if(!iTarget) continue;
engfunc(EngFunc_FreeEntPrivateData, iTarget); if(dllfunc(DLLFunc_ClientConnect, iTarget , szName[i], "127.0.0.1", szRejectReason)) { dllfunc(DLLFunc_ClientPutInServer, iTarget); set_pev(iTarget, pev_flags, pev(iTarget, pev_flags) | FL_FAKECLIENT); set_pev(iTarget, pev_deadflag, DEAD_DISCARDBODY);
message_begin(MSG_BROADCAST, iMsg_TeamInfo, {0,0,0}, 0); write_byte(iTarget); write_string("TERRORIST"); message_end();
set_rendering(iTarget, kRenderFxNone, 0, 0, 0, kRenderTransAlpha); } }
new szParam[16], Array:xArray, iNPC_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(_:xArray, szParam, charsmax(szParam)); set_task(0.5, "declare_npc_deathmsg", id + TASK_NPC_DEATHMSG, szParam, sizeof szParam); }
public declare_npc_deathmsg(const szParam[16], const taskid) { new Array:xArray = any:str_to_num(szParam), iNPC_DeathMSG_Data[DEATHMSG_DATA]; ArrayGetArray(xArray, 0, iNPC_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(victim, pev_netname, szNetName, 1); if(szNetName[0] == EOS) { set_task(0.1, "declare_npc_deathmsg", taskid, szParam, sizeof szParam); return; }
ArrayDestroy(xArray);
make_deathmsg(killer, victim, iNPC_DeathMSG_Data[DEATHMSG_bHEADSHOT], iNPC_DeathMSG_Data[DEATHMSG_WEAPON_NAME]);
if(killer > 0 && pev(killer, pev_flags) & FL_FAKECLIENT) { remove_task(killer + TASK_NPC_DEATHMSG); set_task(1.0, "task_kick_bot", killer + TASK_NPC_DEATHMSG); }
if(victim > 0 && pev(victim, pev_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.
__________________
Last edited by Natsheh; 12-11-2022 at 20:54.
|
|