[ROZWIĄZANE] problem z find_ent_by_owner
Best Answer
sebul
12.08.2013 11:36
Ale jeszcze z małą poprawką
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_HANDLED;
}
}
return HAM_IGNORED;
}
po zmianie obrażeń, zwracamy "HAM_HANDLED", taki mniej ważny szczegół, ale jednak. Go to the full post

Rivit
08.08.2013
Witam.
Stworzyłem sobie perk ( z pomocą forum) i jak chce skompilować to wyskakuje mi to:
undefined symbol ''id'' <40>
new WpnId = find_ent_by_owner(-1, "weapon_usp", id); if(ma_perk[idattacker] && random_num(1,5)==5 && get_user_weapon(idattacker)==CSW_USP && cs_get_weapon_silen(WpnId))
W dokumentacji nie ma nic o tej funkcji. proszę o pomoc
BlackPerfum
08.08.2013
if(ma_perk[idattacker] && random_num(1,5)==5 && get_user_weapon(idattacker)==CSW_USP && get_pdata_int(idattacker, 74,4) == 1)
Tak nie szybciej??
Edited by BlackPerfum, 08.08.2013 09:26.
K!113r
08.08.2013
BlackPerfum
08.08.2013
Killer masz zupełną rację To pewnie jest Ham_TakeDamage lub inna funkcja ham`a a błąd jest tu:
new WpnId = find_ent_by_owner(-1, "weapon_usp", id);
Zamień id na idattacker i będzie działać(wnioskuje po tym iż przy idattacker nie wyskakuje żaden błąd), ale zawsze możesz użyć podręcznej pamięci bytu. Według mnie takie coś jest troszkę bardziej wydajne(raczej):
if(ma_perk[idattacker] && random_num(1,5)==5 && get_user_weapon(idattacker)==CSW_USP) { if(get_pdata_int(idattacker, 74,4)) { //Twój kod } }
Edited by BlackPerfum, 08.08.2013 21:08.
K!113r
08.08.2013
Być może twoja porada mu pomoże w co nie wątpię ale to jest strzał na ślepo, dlatego też poprosiłem o obszerniejszy kod

BlackPerfum
08.08.2013
wnioskuje po tym iż przy idattacker nie wyskakuje żaden błąd
Dlatego to napisałem
To już nie do końca jest strzał na ślepo ale 100% nie ma gdyż mógł tak nazwać jakąś zmienną ale to już jest przypadek
Edited by BlackPerfum, 08.08.2013 22:57.
Rivit
09.08.2013
Wiem że undefined symbol to niezdefiniowany symbol
Dam ''obszerniejszy kod''
public TakeDamage(this, idinflictor, idattacker, Float:damage, damagebits) { if(!is_user_connected(idattacker)) return HAM_IGNORED; if(!ma_perk[idattacker]) return HAM_IGNORED; new WpnId = find_ent_by_owner(-1, "weapon_usp", id); if(ma_perk[idattacker] && random_num(1,5)==5 && get_user_weapon(idattacker)==CSW_USP && cs_get_weapon_silen(WpnId)) { SetHamParamFloat(4, float(get_user_health(this))); return PLUGIN_HANDLED } return HAM_IGNORED }
sebul
09.08.2013
A gdzie sprawdzenie, czy w ogóle znalazło te usp?Zamień id na idattacker
Spoiler
BlackPerfum
09.08.2013
Tutaj:
if(random_num(1,5)==5 && get_user_weapon(idattacker)==CSW_USP && cs_get_weapon_silen(WpnId))
No może to nie jest sprawdzanie czy znalazło ale błędów ten warunek nie wywali Gdyby nie miał usp to nie doszedł by do "cs_get_weapon_silen(WpnId)"
Edited by BlackPerfum, 09.08.2013 12:59.
sebul
09.08.2013
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)))
}
BlackPerfum
09.08.2013
Jak już mowa o lepszym zrobieniu to tak będzie wydajniej (bynajmniej z mojego punktu widzenia):
if(get_pdata_int(idattacker, 43,5)==CSW_USP) { if(random_num(1,5)==5 && get_pdata_int(idattacker, 74,5)) { SetHamParamFloat(4, float(get_user_health(this))) } }
Rivit
10.08.2013
kurcze nie moge edytowac
dajci mi gotowca bo nie wiem jak mam to zrobic. Czy dodac ma_perk ==true czy nie. i gdzie wogóle w tym get_pdata_int (xxxx) jest usp z tłumikiem??
public TakeDamage(this, idinflictor, idattacker, Float:damage, damagebits) { if(!is_user_connected(idattacker)) return HAM_IGNORED; if(!ma_perk[idattacker]) return HAM_IGNORED; new WpnId = find_ent_by_owner(-1, "weapon_usp", idattacker) if(ma_perk[idattacker] && random_num(1,5)==5 && get_user_weapon(idattacker)==CSW_USP && cs_get_weapon_silen(WpnId)); { SetHamParamFloat(4, float(get_user_health(this))) return PLUGIN_HANDLED } return HAM_IGNORED }
Klakier
10.08.2013
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 }
d0naciak
10.08.2013
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 }
BlackPerfum
10.08.2013
O ile się nie mylę można jeszcze tak:
public TakeDamage(this, idinflictor, idattacker, Float:damage, damagebits) { if(!is_user_connected(idattacker) || !ma_perk[idattacker]) return HAM_IGNORED if((get_pdata_int(idattacker,74,4) & (1<<0)) && !random(5)) SetHamParamFloat(4, float(get_user_health(this))) return HAM_IGNORED }
sebul
11.08.2013
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ś takiegopublic 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 racjiBo 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 }
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.