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.
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ânt | Ce înseamnă |
|---|---|
| Event flag | Un 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_all | Anunț afișat tuturor jucătorilor conectați, pe toate canalele. |
| Asincron | Ceva 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:
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
endExplicat rând cu rând
| Rând | Ce î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 then | Verifică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") == 1 | Efectul evenimentului: blocul rulează doar cât timp flag-ul e 1. |
if number(1, 100) <= 5 then | number(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:
- Canalul pe care ești trimite cererea către procesul
db. dbo salvează în baza de date (tabelulquestdinplayer, la „jucătorul” cu numărul 0).dbtrimite noua valoare înapoi către toate canalele.- 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 0setează 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ă
- Cu un personaj normal: la Uriel nu apare nicio opțiune „GM:”.
- Cu GM-ul: „Starea vanatorii” arată 0. Pornește evenimentul: apare anunțul pe ecran, pe toate canalele.
- Deschide din nou dialogul: acum apare „Oprește”, nu „Pornește”.
- Omoară lupi până primești o gheară. Pentru test poți pune temporar
<= 50în loc de<= 5. - Oprește evenimentul și verifică: lupii nu mai dau gheare.
- 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_item | Schimbi fără să vrei rata de drop a serverului |
set_event_flag, apoi get_event_flag imediat | Citești valoarea veche |
| Procentul de test (50%) uitat pe serverul live | Inflaț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ă.