public TakeDamage(this, idinflictor, idattacker, Float:damage, damagebits)
{
if(!is_user_connected(idattacker))
return HAM_IGNORED;
if(!ma_perk[idattacker])
return HAM_IGNORED;
if(get_user_weapon(idattacker) == CSW_USP)
{
new WpnId = find_ent_by_owner(-1, "weapon_usp", idattacker);
if(WpnId && cs_get_weapon_silen(WpnId) && !random(5))
SetHamParamFloat(4, float(get_user_health(this)))
}
return HAM_IGNORED
}
sebul nie ma racji Bo jak WpnId będzie równe -1 (przynajmniej w fakemecie miałem errorlogi), to wg warunku znajdzie tą broń.
Funkcja powinna wyglądać tak
public TakeDamage(this, idinflictor, idattacker, Float:damage, damagebits)
{
if(!is_user_connected(idattacker))
return HAM_IGNORED;
if(!ma_perk[idattacker])
return HAM_IGNORED;
if(get_user_weapon(idattacker) == CSW_USP)
{
new WpnId = find_ent_by_owner(-1, "weapon_usp", idattacker);
if(WpnId > 0 && cs_get_weapon_silen(WpnId) && !random(5))
SetHamParamFloat(4, float(get_user_health(this)))
}
return HAM_IGNORED
}
W tym przypadku "WpnId" nigdy nie będzie miało wartości -1, zawsze ma 0 lub id entu (czyli > 0), które znalazło. Dowód? Bardzo często używam, np. czegoś takiego
new ent = -1;
while((ent = find_ent_by_owner(ent, "weapon_usp", id))) {
// jakieś operacje na "ent"
}
i nigdy żadnych błędów związanych z takim kodem nie miałem, no chyba że akurat taki kod wrzuciłem do funkcji rozłączenia gracza z serwerem, ale wtedy błąd dotyczył samej funkcji "find_ent_by_owner" (a dokładniej, że ownera nie ma już na serwerze), a nie tego, że "ent" przyjął wartość -1. A nawet mam jeszcze lepszy dowód
static cell AMX_NATIVE_CALL find_ent_by_owner(AMX *amx, cell *params) // native find_ent_by_owner(start_from_ent, classname[], owner_index); = 3 params
{
int iEnt = params[1];
int oEnt = params[3];
// Check index to start searching at, 0 must be possible for iEnt.
CHECK_ENTITY(oEnt);
edict_t *pEnt = INDEXENT2(iEnt);
edict_t *entOwner = INDEXENT2(oEnt);
//optional fourth parameter is for jghg2 compatibility
const char* sCategory = NULL;
switch(params[4]){
case 1: sCategory = "target"; break;
case 2: sCategory = "targetname"; break;
default: sCategory = "classname";
}
// No need to check if there is a real ent where entOwner points at since we don't access it anyway.
int len;
char* classname = MF_GetAmxString(amx, params[2], 0, &len);
while (true) {
pEnt = FIND_ENTITY_BY_STRING(pEnt, sCategory, classname);
if (FNullEnt(pEnt)) // break and return 0 if bad
break;
else if (pEnt->v.owner == entOwner) // compare pointers
return ENTINDEX(pEnt);
}
// If it comes here, the while loop ended because an ent failed (FNullEnt() == true)
return 0;
}
zwracane jest 0 lub id entu, więc -1 nigdy nie będzie.