Înapoi la blogToate tutorialele Metin2
Tutoriale Metin2 · Lecția 60 din 99

Un NPC care pornește un eveniment în Metin2, doar pentru GM, cu event flag-uri

2 noiembrie 2026 7 min de citit

Evenimentele țin serverul viu: un weekend cu drop dublu, o vânătoare de lupi cu premii, o seară cu boss special. Ca să nu tastezi comenzi de fiecare dată, poți face un NPC care, **doar pentru GM**, are opțiunile „Pornește evenimentul” și „Oprește evenimentul”. Jucătorii obișnuiți nu văd nimic din toate acestea. În lecția asta construim un astfel de NPC și învățăm **event flag-urile**, memoria comună a întregului server.

Pe scurt: un event flag (game.set_event_flag / game.get_event_flag) e un număr valabil pentru tot serverul. Opțiunile de GM le ascunzi cu with pc.is_gm(), anunțul îl dai cu notice_all, iar efectul evenimentului îl legi de flag cu with game.get_event_flag("...") == 1.

Cuvinte pe care le vei întâlni

CuvântCe înseamnă
Event flagUn număr salvat pentru întreg serverul, pe toate canalele. De exemplu ev_lupi = 1 înseamnă „evenimentul merge”.
pc.is_gm()Răspunde „da” dacă jucătorul care vorbește cu NPC-ul e GM de rang suficient de mare.
notice_allAnunț afișat tuturor jucătorilor conectați, pe toate canalele.
AsincronCeva care nu se întâmplă imediat, ci după un mic drum, ca o scrisoare trimisă prin poștă.

Ce face evenimentul nostru

„Vânătoarea de lupi”: cât timp evenimentul e pornit, fiecare Lup (monstrul 102) omorât are 5% șanse să-i dea jucătorului o Gheară de lup (itemul 30028). VNUM-urile sunt cele din pachetul de referință.

Ca GM, mergi la Uriel (20011) și vezi trei opțiuni: starea evenimentului, „Pornește” (doar dacă e oprit) și „Oprește” (doar dacă e pornit).

Codul complet

Fișierul eveniment_lupi.quest:

lua
quest eveniment_lupi begin
    state start begin
        when 20011.chat."GM: Starea vanatorii" with pc.is_gm() begin
            say_title("Vanatoarea de lupi")
            say(string.format("ev_lupi = %d", game.get_event_flag("ev_lupi")))
        end

        when 20011.chat."GM: Porneste vanatoarea" with pc.is_gm() and game.get_event_flag("ev_lupi") == 0 begin
            say_title("Vanatoarea de lupi")
            say("Pornesti evenimentul pe TOATE canalele?")
            local alegere = select("Da, porneste", "Nu")
            if alegere ~= 1 then
                return
            end
            if game.get_event_flag("ev_lupi") ~= 0 then
                say("Evenimentul e deja pornit.")
                return
            end
            game.set_event_flag("ev_lupi", 1)
            notice_all("Vanatoarea de lupi a inceput! Lupii pot lasa Gheare de lup.")
        end

        when 20011.chat."GM: Opreste vanatoarea" with pc.is_gm() and game.get_event_flag("ev_lupi") == 1 begin
            say_title("Vanatoarea de lupi")
            local alegere = select("Da, opreste", "Nu")
            if alegere == 1 then
                game.set_event_flag("ev_lupi", 0)
                notice_all("Vanatoarea de lupi s-a terminat. Multumim!")
            end
        end

        when 102.kill with game.get_event_flag("ev_lupi") == 1 begin
            if number(1, 100) <= 5 then
                pc.give_item2(30028, 1)
            end
        end
    end
end

Explicat rând cu rând

RândCe înseamnă
with pc.is_gm()Opțiunea apare doar pentru GM. Un jucător obișnuit vorbește cu Uriel și nu vede nimic nou.
"GM: Starea vanatorii"O opțiune de control: îți arată valoarea flag-ului. Utilă la testare.
game.get_event_flag("ev_lupi")Citește flag-ul. Dacă nu a fost setat niciodată, e 0.
with pc.is_gm() and game.get_event_flag("ev_lupi") == 0„Pornește” apare doar dacă evenimentul e oprit. Așa nu-l poți porni de două ori din greșeală.
select("Da, porneste", "Nu")Confirmare. Un eveniment pe tot serverul nu se pornește dintr-o apăsare greșită.
if game.get_event_flag("ev_lupi") ~= 0 thenVerificăm din nou după confirmare: poate alt GM l-a pornit între timp.
game.set_event_flag("ev_lupi", 1)Pornim evenimentul pentru tot serverul.
notice_all("...")Anunțul ajunge la toți jucătorii, pe toate canalele.
when 102.kill with game.get_event_flag("ev_lupi") == 1Efectul evenimentului: blocul rulează doar cât timp flag-ul e 1.
if number(1, 100) <= 5 thennumber(1, 100) alege un număr la întâmplare între 1 și 100. Dacă e 5 sau mai mic, adică în 5% din cazuri…
pc.give_item2(30028, 1)…jucătorul primește o Gheară de lup.

Aici nu verificăm locul din inventar, și e o alegere conștientă: e ca un drop normal. Dacă inventarul e plin, gheara cade lângă jucător, cum ar cădea și din monstru. Pentru recompensele importante, verificarea rămâne obligatorie; vezi recompense în inventar în siguranță.

Cine e „GM” pentru pc.is_gm()

În sursa pachetului de referință, pc.is_gm() răspunde „da” doar de la rangul HIGH_WIZARD în sus (rangurile sunt, în ordine: jucător, LOW_WIZARD, WIZARD, HIGH_WIZARD, GOD, IMPLEMENTOR). Un GM cu rang mic nu va vedea opțiunile. Dacă vrei alt prag, există și pc.get_gm_level(), care îți dă rangul ca număr. Despre ranguri și cine ce are voie vei afla în lecția despre conturile GM și permisiunile.

Nu pune niciodată o opțiune de administrare fără pc.is_gm(). Un singur with uitat și orice jucător poate porni sau opri evenimente pe tot serverul.

Event flag-urile sunt asincrone

Când scrii game.set_event_flag("ev_lupi", 1), se întâmplă asta, verificat în sursa pachetului:

  1. Canalul pe care ești trimite cererea către procesul db.
  2. db o salvează în baza de date (tabelul quest din player, la „jucătorul” cu numărul 0).
  3. db trimite noua valoare înapoi către toate canalele.
  4. Abia acum, pe fiecare canal, game.get_event_flag("ev_lupi") întoarce 1.

Pașii durează foarte puțin, dar nu zero. Deci, imediat după set_event_flag, în același bloc, get_event_flag poate încă întoarce valoarea veche. Nu scrie cod care setează flag-ul și apoi se bazează pe el în rândul următor. Și nu te baza pe flag ca „lacăt” împotriva a doi GM care apasă în aceeași secundă: verificarea de după confirmare reduce riscul, dar nu îl elimină. Hotărâți în echipă cine pornește evenimentele.

Vestea bună: pentru că flag-ul e salvat în baza de date, supraviețuiește restartului. Un eveniment pornit rămâne pornit și după ce repornești serverul. Asta e bine sau rău, în funcție de ce vrei; în lecția următoare adăugăm o oprire automată.

Nume de flag-uri pe care nu le folosești

Serverul are câteva event flag-uri cu înțeles special. În sursa verificată: mob_item, mob_exp, mob_gold, mob_dam, mob_gold_pct și variantele lor ..._buyer. Ele schimbă direct ratele de drop, EXP sau yang. Nu le folosi ca nume pentru evenimentele tale. Pune un prefix propriu, de exemplu ev_.

Comenzi de urgență pentru GM

În pachetul de referință există două comenzi utile:

  • /geteventflag îți afișează lista event flag-urilor.
  • /eventflag ev_lupi 0 setează direct flag-ul la 0, adică oprește evenimentul.

Ambele cer rang de GM (în sursa verificată, /eventflag cere HIGH_WIZARD). La tine numele sau rangurile pot diferi.

Testează

  1. Cu un personaj normal: la Uriel nu apare nicio opțiune „GM:”.
  2. Cu GM-ul: „Starea vanatorii” arată 0. Pornește evenimentul: apare anunțul pe ecran, pe toate canalele.
  3. Deschide din nou dialogul: acum apare „Oprește”, nu „Pornește”.
  4. Omoară lupi până primești o gheară. Pentru test poți pune temporar <= 50 în loc de <= 5.
  5. Oprește evenimentul și verifică: lupii nu mai dau gheare.
  6. Repornește serverul de test cu evenimentul pornit și verifică cu „Starea vanatorii” că a rămas 1.

Ce ar trebui să vezi: opțiuni doar pentru GM, anunț global, efect doar cât flag-ul e 1.

Greșeli des întâlnite

GreșealăUrmarea
Opțiunile de GM fără pc.is_gm()Orice jucător controlează evenimentele
Fără confirmare select()Evenimente pornite din greșeală
Nume de flag mob_itemSchimbi fără să vrei rata de drop a serverului
set_event_flag, apoi get_event_flag imediatCitești valoarea veche
Procentul de test (50%) uitat pe serverul liveInflație de gheare. Vezi cum eviți inflația

Întrebări frecvente

Pot porni evenimentul doar pe un canal?

Flag-ul e comun pentru toate canalele, dar condiția o poți face mai strictă, de exemplu adăugând and pc.get_channel_id() == 1 în rândul when al efectului. Testează întâi, pentru că numerotarea canalelor depinde de configurația ta.

Pot folosi alt NPC decât Uriel?

Da, orice NPC. Mulți administratori pun un NPC separat, într-un loc ferit, doar pentru echipă. Vezi cum adaugi un NPC în lecția despre NPC nou cu dialog și cum îl pui pe hartă cu regen.txt.

Evenimentul consumă mult din server?

Un when 102.kill cu o condiție simplă e foarte ușor. Problemele apar la evenimente care fac spawn de sute de monștri; acolo testează pe serverul de test cu mai mulți jucători.

Ce urmează

Acum evenimentul se oprește doar manual. În lecția următoare îl facem să se oprească singur și să anunțe cât timp a mai rămas: eveniment cu timer și anunțuri.

Toate lecțiile sunt în lista tutorialelor Metin2.

Server Metin2 gata de joc

Găzduire Metin2 în România, cu instalare de serverfiles, bază de date MySQL și protecție Anti-DDoS inclusă.

DiscordWhatsApp