Metin2 Quest Olayları: login, kill, levelup, timer ve Diğerleri
Hazırlayan: Metin2VIP Editörleri Yayın: 9 dk okuma
İçindekiler
- Olay nasıl yazılır?
- Bütün olaylar tek tabloda
- Giriş ve çıkış: login, logout, letter
- Durum olayları: enter ve leave
- NPC olayları: click, chat ve take
- Savaş olayları: kill, party_kill ve die
- Seviye ve eşya olayları: levelup, use, sig_use, pick, unmount
- Zamanlayıcılar: timer ve server_timer
- Hedef olayları: target.click, target.arrive, target.die
- Zindan olayları: in ve out
- item_informer
- Sık karşılaşılan durumlar
Metin2 quest'lerinde her when bloğu bir olaya bağlıdır ve o olay gerçekleştiğinde çalışır. login oyuncu oyuna her girdiğinde, kill bir canavar öldüğünde EXP'yi alan oyuncu için, levelup seviye değiştiğinde, timer oyuncuya kurulan zamanlayıcı dolduğunda çalışır. server_timer dışındaki bütün olaylar bir oyuncunun bağlamında koşar; npc ve item fonksiyonlarının hangi karakteri ve hangi eşyayı gösterdiği ise olaya göre değişir.
Bu yazı incelenen sunucu kaynağındaki 24 olayı tek tek anlatır. Quest dosyasının genel yapısı için quest yazma yazısına, olaylarda kullanılan fonksiyonlar için quest fonksiyonları yazısına bakabilirsin.
Olay nasıl yazılır?
Olay bloğu iki biçimde yazılır. Hedefli biçimde olayın önüne bir hedef konur: when 20016.click begin, when 101.kill begin, when 71002.use begin, when kapi.target.arrive begin. Hedef bir NPC ya da canavar vnum'u, questnpc.txt'de tanımlı bir ad, bir eşya vnum'u, bir zamanlayıcı adı ya da bir hedef işareti adı olabilir. Hedefsiz biçim (when login begin, when kill begin) belirli bir NPC'ye bağlı olmadan çalışır; derleyici bunları object/notarget klasörüne yazar.
Bloğa with ile koşul eklenir, birden çok olay or ile birleştirilir:
when 20077.click or 20078.click or 20079.click with npc.get_guild() == pc.get_guild() begin
...
end
Bir olay geldiğinde sunucu, o olaya bağlı quest'lere bakar ve her quest için oyuncunun o andaki durumunda (state) yazılmış bloğu çalıştırır. Oyuncunun hiç başlamadığı quest'lerde start durumundaki blok koşar. Aynı olayı karşılayan birden çok quest varsa hepsi sırayla çalışır.
Bütün olaylar tek tabloda
| Olay | Ne zaman çalışır | Yazım | npc / item |
|---|---|---|---|
login |
Karakter oyuna girince, her ışınlanmadan sonra da | hedefsiz | |
logout |
Bağlantı kapanırken, ışınlanma dahil | hedefsiz | |
letter |
login'den hemen sonra ve bir duruma girilince | hedefsiz | |
enter, leave |
Duruma girince, durumdan çıkınca | hedefsiz | |
levelup |
Seviye değişince (düşünce de) | hedefsiz | |
click |
NPC'ye tıklanınca, chat menüsü yoksa ya da boşsa | vnum.click |
npc = NPC |
chat |
NPC'ye tıklanınca açılan menüde seçenek olarak | vnum.chat."Metin" |
npc = NPC |
take |
Eşya NPC'nin üzerine sürüklenince | vnum.take |
npc = NPC, item = eşya |
kill |
Canavar ölünce, EXP'yi alan oyuncu için | vnum.kill ya da hedefsiz |
npc = ölen |
party_kill |
kill'den hemen sonra, grup liderinin bağlamında | vnum.party_kill ya da hedefsiz |
npc = ölen, member = öldüren |
die |
Oyuncu ölünce | hedefsiz | npc = öldüren |
use |
Quest türü (18) eşya kullanılınca | vnum.use |
item = eşya |
sig_use |
Özel eşya grubuna bağlı quest eşyası kullanılınca | grup.sig_use |
item = eşya |
pick |
Yerden eşya alınınca | vnum.pick ya da hedefsiz |
item = eşya |
button |
Ekrandaki görev simgesine (mektup) tıklanınca | hedefsiz | |
info |
Görev penceresinde quest'e tıklanınca | hedefsiz | |
timer |
Oyuncuya kurulan zamanlayıcı dolunca | ad.timer |
|
server_timer |
Sunucu zamanlayıcısı dolunca, oyuncusuz | ad.server_timer |
geçerli oyuncu yok |
target |
Hedef işaretine tıklanınca, varılınca, hedef yok olunca | ad.target.click / .arrive / .die |
|
unmount |
Oyuncu binekten inince | hedefsiz | |
in, out |
Zindanda olay bölgesine girip çıkınca | öznitelik hedefi | member = hareket eden |
item_informer |
Hesaba nesne market hediyesi gelince | hedefsiz |
Giriş ve çıkış: login, logout, letter
login, oyuncunun quest verisi yüklenip karakter oyuna geçtiğinde çalışır. Işınlanma istemciyi kapatıp yeni çekirdeğe yeniden bağladığı için her ışınlanmadan sonra da çalışır. Giriş olayı "beklemesiz" işlenir: bloğun içinde select, wait ya da input ile bekleyen betik zorla kapatılır ve syserr'e "QUEST NOT END RUNNING on Login/Logout" yazılır. Girişte oyuncuya bir şey söylenecekse yapılacak iş, mektup göndermektir.
letter olayı login'in hemen ardından ve oyuncu bir duruma her girdiğinde çalışır. Görev simgesini göstermek (send_letter), hedef işareti koymak ve görev penceresindeki sayaçları yazmak bu bloğun işidir; oyuncu simgeye tıklayınca button, görev penceresinden açınca info olayı gelir:
state run begin
when letter begin
send_letter("Beceri eğitimi")
end
when button or info begin
say_title("Beceri eğitimi")
say("Öğretmenine git ve eğitim yolunu seç.")
end
end
info yalnız oyuncunun başladığı ve o durumda info bloğu bulunan quest'lerde çalışır. button ise başlanmamış bir quest'i start durumundan da tetikleyebilir.
logout bağlantı her kapandığında çalışır, buna ışınlanma ve karakter seçim ekranına dönüş de dahildir. Ardından oyuncunun quest verisi bellekten silinir ve timer ile loop_timer ile kurulmuş zamanlayıcılar iptal olur. Bir zamanlayıcının ışınlanmadan sonra da sürmesi gerekiyorsa bitiş zamanını bayrağa yazıp login olayında yeniden kurmak gerekir.
Durum olayları: enter ve leave
Durum değişikliği betik bitince işlenir. Önce eski durumun leave, sonra yeni durumun enter, en son yeni durumun letter olayı çalışır. leave bloğu, durumdan çıkarken hedef işaretlerini silmek ya da sayacı temizlemek için kullanılır. Başka bir quest'in durumunu set_quest_state ile değiştirmek de aynı sırayı izler.
NPC olayları: click, chat ve take
Oyuncu bir NPC'ye tıkladığında sunucu önce o NPC üzerinde bu quest'e ait bir hedef işareti olup olmadığına bakar; varsa target.click çalışır. Yoksa NPC'nin chat seçenekleri varsa menü açılır, menü boş kalırsa click olayı denenir. Quest tıklamayı karşılamazsa NPC kendi işlevini (dükkân, depo gibi) yapar.
chat blokları menü seçeneği olur; örneğin Demirci için yazılan her when 20016.chat."..." bloğu onun menüsüne bir satır ekler. Oyuncunun durumuna uyan ve koşulu tutan bütün chat seçenekleri, NPC'ye bağlı bütün quest'lerden toplanıp tek bir menüde gösterilir ve sonuna "Kapat" eklenir. Seçenek metni aslında bir Lua ifadesidir; bu yüzden düz metin yerine locale.lua ya da translate.lua tablolarından bir değer de yazılabilir:
when 20016.chat."Silahımı geliştirmek istiyorum" begin
when guild_war_observer1.chat.locale.guild.war_list_button begin
take olayı oyuncu envanterindeki bir eşyayı NPC'nin üzerine sürükleyip bıraktığında çalışır. Kamp ateşine balık ve ata yem vermek gibi koda gömülü işler bu olaya gelmez. Blokta npc eşyanın verildiği NPC'yi, item sürüklenen eşyayı gösterir.
Aynı NPC'yi iki oyuncunun aynı anda kullanmasını önlemek için uzun diyaloglarda npc.lock() kullanılır.
Savaş olayları: kill, party_kill ve die
kill olayı bir canavar ölüp ödülü dağıtıldığında çalışır ve canavarın EXP'sini alan oyuncuya gelir; bu genellikle en çok hasarı veren oyuncudur. EXP vermeyen canavarlarda bu kaynakta yine en çok hasar veren oyuncu seçilir. Hem when 101.kill hem hedefsiz when kill blokları çalışır; npc fonksiyonları ölen canavarı gösterir. Ödül dağıtılmayan ölümlerde, örneğin canavarı bir muhafız öldürdüyse, kill olayı da gelmez.
Oyuncu bir oyuncuyu öldürdüğünde yalnız hedefsiz when kill çalışır ve npc ölen oyuncuyu gösterir. Canavar kill'leriyle karışmaması için bu ayrım npc.is_pc() ile yapılır:
when kill with npc.is_pc() begin
pc.setqf("pvp_skor", pc.getqf("pvp_skor") + 1)
end
party_kill olayı kill'in hemen ardından, grup liderinin bağlamında çalışır: blokta pc fonksiyonları lideri, member fonksiyonları canavarı öldüren üyeyi gösterir. Oyuncu grupsuzsa olay onun kendi bağlamında çalışır; lider başka bir çekirdekteyse olay hiç çalışmaz. Bu olay ve die, incelenen kaynağa sonradan eklenmiş seçeneklerle gelir; her sunucuda bulunmayabilir.
die olayı bir oyuncu öldüğünde, ölen oyuncunun bağlamında çalışır. Yalnız hedefsiz yazılır (when die begin); öldüren biri varsa npc onu gösterir.
Seviye ve eşya olayları: levelup, use, sig_use, pick, unmount
levelup seviye puanı her değiştiğinde çalışır. Seviye düştüğünde de (GM komutuyla ya da pc.set_level ile) tetiklenir, bu yüzden seviye eşiği kontrol eden quest'lerde koşulu with pc.get_level() >= 30 gibi açıkça yazmak gerekir.
use olayı item_proto'da türü 18 (quest eşyası) olan bir eşya kullanıldığında çalışır ve hedef olarak eşyanın vnum'u yazılır: when 71002.use begin. Blokta item fonksiyonları kullanılan eşyayı gösterir; eşyayı tüketmek quest'in işidir (item.remove() yığının tamamını siler, tek adet için pc.remove_item(vnum, 1) kullanılır). Bu kaynakta eşyada QUEST_USE ya da QUEST_USE_MULTIPLE bayrağı varsa use olayı gelmez. Eşya bir özel eşya grubuna bağlıysa use yerine grup.sig_use olayı çalışır. Kaynağa eklenen bir düzeltmeyle yeni tip binek eşyası giyildiğinde de use olayı tetiklenir.
pick olayı oyuncu yerden bir eşya aldığında çalışır; bir Bulmaca Kutusu için when 50034.pick, her eşya için hedefsiz when pick yazılabilir. unmount olayı oyuncu binekten indiğinde gelir.
Zamanlayıcılar: timer ve server_timer
timer("ad", saniye) geçerli oyuncuya tek seferlik, loop_timer("ad", saniye) tekrarlayan bir zamanlayıcı kurar; süre dolunca when ad.timer begin bloğu çalışır. Zamanlayıcı adı derleyicide bir NPC adı gibi işlenir, bu yüzden her ad kendi bloğunu ister. Aynı adla yeniden kurmak eskisini iptal eder, cleartimer("ad") siler. Oyuncu zamanlayıcıları oyuncu çıkınca ve ışınlanınca kaybolur.
server_timer("ad", saniye, argüman) ve server_loop_timer belirli bir oyuncuya bağlı olmayan sunucu zamanlayıcısı kurar; süre dolunca when ad.server_timer begin bloğu geçerli oyuncu olmadan çalışır. Blok quest'in start durumuna yazılır. Kurarken verilen argüman get_server_timer_arg() ile okunur; zindan quest'leri bununla zindanın harita numarasını taşır:
state start begin
when devil_stone4_update.server_timer begin
if d.select(get_server_timer_arg()) then
if d.count_monster() == 0 then
d.notice("Bütün canavarlar temizlendi.")
clear_server_timer("devil_stone4_update", get_server_timer_arg())
end
end
end
end
Aynı ad ve argümanla ikinci bir sunucu zamanlayıcısı kurmamak gerekir: ikincisi yine çalışır ama artık clear_server_timer ile silinemez. Bu kaynakta argümanı 0 olan sunucu zamanlayıcısı da silinemez, bu yüzden tekrarlayan zamanlayıcılara sıfırdan farklı bir argüman (örneğin harita numarası) verilir. Sunucu zamanlayıcıları sunucu yeniden başlayınca kaybolur. Zindan quest'lerindeki kullanım zindanlar yazısıyla birlikte okunabilir.
Hedef olayları: target.click, target.arrive, target.die
target.vid("ad", vid, "açıklama") bir karaktere, target.pos("ad", x, y, harita, "açıklama") bir konuma hedef işareti koyar. Hedef, quest'te şu üç olayı tetikler:
when ad.target.click begin: hedef NPC'ye tıklanınca ya da hedef oyuncuyla ticaret başlatılınca.when ad.target.arrive begin: oyuncu hedefe 5 metre yaklaşınca.when ad.target.die begin: hedef karakter yok olunca; bu olaydan sonra hedef kendiliğinden silinir.
Beceri öğretmenine yönlendiren quest bu kalıbı kullanır: letter bloğunda öğretmenin VID'i bulunur ve hedef konur, target.click bloğunda hedef silinip diyalog açılır, leave bloğunda kalan hedefler temizlenir.
Zindan olayları: in ve out
in ve out olayları yalnız zindan haritalarında, oyuncu haritanın olay özniteliği (event attribute) taşıyan bir bölgesine girip çıktığında çalışır. Hedef numarası 100000 ile özniteliğin numarasının toplamıdır. Grup varsa olay liderin bağlamında çalışır, hareket eden oyuncuya member fonksiyonlarıyla ulaşılır. İncelenen paketin quest'lerinde bu olay kullanılmıyor.
item_informer
item_informer olayı hesaba nesne market deposu üzerinden bir hediye geldiğinde, veritabanı sunucusunun bildirimiyle çalışır. Blokta pc.get_informer_type() hediyenin türünü, pc.get_informer_item() eşyanın vnum'unu döndürür; bu değerler yalnız bu olay sırasında anlamlıdır.
Sık karşılaşılan durumlar
- login'de diyalog açılmıyor. Giriş olayı beklemesizdir; mektup gönderip diyalogu
buttonveinfoolaylarına taşı. - Sayaç ışınlanınca sıfırlanıyor. Sayaç değeri bayrağa yazılmazsa ve sadece
q.set_counterile gösterilirse görev penceresi yeniden girişte boş kalır. Değeri bayrakta tut,letterbloğunda yeniden yaz. - Zamanlayıcı bloğu hiç çalışmıyor.
timerbloğu oyuncunun o andaki durumunda tanımlı olmalıdır; durum değişmişse eski durumdaki blok çalışmaz ve olay yarım saniyede bir boşuna yeniden denenir.server_timerbloğu isestartdurumunda olmalıdır. - NPC menüsünde seçenek görünmüyor. chat bloğu oyuncunun o quest'teki durumunda olmalı ve
withkoşulu tutmalıdır. Quest'i hiç başlatmamış oyuncu için yalnızstartdurumundaki seçenekler görünür. - Değişiklik oyuna yansımıyor. Quest yeniden derlenmeli ve yüklenmelidir;
/reload qyalnız yazıldığı çekirdekte işler. Komutların listesi GM komutları rehberinde.
Sık sorulan sorular
- when login her ışınlanmada çalışır mı?
- Evet. Işınlanma istemcinin bağlantısını kapatıp yeni çekirdeğe yeniden bağlar; bu yüzden her ışınlanmada önce logout, sonra login olayı çalışır ve oyuncuya kurulmuş timer'lar silinir.
- Grupla canavar öldürünce kill olayı herkese gelir mi?
- Gelmez. kill olayı canavarın EXP'sini dağıtan oyuncuya, yani genellikle en çok hasarı veren oyuncuya gelir. Grup için party_kill olayı vardır; o da grup liderinin bağlamında çalışır ve öldüren üyeye member fonksiyonlarıyla ulaşılır.
- server_timer içinde pc fonksiyonları neden çalışmıyor?
- server_timer olayı belirli bir oyuncuya bağlı değildir, geçerli oyuncu yoktur. Bu yüzden pc, npc ve item fonksiyonlarının çoğu orada kullanılamaz; zindan işleri d.select ile seçilen zindan üzerinden yapılır.
- NPC'ye tıklayınca quest yerine dükkân neden açılıyor?
- Tıklamayı karşılayan bir quest bloğu yoksa NPC kendi işlevini yerine getirir. NPC'de chat seçenekleri varsa önce chat menüsü gösterilir; menü boş kalırsa click olayı denenir, o da yoksa dükkân gibi NPC işlevi çalışır.
İlgili sayfalar
- Metin2 GM Komutları: En Çok Kullanılan Komutlar ve Yetki Seviyeleri (Server kurma)
- Metin2 Grup (Parti) Sistemi: EXP Paylaşımı ve Grup Bonusları (Wiki)
- Metin2 Quest Fonksiyonları: En Çok Kullanılan pc, npc, item ve game Fonksiyonları (Server kurma)
- Metin2 Quest Nasıl Yazılır? Lua Quest Yapısı, State ve When Blokları (Server kurma)
- Metin2 Zindanlar: Şeytan Kulesi Katları, Zindan Kopyası ve Giriş Kuralları (Wiki)
Kategori: Server Kurma Quest Geliştirme quest zindan lua olaylar timer
Bu sayfadaki bilgiler Metin2'nin sunucu yazılımındaki hesaplamalara ve standart oyun dosyalarına dayanır. Oyun dosyalarını değiştiren sunucularda değerler farklı olabilir. İçerikleri nasıl hazırlıyoruz?