Skocz do zawartości

Witamy w Nieoficjalnym polskim support'cie AMX Mod X

Witamy w Nieoficjalnym polskim support'cie AMX Mod X, jak w większości społeczności internetowych musisz się zarejestrować aby móc odpowiadać lub zakładać nowe tematy, ale nie bój się to jest prosty proces w którym wymagamy minimalnych informacji.
  • Rozpoczynaj nowe tematy i odpowiedaj na inne
  • Zapisz się do tematów i for, aby otrzymywać automatyczne uaktualnienia
  • Dodawaj wydarzenia do kalendarza społecznościowego
  • Stwórz swój własny profil i zdobywaj nowych znajomych
  • Zdobywaj nowe doświadczenia

Dołączona grafika Dołączona grafika

Guest Message by DevFuse
 

Zdjęcie

[ROZWIĄZANE] Usuwanie stworzonego 'entity' po określonym czasie


Najlepsza odpowiedź sebul, 15.01.2015 23:06

Spróbuj w tej funkcji zaraz przed usunięciem entu, usunąć także taska "killBox". Przejdź do postu


  • Zamknięty Temat jest zamknięty
16 odpowiedzi w tym temacie

#1 psilocybe

    Toasty!

  • Power User

Reputacja: 252
Wszechwidzący

  • Postów:524
  • Steam:steam
  • Imię:Filip
  • Lokalizacja:PL
Offline

Napisano 15.01.2015 13:37

Nie mogę znaleźć dobrego przykładu.

 

Sprawa wygląda tak:

 

Na mapie tworzy się jakaś liczba entity 'info_target' ze zmienionym stringiem 'classname', na koniec rundy usuwam w pętli enty z tym 'classname' i wszystko jest ok.

 

Teraz chcę napisać funkcję która usunie mi mój entity np. 5 sekund po jego spawnie, myślałem że to proste będzie ale coś jest bardzo nie tak :D

 

 

Moment utworzenia entity:

new ent = create_entity("info_target")
entity_set_string(ent, EV_SZ_classname, "w_box")

No i tu dałem taska za 5 sekund, a funkcja którą uruchamiał to coś takiego:

public killBox(ent)
{
    if(is_valid_ent(ent))
    {
        remove_entity(ent);
    }
}

Funkcja usuwała wybranego enta który "uruchomił" task, ale np. w losowym momencie (ok. 1-2 minut od startu mapy) crash serwera, brak logów a w konsoli serwera tylko 'Segmentation Fault'.

 

Jeszcze raz w skrócie, tworzę enta (create_entity), nadaję mu swój classname (w_box) i nakazuje mu za 5 sekund (set_task) zniknąć z mapy (remove_entity)

 

Jak to wykonać? :D


  • +
  • -
  • 0

Dołączona grafika

Dołączona grafika


#2 MAGNET

    SourceLearned ;)

  • Moderator

Reputacja: 661
Wszechmogący

  • Postów:1 535
  • GG:
  • Imię:Olek
  • Lokalizacja:Dalekoo
Offline

Napisano 15.01.2015 15:09

A jak pobierasz id enta?

Była taka fajna funkcja od pobierania id enta przez nazwę i było to w klasie Replikant CODMOD. Piszę z tel i nie mam jak tam to podejrzeć.
  • +
  • -
  • 0

#3 DarkGL

    Nie oddam ciasteczka !

  • Administrator

Reputacja: 6 555
Godlike

  • Postów:11 981
  • GG:
  • Steam:steam
  • Imię:Rafał
  • Lokalizacja:Warszawa
Offline

Napisano 15.01.2015 15:41

Pokaż utworzenie taska i pełny kod tworzenia entity , jesteś pewny ze to przez to ;P ?
  • +
  • -
  • 0

#4 psilocybe

    Toasty!

  • Autor tematu
  • Power User

Reputacja: 252
Wszechwidzący

  • Postów:524
  • Steam:steam
  • Imię:Filip
  • Lokalizacja:PL
Offline

Napisano 15.01.2015 20:53

Dark'u na pewno przez to, sprawdziłem.

 

Co do tworzenia samego enta to ciekawego nic tam nie ma:      

        new Float:fVelocity[3], Float:fOrigin[3]
        entity_get_vector(id, EV_VEC_origin, fOrigin)
        VelocityByAim(id, 34, fVelocity)
    
        fOrigin[0] += fVelocity[0]
        fOrigin[1] += fVelocity[1]

        VelocityByAim(id, 300, fVelocity)
    
        new ent = create_entity("info_target")
        entity_set_string(ent, EV_SZ_classname, "w_box")
        entity_set_model(ent, "models/w_box3.mdl")
    
        entity_set_int(ent, EV_INT_movetype, MOVETYPE_TOSS)
        entity_set_int(ent, EV_INT_solid, SOLID_TRIGGER)
        entity_set_vector(ent, EV_VEC_origin, fOrigin)
        entity_set_vector(ent, EV_VEC_velocity, fVelocity)
        entity_set_float(ent, EV_FL_nextthink, halflife_time() + 0.01)
        
        set_task( 2.0, "killBox", ent )

Teraz w tasku killBox dałem sprawdzenie współrzędnych enta który powstał.

public killBox(ent)
{
    if(is_valid_ent(ent)){
    new vec[3];
    entity_get_vector(ent,EV_VEC_origin,Float:vec);
    
    client_print(0, print_chat, "[ORIGIN] x: %f y: %f z: %f",vec[0], vec[1], vec[2]);
    }
}

No i śmieszna sytuacja bo współrzędne mi pokazuje prawidłowe, za każdym razem inne, czyli zakładam że prawidłowo pobiera origins entity który uruchomił task.

 

Wystarczy że dodam pod client_print funkcję remove_entity(ent) i usuwa mi tego ent'a - ale serwer za chwile crashuje, losowo ale nigdy od razu.


  • +
  • -
  • 0

Dołączona grafika

Dołączona grafika


#5 wooDy.

    Pomocny

  • Użytkownik

Reputacja: 24
Życzliwy

  • Postów:71
  • Lokalizacja:Kraków
Offline

Napisano 15.01.2015 21:22

public killBox(ent)
{
    if(is_valid_ent(ent)){
         new Float:vec[3];
         entity_get_vector(ent,EV_VEC_origin,vec);
    
         client_print(0, print_chat, "[ORIGIN] x: %.2f y: %.2f z: %.2f",vec[0], vec[1], vec[2]);
         remove_entity(ent);
    }
}

Nie tak powinno być? ;)
  • +
  • -
  • 1
b_350_20_00DF04_000000_FFFFFF_00DF04.png
b_350_20_00DF04_000000_FFFFFF_00DF04.png

#6 Petpat

    Wszechwidzący

  • Użytkownik

Reputacja: 64
Pomocny

  • Postów:246
  • Imię:Łukasz
  • Lokalizacja:Rzeszów
Offline

Napisano 15.01.2015 21:37

public killBox(ent)
{
    if(is_valid_ent(ent)){
         new Float:vec[3];
         entity_get_vector(ent,EV_VEC_origin,vec);
    
         client_print(0, print_chat, "[ORIGIN] x: %.2f y: %.2f z: %.2f",vec[0], vec[1], vec[2]);
         remove_entity(ent);
    }
}
Nie tak powinno być? ;)


Czytaj ze zrozumieniem napisał wyraźnie

"Wystarczy że dodam pod client_print funkcję remove_entity(ent) i usuwa mi tego ent'a - ale serwer za chwile crashuje, losowo ale nigdy od razu."
  • +
  • -
  • 0

#7 wooDy.

    Pomocny

  • Użytkownik

Reputacja: 24
Życzliwy

  • Postów:71
  • Lokalizacja:Kraków
Offline

Napisano 15.01.2015 21:48

A tego, ze zmienna została źle utworzona nie zauwazyles, panie spostrzegawczy?
  • +
  • -
  • 0
b_350_20_00DF04_000000_FFFFFF_00DF04.png
b_350_20_00DF04_000000_FFFFFF_00DF04.png

#8 psilocybe

    Toasty!

  • Autor tematu
  • Power User

Reputacja: 252
Wszechwidzący

  • Postów:524
  • Steam:steam
  • Imię:Filip
  • Lokalizacja:PL
Offline

Napisano 15.01.2015 22:34

@wooDy, print_chat tylko do testów używam więc tu nie ma to znaczenia.

 

Wszystko zdaje się być ok, a to że crashuje sprawdzałem i lokalnie i na serwerze, po "zablokowaniu" wykonywania funkcji która usuwa enta plugin nie crashuje (kilka godzin bez żadnego erroru już działa).

 

Poza tym, usuwam enty na koniec rundy, przy 'touch' itp. nigdy nie crashuje - problem jest z tym taskiem.

 

Mi się wydaje że po prostu brakuje tu czegoś, jakiś szczegół albo nie wiem, brak warunku else?

 

Teraz dałem taką testową funkcję:

public killBox(ent)
{
    if(is_valid_ent(ent)){
    
        new vec[3];
        entity_get_vector(ent,EV_VEC_origin,Float:vec);
    
        new name[64]; //dla pewności 64
        entity_get_string(ent,EV_SZ_classname,name,63);
    
        client_print(0, print_chat, "[TEST] x: %f y: %f z: %f name: %s",vec[0], vec[1], vec[2], name);
    
        client_print(0, print_chat, "[TEST] Usuwam entity o ID: %d", ent);
    
        remove_entity(ent);
    }
    
    else{
    
        client_print(0, print_chat, "[TEST] Nie znaleziono entity o ID: %d", ent); 

    }
    
    return PLUGIN_HANDLED
}

No i pokazuje prawidłowe współrzędne, prawidłowy 'classname', prawidłowe ID enta, usuwa, ent znika - no i crash następuje tak jak pisałem losowo w ciągu około minuty, czasem dłużej, czasem przy nowej rundzie. Brak error_log, debug włączony, w konsoli 'Segmentation Fault' :D

 

Dodam, że jeżeli stworzę 10 entów w odstępach co 1 sekundę to usuwa po kolei tak jak chciałem - nie wiem co jest nie tak. Może w końcu debug wypluje jakieś logi :(

 

 

 


  • +
  • -
  • 0

Dołączona grafika

Dołączona grafika


#9 sebul

    Godlike

  • Przyjaciel

Reputacja: 2 035
Godlike

  • Postów:5 411
  • Steam:steam
  • Imię:Sebastian
  • Lokalizacja:Ostrołęka
Offline

Napisano 15.01.2015 22:38

A pokaż kod, gdzie usuwasz w innych momentach te enty.
I taka uwaga, o ile to może i działa
new vec[3];
entity_get_vector(ent,EV_VEC_origin,Float:vec);
to jednak prawidłowo powinno się pisać tak
new Float:vec[3];
entity_get_vector(ent,EV_VEC_origin,vec);
Przy tworzeniu zmiennej powinno być widać jaki to będzie "typ".
  • +
  • -
  • 1

Posiadam TBM (inaczej PTB), które działa dużo lepiej niż zwykłe PTB, nawet na modach z lvlami. Zainteresowany? Proszę bardzo


#10 psilocybe

    Toasty!

  • Autor tematu
  • Power User

Reputacja: 252
Wszechwidzący

  • Postów:524
  • Steam:steam
  • Imię:Filip
  • Lokalizacja:PL
Offline

Napisano 15.01.2015 22:59

@sebul, poprawione, mój błąd ;) Wracając do usuwania w innych momentach to najczęściej tak:

register_touch("w_box", "player", "touch_box");
public touch_box(ent, id)
{
    if(!is_valid_ent(ent) || !is_user_alive(id))
        {
        return PLUGIN_CONTINUE
        }

    if(is_user_alive(id))
        {
        client_cmd(id, "spk %s", beep);
        remove_entity(ent)
        }
    
    return PLUGIN_CONTINUE
}

Kod jest bardziej uwarunkowany ale usunąłem to co nie ma znaczenia.


  • +
  • -
  • 0

Dołączona grafika

Dołączona grafika


#11 sebul

    Godlike

  • Przyjaciel

Reputacja: 2 035
Godlike

  • Postów:5 411
  • Steam:steam
  • Imię:Sebastian
  • Lokalizacja:Ostrołęka
Offline

Napisano 15.01.2015 23:06   Najlepsza odpowiedź

Spróbuj w tej funkcji zaraz przed usunięciem entu, usunąć także taska "killBox".
  • +
  • -
  • 1

Posiadam TBM (inaczej PTB), które działa dużo lepiej niż zwykłe PTB, nawet na modach z lvlami. Zainteresowany? Proszę bardzo


#12 psilocybe

    Toasty!

  • Autor tematu
  • Power User

Reputacja: 252
Wszechwidzący

  • Postów:524
  • Steam:steam
  • Imię:Filip
  • Lokalizacja:PL
Offline

Napisano 16.01.2015 00:11

Czyli przed usunięciem enta w innych funkcjach dodaje:

if( task_exists(ent) )
            {
            remove_task(ent);
            }

Poczekałem 50 minut dla pewności, nie crashuje :)

 

Możliwe że to jest to. Raczej na pewno.

 

 

Jeszcze dla jasności pytanie, bo na koniec rundy też usuwam wszystkie enty ale wygląda to nieco inaczej, pytanie czy dobrze dodałem usuwanie task'a? Ma to sens?

 

To jest w funkcji round_end:

new wBox = find_ent_by_class(-1, "w_box"); // Wyszukuje ID enta po classname
    
    while( wBox> 0 && is_valid_ent(wBox) )
    {
    remove_entity(wBox);
    wBox= find_ent_by_class(-1, "w_box");
    
    if( task_exists(wBox) )
            {
            remove_task(wBox);
            }    
    }

"Komplikować" to się "komplikuje" ale czy poprawnie to jest napisane? :D


  • +
  • -
  • 0

Dołączona grafika

Dołączona grafika


#13 sebul

    Godlike

  • Przyjaciel

Reputacja: 2 035
Godlike

  • Postów:5 411
  • Steam:steam
  • Imię:Sebastian
  • Lokalizacja:Ostrołęka
Offline

Napisano 16.01.2015 08:28

Tak krócej
new wBox = -1 // Wyszukuje ID enta po classname

while( (wBox = find_ent_by_class(wBox, "w_box")) && is_valid_ent(wBox) )
{
	remove_entity(wBox);
	remove_task(wBox);
}
ale dobrze by było, żebyś też tego taska jakoś przerobił na bardziej unikalnego, czyli daj sobie gdzieś na górę
#define TASK_KILLENT 473825
i potem tego wszędzie do taska używasz, czyli chociażby
public killBox(ent)
{
    ent -= TASK_KILLENT;
    if(is_valid_ent(ent))
    {
        remove_entity(ent);
    }
}

  • +
  • -
  • 1

Posiadam TBM (inaczej PTB), które działa dużo lepiej niż zwykłe PTB, nawet na modach z lvlami. Zainteresowany? Proszę bardzo


#14 GwynBleidD

    Godlike

  • Przyjaciel

Reputacja: 1 869
Godlike

  • Postów:3 066
  • Steam:steam
  • Lokalizacja:Przemyśl
Offline

Napisano 16.01.2015 11:26

Tak krócej

new wBox = -1 // Wyszukuje ID enta po classname

while( (wBox = find_ent_by_class(wBox, "w_box")) && is_valid_ent(wBox) )
{
	remove_entity(wBox);
	remove_task(wBox);
}

Nope!
remove_task powinno być PRZED remove entity. remove_entity zmienia wartość wBox na -1! Przez co nie usuniemy taska, bo taki nie istnieje.

ale dobrze by było, żebyś też tego taska jakoś przerobił na bardziej unikalnego, czyli daj sobie gdzieś na górę

#define TASK_KILLENT 473825
i potem tego wszędzie do taska używasz, czyli chociażby
public killBox(ent)
{
    ent -= TASK_KILLENT;
    if(is_valid_ent(ent))
    {
        remove_entity(ent);
    }
}


Ma to sens TYLKO wtedy, gdy mamy kolizję numerów tasków w jednym pluginie. Inne pluginy, jeśli nie szukają specjalnie, tasków obcych nie widzą. A nawet jeśli to szkoda się silić na wymyślanie cyferek typu 473825, wystarczy po prostu policzyć ile ID tasków użyjemy i zachować ciągłość. Jeśli nie jesteśmy w stanie przewidzieć (np jak w tym przypadku, entów może być naprawdę sporo i mogą mieć różne ID) to taką grupę tasków warto dać na końcu. Gorzej jeśli mamy 2 takie grupy...
  • +
  • -
  • 1

NIE pomagam na PW. Nie trudź się, na zlecenia nie odpiszę... Od pomagania jest forum.
NIE zaglądam w tematy wysłane na PW. Jeśli są na forum to prędzej czy później je przeczytam. Jeśli mam co w nich odpisać, to odpiszę.
 
1988650.png?theme=dark


#15 sebul

    Godlike

  • Przyjaciel

Reputacja: 2 035
Godlike

  • Postów:5 411
  • Steam:steam
  • Imię:Sebastian
  • Lokalizacja:Ostrołęka
Offline

Napisano 16.01.2015 14:16

No tak, usunięcie entu musi być za usunięciem tasku. A co do id tasków, po temacie jak dla mnie widać, że jest to bardziej rozbudowany plugin, a w takich ja zawsze dodaję/odejmuję do id tasków jakąś wartość, wtedy to też ma sens przy szukaniu danego taska (więc wcale nie tylko do tego o czym napisałeś), ale zazwyczaj wtedy też to robię trochę inaczej, chociażby
enum (+= 200) {
	TASK_PIERWSZY = 2000,
	TASK_DRUGI,
	TASK_TRZECI // itd.
};

A nawet jeśli to szkoda się silić na wymyślanie cyferek typu 473825

A co to za wysiłek?
  • +
  • -
  • 0

Posiadam TBM (inaczej PTB), które działa dużo lepiej niż zwykłe PTB, nawet na modach z lvlami. Zainteresowany? Proszę bardzo


#16 psilocybe

    Toasty!

  • Autor tematu
  • Power User

Reputacja: 252
Wszechwidzący

  • Postów:524
  • Steam:steam
  • Imię:Filip
  • Lokalizacja:PL
Offline

Napisano 17.01.2015 10:31

Dzięki za wyjaśnienie, problem rozwiązany.

 

Crashe bez logów, gdzie w konsoli było tylko 'Segmentation fault' to prawdopodobnie efekt próby usunięcia entity o ID 0 lub mniejszego od 32. Nadal nie jestem pewny bo nie udało się uzyskać logów nawet przy wszystkich dostępnych komendach debugowania serwera i amx'a. Jednego jestem pewny - miało to związek z usuwaniem tych entity.

 

 


  • +
  • -
  • 0

Dołączona grafika

Dołączona grafika


#17 sebul

    Godlike

  • Przyjaciel

Reputacja: 2 035
Godlike

  • Postów:5 411
  • Steam:steam
  • Imię:Sebastian
  • Lokalizacja:Ostrołęka
Offline

Napisano 17.01.2015 10:35

Wiadomość wygenerowana automatycznie


Ten temat został zamknięty przez moderatora.

Powód: Pomoc udzielona

Jeśli się z tym nie zgadzasz, report.png raportuj ten post, a moderator lub administrator rozpatrzy go ponownie.


Z pozdrowieniami,
Zespół AMXX.PL
  • +
  • -
  • 0

Posiadam TBM (inaczej PTB), które działa dużo lepiej niż zwykłe PTB, nawet na modach z lvlami. Zainteresowany? Proszę bardzo





Użytkownicy przeglądający ten temat: 0

0 użytkowników, 0 gości, 0 anonimowych