I've created zombie NPC's with many stuff and pathfinding, yet I'm struggling and having a really hard time finding out the problem of having crash if I put in any external plugin that uses entities or entity calls. It doesn't happen instantly, but randomly at certain actions with no log but segmentation fault and I can't use for example a sandbag plugin or other extra item. I can't really find bad code in those plugins.
P.S. Here is the code one of the plugins that makes the server crash randomly:
PHP Code:
#include <amxmodx>
#include <amxmisc>
#include <fakemeta>
#include <hamsandwich>
#include <engine>
#include <xs>
#include <fun>
#include <beams>
#include <zm_core>
// The sizes of models
#define PALLET_MINS Float:{ -27.260000, -22.280001, -22.290001 }
#define PALLET_MAXS Float:{ 27.340000, 26.629999, 29.020000 }
// from fakemeta util by VEN
#define fm_find_ent_by_class(%1,%2) engfunc(EngFunc_FindEntityByString, %1, "classname", %2)
#define fm_remove_entity(%1) engfunc(EngFunc_RemoveEntity, %1)
// this is mine
#define fm_drop_to_floor(%1) engfunc(EngFunc_DropToFloor,%1)
// cvars
new remove_nrnd
new const SB_CLASSNAME[] = "FakeSandBag"
// num of pallets with bags
/* Models for pallets with bags .
Are available 2 models, will be set a random of them */
new g_models[][] =
{
"models/zombie_mutation/sandbags.mdl"
}
new g_bolsas[33];
new Sb_owner[33]
new cvar_units, g_iMaxPlayers;
new iSandBagHealth[33]
new iTeamLimit, gAlreadyBought[33];
new g_pSB[33], g_pBeam[33], iSBCanBePlaced[33]
new Float:ivecOrigin[3]
/*************************************************************
************************* AMXX PLUGIN *************************
**************************************************************/
public plugin_init()
{
/* Register the plugin */
register_plugin("[ZP] Extra: SandBags", "1.1", "LARP")
/* Register the cvars */
remove_nrnd = register_cvar("zp_pb_remround","1");
cvar_units = register_cvar("zp_sandbag_units", "42")
g_iMaxPlayers = get_maxplayers();
/* Game Events */
register_event("HLTV","event_newround", "a","1=0", "2=0"); // it's called every on new round
/* This is for menuz: */
register_clcmd("say /sb","show_the_menu");
register_clcmd("say_team /sb","show_the_menu");
register_think(SB_CLASSNAME, "SB_Think");
RegisterHam(Ham_TakeDamage,"func_wall","fw_TakeDamage");
RegisterHam(Ham_Killed, "func_wall", "fw_PlayerKilled", 1)
register_clcmd("say asd", "asd")
}
//Here is what I am tryin to make just owner and zombie to be able to destroy sandbags
public fw_TakeDamage(victim, inflictor, attacker, Float:damage, damage_type)
{
//Victim is not aa sandbag.
new sz_classname[32]
entity_get_string( victim , EV_SZ_classname , sz_classname, 31 )
if( !equali(sz_classname,"amxx_pallets") )
return HAM_IGNORED;
new Float:iHealth; pev(victim, pev_health, iHealth)
if( iHealth > 200.0 && iHealth < 400.0 ) // more than 200 glow a bit blue
{
set_rendering ( victim, kRenderFxGlowShell, 255, 0, 0, kRenderNormal, 16)
}
else if( iHealth > 400.0 && iHealth < 600.0 ) // More than 400 glow green
{
set_rendering ( victim, kRenderFxGlowShell, 255, 203, 26, kRenderNormal, 16)
}
else if( iHealth > 600.0) // More than 400 glow green
{
set_rendering ( victim, kRenderFxGlowShell, 0, 255, 0, kRenderNormal, 16)
}
//Attacker is zombie
if( attacker > 32 || zm_is_user_zombie( attacker ))
return HAM_IGNORED;
//Block Damage
return HAM_SUPERCEDE;
}
public fw_PlayerKilled(victim, attacker, shouldgib, id)
{
new sz_classname[32], Float: health
entity_get_string( victim , EV_SZ_classname , sz_classname, charsmax(sz_classname))
health = entity_get_float(victim, EV_FL_health)
if(equal(sz_classname, "amxx_pallets") && health <= 0.0 && is_valid_ent(victim) && (zm_is_npc(attacker) || zm_is_user_zombie(attacker)))
{
return HAM_IGNORED;
}
if (g_pSB[victim] && is_valid_ent(g_pSB[victim]))
remove_entity(g_pSB[victim]);
if (g_pBeam[victim] && is_valid_ent(g_pBeam[victim]))
remove_entity(g_pBeam[victim])
return HAM_IGNORED;
}
public plugin_precache()
{
for(new i;i < sizeof g_models;i++)
engfunc(EngFunc_PrecacheModel,g_models[i]);
}
public show_the_menu(id)
{
new Menu = menu_create("\ySandbags \yMenu", "menu_command")
menu_additem(Menu, "Buy/Place From Extra Items")
menu_setprop( Menu, MPROP_EXIT, MEXIT_ALL );
if(g_bolsas[id] > 0 && !zm_is_user_zombie(id))
{
menu_display(id, Menu, 0 );
CreateFakeSandBag(id)
}
}
SetBar(iId){
client_cmd(iId, "spk sound/sb.wav")
message_begin(MSG_ONE_UNRELIABLE, get_user_msgid("BarTime"), _, iId)
write_short(1);
message_end();
set_pev(iId, pev_flags, pev(iId, pev_flags) | FL_FROZEN )
set_task(1.0, "place_palletwbags", iId)
}
public ZM_Turn_Post(id){
if (g_pSB[id] && is_valid_ent(g_pSB[id]))
remove_entity(g_pSB[id]);
if (g_pBeam[id] && is_valid_ent(g_pBeam[id]))
remove_entity(g_pBeam[id])
}
public free_sb(id)
{
g_bolsas[id] = 10
}
public menu_command(id, menu, item)
{
menu_destroy(menu);
if (!g_pSB[id] || !is_valid_ent(g_pSB[id]))
return PLUGIN_HANDLED;
switch(item)
{
case 0:
{
if ( !zm_is_user_zombie(id) )
{
if(iSBCanBePlaced[id] == 2)
{
show_the_menu(id);
return PLUGIN_CONTINUE;
}
new money = g_bolsas[id]
if ( money < 1 )
{
return PLUGIN_CONTINUE
}
g_bolsas[id]-= 1
SetBar(id)
show_the_menu(id);
if(Sb_owner[id] > 0)
{
Sb_owner[id] -= 1
}
}
return PLUGIN_CONTINUE
}
case MENU_EXIT:
{
if (g_pSB[id] && is_valid_ent(g_pSB[id]))
remove_entity(g_pSB[id]);
if (g_pBeam[id] && is_valid_ent(g_pBeam[id]))
remove_entity(g_pBeam[id]);
}
}
return PLUGIN_HANDLED;
}
public CreateFakeSandBag(id)
{
if (g_pSB[id] && is_valid_ent(g_pSB[id]))
remove_entity(g_pSB[id]);
if (g_pBeam[id] && is_valid_ent(g_pBeam[id]))
remove_entity(g_pBeam[id]);
new iSB = create_entity("info_target")
if (!iSB)
return;
static Float:vecAngles[3]
GetOriginAimEndEyes(id, 128, ivecOrigin, vecAngles)
engfunc(EngFunc_SetModel, iSB,g_models[random(sizeof g_models)]);
engfunc(EngFunc_SetOrigin, iSB, ivecOrigin);
set_pev(iSB, pev_classname, SB_CLASSNAME);
set_pev(iSB, pev_owner, id);
set_pev(iSB, pev_rendermode, kRenderTransAdd);
set_pev(iSB, pev_renderamt, 200.0);
set_pev(iSB, pev_body, 1);
set_pev(iSB, pev_nextthink, get_gametime());
set_pev(iSB,pev_movetype,MOVETYPE_PUSHSTEP); // Movestep <- for Preview
new pBeam = Beam_Create("sprites/laserbeam.spr", 6.0);
if (pBeam != FM_NULLENT)
{
Beam_EntsInit(pBeam, iSB, id);
Beam_SetColor(pBeam, Float:{150.0, 0.0, 0.0});
Beam_SetScrollRate(pBeam, 255.0);
Beam_SetBrightness(pBeam, 200.0);
}
else
{
pBeam = 0;
}
g_pBeam[id] = pBeam;
g_pSB[id] = iSB;
}
public SB_Think(SandBag)
{
if (pev_valid(SandBag) != 2)
return;
static pOwner;
pOwner = pev(SandBag, pev_owner);
if (!(1 <= pOwner <= g_iMaxPlayers) || !is_user_alive(pOwner))
return;
static iBody, Float:vecColor[3], Float:vecAngles[3];
GetOriginAimEndEyes(pOwner, 128, ivecOrigin, vecAngles);
iBody = 2
xs_vec_set(vecColor, 250.0, 0.0, 0.0);
engfunc(EngFunc_SetOrigin, SandBag, ivecOrigin);
if (!IsHullVacant(ivecOrigin, HULL_HEAD, SandBag))
{
if(CheckSandBag() || CheckSandBagFake())
{
iBody = 1
xs_vec_set(vecColor, 0.0, 250.0, 0.0);
}
}
if (g_pBeam[pOwner] && is_valid_ent(g_pBeam[pOwner]))
{
Beam_RelinkBeam(g_pBeam[pOwner]);
Beam_SetColor(g_pBeam[pOwner], vecColor);
}
iSBCanBePlaced[pOwner] = iBody
set_pev(SandBag, pev_angles, vecAngles);
set_pev(SandBag, pev_body, iBody);
set_pev(SandBag, pev_nextthink, get_gametime() + 0.01);
return;
}
public place_palletwbags(id)
{
if(!is_user_alive(id) || zm_is_user_zombie(id)){
if (g_pSB[id] && is_valid_ent(g_pSB[id]))
remove_entity(g_pSB[id]);
if (g_pBeam[id] && is_valid_ent(g_pBeam[id]))
remove_entity(g_pBeam[id])
return
}
set_pev(id, pev_flags, pev(id, pev_flags) & ~FL_FROZEN )
new Ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "func_wall"));
set_pev(Ent,pev_classname,"amxx_pallets");
engfunc(EngFunc_SetModel,Ent,g_models[random(sizeof g_models)]);
static Float:p_mins[3], Float:p_maxs[3], Float:vecOrigin[3], Float:vecAngles[3];
p_mins = PALLET_MINS;
p_maxs = PALLET_MAXS;
engfunc(EngFunc_SetSize, Ent, p_mins, p_maxs);
set_pev(Ent, pev_mins, p_mins);
set_pev(Ent, pev_maxs, p_maxs );
set_pev(Ent, pev_absmin, p_mins);
set_pev(Ent, pev_absmax, p_maxs );
set_pev(Ent, pev_body, 3);
//vecOrigin[2] -= 8.0;
GetOriginAimEndEyes(id, 128, vecOrigin, vecAngles);
engfunc(EngFunc_SetOrigin, Ent, vecOrigin);
set_pev(Ent,pev_solid,SOLID_BBOX); // touch on edge, block
set_rendering ( Ent, kRenderFxGlowShell, 0, 255, 0, kRenderNormal, 16)
set_pev(Ent,pev_movetype,MOVETYPE_FLY); // no gravity, but still collides with stuff
new Float:p_cvar_health = float(iSandBagHealth[id])
set_pev(Ent,pev_health,p_cvar_health);
set_pev(Ent,pev_takedamage,DAMAGE_YES);
static Float:rvec[3];
pev(Ent,pev_v_angle,rvec);
rvec[0] = 0.0;
set_pev(Ent,pev_angles,rvec);
set_pev(Ent, pev_owner, id);
if (g_pBeam[id] && is_valid_ent(g_pBeam[id]))
remove_entity(g_pBeam[id]);
if (g_pSB[id] && is_valid_ent(g_pSB[id]))
remove_entity(g_pSB[id])
}
/* ====================================================
This is called on every round, at start up,
with HLTV logevent. So if the "pallets_wbags_nroundrem"
cvar is set to 1, all placed pallets with bugs will be
removed.
====================================================*/
public event_newround()
{
iTeamLimit = 0
for ( new id; id <= get_maxplayers(); id++)
{
if( get_pcvar_num ( remove_nrnd ) == 1)
remove_allpalletswbags();
g_bolsas[id] = 0
Sb_owner[id] = 0
gAlreadyBought[id] = 0
if (g_pBeam[id] && is_valid_ent(g_pBeam[id]))
remove_entity(g_pBeam[id])
if (g_pSB[id] && is_valid_ent(g_pSB[id]))
remove_entity(g_pSB[id]);
}
}
/* ====================================================
This is a stock to help for remove all pallets with
bags placed . Is called on new round if the cvar
"pallets_wbags_nroundrem" is set 1.
====================================================*/
stock remove_allpalletswbags()
{
new pallets = -1;
while((pallets = fm_find_ent_by_class(pallets, "amxx_pallets")))
fm_remove_entity(pallets);
}
public asd(id)
{
g_bolsas[id]+= 2
gAlreadyBought[id] = 1
iTeamLimit++
set_task(0.3,"show_the_menu",id)
Sb_owner[id] = 2
iSandBagHealth[id] = 750
}
public client_disconnected(id)
{
if (g_pSB[id] && is_valid_ent(g_pSB[id]))
remove_entity(g_pSB[id]);
if (g_pBeam[id] && is_valid_ent(g_pBeam[id]))
remove_entity(g_pBeam[id]);
}
bool:IsHullVacant(const Float:vecSrc[3], iHull, pEntToSkip = 0)
{
engfunc(EngFunc_TraceHull, vecSrc, vecSrc, DONT_IGNORE_MONSTERS, iHull, pEntToSkip, 0);
return bool:(!get_tr2(0, TR_AllSolid) && !get_tr2(0, TR_StartSolid) && get_tr2(0, TR_InOpen));
}
GetOriginAimEndEyes(this, iDistance, Float:vecOut[3], Float:vecAngles[3])
{
static Float:vecSrc[3], Float:vecEnd[3], Float:vecViewOfs[3], Float:vecVelocity[3];
static Float:flFraction;
pev(this, pev_origin, vecSrc);
pev(this, pev_view_ofs, vecViewOfs);
xs_vec_add(vecSrc, vecViewOfs, vecSrc);
velocity_by_aim(this, iDistance, vecVelocity);
xs_vec_add(vecSrc, vecVelocity, vecEnd);
engfunc(EngFunc_TraceLine, vecSrc, vecEnd, DONT_IGNORE_MONSTERS, this, 0);
get_tr2(0, TR_flFraction, flFraction);
if (flFraction < 1.0)
{
static Float:vecPlaneNormal[3];
get_tr2(0, TR_PlaneNormal, vecPlaneNormal);
get_tr2(0, TR_vecEndPos, vecOut);
xs_vec_mul_scalar(vecPlaneNormal, 1.0, vecPlaneNormal);
xs_vec_add(vecOut, vecPlaneNormal, vecOut);
}
else
{
xs_vec_copy(vecEnd, vecOut);
}
vecVelocity[2] = 0.0;
vector_to_angle(vecVelocity, vecAngles);
}
public CheckSandBag()
{
static victim
victim = -1
while ( ( victim = find_ent_in_sphere(victim,ivecOrigin,get_pcvar_float(cvar_units))) != 0 )
{
if(victim > 32)
continue
new sz_classname[32]
entity_get_string( victim , EV_SZ_classname , sz_classname, 31 )
if( !equali(sz_classname,"amxx_pallets") )
{
//our dude has sandbags and wants to place them near to him
if(is_user_connected(victim) && is_user_alive(victim) && Sb_owner[victim] == 0)
return false;
}
}
return true
}
public CheckSandBagFake()
{
static victim
victim = -1
while ( ( victim = find_ent_in_sphere(victim,ivecOrigin,get_pcvar_float(cvar_units))) != 0 )
{
if(victim > 32)
continue
new sz_classname[32]
entity_get_string( victim , EV_SZ_classname , sz_classname, 31 )
if( !equali(sz_classname,"FakeSandBag") )
{
//our dude has sandbags and wants to place them near to him
if(is_user_connected(victim) && is_user_alive(victim) && Sb_owner[victim] == 0)
return false;
}
}
return true
}