←  Problemy

AMXX.pl: Support AMX Mod X i SourceMod

»

[ROZWIĄZANE] problem z find_ent_by_owner


Best Answer sebul 12.08.2013 11:36

http://amxx.pl/topic...er/#entry562308
To

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
Locked

  • +
  • -
Rivit's Photo 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

Quote

  • +
  • -
BlackPerfum's Photo 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.
Quote

  • +
  • -
K!113r's Photo K!113r 08.08.2013

Przetłumacz sobie błąd to się wiele dowiesz, a mianowicie kompilator nie wie co oznacza twoje "id", nie jest to zdefiniowane, podaj funkcje całą razem z argumentami.
Quote

  • +
  • -
BlackPerfum's Photo BlackPerfum 08.08.2013

Killer masz zupełną rację :D 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.
Quote

  • +
  • -
K!113r's Photo K!113r 08.08.2013

Zależy jakimi nazwami opisze sobie parametry, nie zawsze id to indeks gracza i nie zawsze jest on przekazywany, choć są użytkownicy którzy uważają że jak wpiszą sobie id to kompilator będzie wiedział o co i o kogo chodzi.
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 :).
Quote

  • +
  • -
BlackPerfum's Photo BlackPerfum 08.08.2013


wnioskuje po tym iż przy idattacker nie wyskakuje żaden błąd

Dlatego to napisałem :D

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   :D


Edited by BlackPerfum, 08.08.2013 22:57.
Quote

  • +
  • -
Rivit's Photo 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    
}
Quote

  • +
  • -
BlackPerfum's Photo BlackPerfum 09.08.2013

Zamień id na idattacker

Spoiler
Quote

  • +
  • -
sebul's Photo sebul 09.08.2013

Zamień id na idattacker

Spoiler

A gdzie sprawdzenie, czy w ogóle znalazło te usp?
Quote

  • +
  • -
BlackPerfum's Photo 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 :D Gdyby nie miał usp to nie doszedł by do "cs_get_weapon_silen(WpnId)"


Edited by BlackPerfum, 09.08.2013 12:59.
Quote

  • +
  • -
sebul's Photo sebul 09.08.2013

To już lepiej zrobić tak
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)))
}
Quote

  • +
  • -
BlackPerfum's Photo 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)))
	}
}

sebul (09.08.2013 15:56):
Mój, czy Twój kod, To bynajmniej nie ma większego znaczenia ^ ^
Mi chodziło o sam fakt złego (a raczej niezbyt dobrego) ułożenia warunków.
Quote

  • +
  • -
Rivit's Photo Rivit 10.08.2013

dzięki chłopacy xD

 

jakos wybiore

Quote

  • +
  • -
Rivit's Photo 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    
}
Quote

  • +
  • -
Klakier's Photo 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    
}
 
Quote

  • +
  • -
d0naciak's Photo 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
}
Quote

  • +
  • -
BlackPerfum's Photo 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
}
Quote

  • +
  • -
sebul's Photo sebul 11.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
}

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.
Quote

  • +
  • -
Rivit's Photo Rivit 12.08.2013

!!!

 

Czyli które? Już się pogubiłem

Quote
Locked