Metin2 Quest Fonksiyonları: En Çok Kullanılan pc, npc, item ve game Fonksiyonları
Hazırlayan: Metin2VIP Editörleri Yayın: 10 dk okuma
İçindekiler
Metin2 quest fonksiyonları, sunucunun C++ kodunun Lua'ya açtığı tablolarda toplanır. pc geçerli oyuncuyla, npc tıklanan ya da öldürülen karakterle, item olaydaki eşyayla, game sunucu geneli işlerle çalışır; say, select, timer gibi temel fonksiyonlar ise önek almaz. Quest yazarken en çok kullanılanlar pc.get_level, pc.count_item, pc.remove_item, pc.give_item2, pc.getqf ile pc.setqf, npc.get_race, item.get_vnum ve game.get_event_flag'dir.
Bu yazı en sık kullanılan fonksiyonları, ne döndürdüklerini ve hangi durumlarda beklenmedik davrandıklarını anlatır. İncelenen kaynakta 29 modülde, takma adlarla birlikte 733 fonksiyon var; hepsinin parametreleri, dönüş değeri ve açıklaması quest fonksiyonları listesinde. Quest dosyasının yapısını bilmiyorsan önce quest yazma yazısını oku.
Fonksiyonlar nasıl gruplanır?
| Modül | Ne üzerinde çalışır | Örnek |
|---|---|---|
pc |
Geçerli oyuncu: seviye, Yang, eşya, bayrak, ışınlanma | pc.get_level() |
npc |
Geçerli NPC ya da canavar | npc.get_race() |
item |
Geçerli eşya | item.get_vnum() |
game |
Sunucu geneli: olay bayrakları, depo, yere eşya | game.set_event_flag("x", 1) |
| önek yok | Diyalog, zamanlayıcı, duyuru, rastgele sayı | say("..."), timer("ad", 60) |
q |
Quest'in kendisi: durum, görev penceresi | q.set_title("...") |
d |
Zindan örneği | d.new_jump_party(66, x, y) |
party, guild, marriage, horse |
Grup, lonca, evlilik, at | party.is_party() |
affect, target |
Süreli bonus, hedef işareti | target.vid("ad", vid, "...") |
Bunlara ek olarak sunucunun questlib.lua dosyası select, wait, say_title, send_letter gibi Lua ile yazılmış yardımcılar tanımlar. Bu dosya pc tablosuna özellik okuması da ekler: pc.level, pc.name, pc.job, pc.gold yazmak pc.get_level() gibi ilgili fonksiyonu çağırır.
Geçerli oyuncu, NPC ve eşya
Fonksiyonların çoğu parametre olarak oyuncu almaz, "geçerli" olanı kullanır. Geçerli oyuncu olayı tetikleyen oyuncudur. Geçerli NPC tıklanan NPC'dir; kill olayında ölen canavar, PvP'de ölen oyuncu, die olayında öldüren karakter olur. Geçerli eşya use, take ve pick olaylarındaki eşyadır. Hangi olayın neyi geçerli yaptığı quest olayları yazısında tablo halinde var.
Geçerli oyuncuyu geçici olarak değiştirmenin iki yolu vardır. pc.select(vid) başka bir oyuncuyu seçer ve eski oyuncunun VID'ini döndürür; iş bitince eskisi yeniden seçilir. q.begin_other_pc_block(pid) ile q.end_other_pc_block() arasındaki çağrılar ise kimliği verilen oyuncuya uygulanır (oyuncu aynı çekirdekte çevrimiçi değilse bağlam değişmez ve çağrılar geçerli oyuncuya gider); bu blokta say ya da select gibi bekleten çağrılar kullanılamaz:
local pids = {party.get_member_pids()}
for i = 1, table.getn(pids) do
q.begin_other_pc_block(pids[i])
pc.setqf("kule_bitti", 1)
q.end_other_pc_block()
end
server_timer olaylarında geçerli oyuncu yoktur. Bu olaylarda pc, npc ve item fonksiyonlarının çoğu çalışmaz, bazıları denetim yapmadığı için çekirdeği çökertebilir.
En çok kullanılan pc fonksiyonları
Oyuncu bilgisi
pc.get_level(), pc.get_name(), pc.get_empire() (1 Shinsoo, 2 Chunjo, 3 Jinno) ve pc.get_map_index() en sık sorulan bilgilerdir. pc.get_job() sınıfı (0 savaşçı, 1 ninja, 2 sura, 3 şaman, 4 Lycan), pc.get_race() ise cinsiyetle birlikte ırk numarasını verir; oyuncu dönüşmüşse pc.get_race() canavarın vnum'unu döndürür. pc.get_skill_group() beceri grubunu (0 henüz seçmemiş, 1 ya da 2) döndürür.
Zindanda olup olmadığını pc.in_dungeon(), GM olup olmadığını pc.is_gm() söyler. CONFIG'de test sunucusu açıkken herkes en yüksek GM seviyesinde sayıldığı için pc.is_gm() her oyuncuda true döner; canlı sunucu ayarını test ederken bunu hesaba kat.
Yang
pc.get_gold() (aynı fonksiyonun diğer adları pc.get_money, pc.getgold) oyuncunun Yang'ını döndürür. pc.change_money(miktar) ekler, negatif miktarla düşer; pc.changegold ve pc.change_gold aynı fonksiyondur. Sonuç sıfırın altına düşecekse ya da 2.000.000.000'a ulaşacaksa işlem sessizce yapılmaz ve quest'e hata dönmez, bu yüzden önce denetlemek gerekir:
if pc.get_gold() < 500000 then
say("Yeterli Yang'ın yok.")
return
end
pc.change_money(-500000)
Eşya sayma, silme ve verme
pc.count_item(vnum) envanterdeki toplam adedi bütün yığınlarıyla sayar; giyili eşyalar ve oyuncunun açık pazarındaki eşyalar sayılmaz. pc.remove_item(vnum, adet) o adedi siler; eşya yetmezse elindekinin hepsini siler ve hata vermez. İkisinin birlikte kullanılması bu yüzden alışkanlık olmalıdır:
if pc.count_item(30006) >= 10 then
pc.remove_item(30006, 10)
pc.give_item2(27001, 20)
end
pc.give_item2(vnum, adet) eşyayı hemen verir, yığınlanabilir eşyayı önce mevcut yığınlara ekler ve envanter doluysa eşyayı oyuncunun yanına düşürür; yere düşen eşyayı bir süre yalnız o oyuncu alabilir. Dönüş değeri eşyanın benzersiz kimliğidir, vnum değildir. Adet bir bayta sığdırıldığı için 255'ten büyük adet verilmemelidir. Envanterde yer olup olmadığını önceden görmek için pc.enough_inventory(vnum) ya da pc.get_empty_inventory_count() kullanılır. Örnekteki Kırmızı İksir(K) yığınlanabilir bir eşyadır; oyuncunun elinde zaten varsa önce o yığına eklenir.
pc.give_item(etiket, vnum, adet) ise etiketli ödüldür: geçerli quest'in etiketle aynı adlı bayrağı 0 değilse eşyayı vermez ve oyuncuya ödülü daha önce aldığını söyler. Eşya betik bitince verilir ve fonksiyon bayrağı kendisi yazmaz:
pc.give_item("ilk_odul", 27001, 5)
pc.setqf("ilk_odul", 1)
EXP
pc.give_exp2(miktar) EXP'yi hemen ekler ve yetiyorsa oyuncuyu bir ya da birkaç seviye atlatır. pc.give_exp(etiket, miktar) etiketli ödüldür, betik sonunda verilir ve bir sonraki seviye sınırının bir altında kesilir, yani seviye atlatmaz. pc.give_exp_perc(etiket, seviye, yüzde) EXP tablosundaki bir seviyenin gerektirdiği EXP'nin yüzdesini aynı kuralla verir.
Bayraklar
pc.getqf("ad") ve pc.setqf("ad", değer) geçerli quest'in, pc.getf("quest", "ad") ve pc.setf("quest", "ad", değer) başka bir quest'in oyuncuya ait tamsayı bayrağıdır. Hiç yazılmamış bayrak 0 okunur, 0 yazmak kaydı siler; pc.delqf de bayrağı siler. pc.getqf yalnız son argümanını okur, başka quest'in bayrağını okumak için mutlaka pc.getf kullanılmalıdır. Bekleme süreli görevlerde bitiş zamanı bayrağa yazılır:
if get_time() < pc.getqf("sonraki") then
say("Bugünlük bu kadar, yarın gel.")
return
end
pc.setqf("sonraki", get_time() + 86400)
Işınlanma
pc.warp(x, y) oyuncuyu oyun birimiyle verilen genel koordinata ışınlar; pc.get_x() ve pc.get_y() metre döndürdüğü için 100 ile çarpmak gerekir. Ticaret, pazar, depo ya da küp penceresi açıksa veya son 10 saniyede bu işlerden biri yapıldıysa ışınlanma olmaz ve nedeni oyuncuya yazılır; pc.can_warp() bunu önceden söyler. pc.warp bu denetimi geçince true döndürür; ışınlanma daha sonra başarısız olsa bile dönüş değeri değişmez.
pc.set_warp_location(harita, x, y) oyuncunun kayıt konumunu metre cinsinden ayarlar: oyuncu oyundan çıkarsa bir sonraki girişte orada başlar, pc.warp_exit() da oraya ışınlar. Zindana giren oyuncunun çıkış noktası böyle saklanır.
npc fonksiyonları
npc.get_race() geçerli NPC'nin vnum'unu döndürür; aynı bloğu birden çok NPC paylaşıyorsa ayrım bununla yapılır. npc.open_shop() NPC'nin marketini açar, npc.open_shop(numara) belirli bir marketi açar; bu konu NPC market ekleme yazısında ayrıntılı anlatılıyor.
npc.lock() NPC'yi geçerli oyuncuya kilitler: NPC başkasıyla meşgulse false döner. Uzun diyaloglarda aynı NPC'yi iki oyuncunun aynı anda kullanmasını önler, iş bitince npc.unlock() çağrılır. npc.is_pc() geçerli "NPC"nin aslında bir oyuncu olup olmadığını söyler; PvP öldürmelerinde kill olayındaki ayrım bununla yapılır. npc.purge() NPC'yi ölüm olmadan siler, npc.kill() öldürür.
Zindan patronlarını güçlendirmek için npc.set_vid_attack_mul(vid, çarpan) karakterin düz vuruş hasarını, npc.set_vid_damage_mul(vid, çarpan) aldığı hasarı çarpar; varsayılan çarpan 1'dir.
item fonksiyonları
item.get_vnum(), item.get_count() ve item.get_id() geçerli eşyanın vnum'unu, adedini ve benzersiz kimliğini döndürür. item.get_socket(0) ve item.set_socket(0, değer) soket değerini okur ve yazar; süreli eşyaların süresi böyle uzatılır. Soket numarası 0-2 arasıdır.
item.remove() eşyanın bütün yığınını siler. Kullanılınca tek adet eksilmesi gereken bir quest eşyasında yaygın kalıp şudur:
when 71002.use begin
if item.get_count() > 1 then
item.set_count0(item.get_count() - 1)
else
item.remove()
end
end
item.set_count0 topluluk eki bir fonksiyondur; bulunmayan kaynaklarda aynı iş pc.remove_item(item.get_vnum(), 1) ile yapılır. Başka bir eşyayla çalışmak için item.select(kimlik) ya da item.select_cell(hücre) o eşyayı geçerli eşya yapar.
item.set_value adına rağmen item_proto değerini değiştirmez, eşyanın bir efsun yuvasına apply türü ve değer yazar. item_proto'daki value sütunlarını okumak için item.get_value(0-5) kullanılır.
game fonksiyonları
game.get_event_flag("ad") ve game.set_event_flag("ad", değer) sunucu geneli olay bayraklarıdır. Yazılan değer veritabanı sunucusuna gider, oradan bütün kanal ve çekirdeklere dağıtılır ve quest tablosunda saklandığı için yeniden başlatmada korunur; yeni değer bu tur tamamlanınca okunur. Etkinliği açıp kapamak, bir quest'i herkes için kilitlemek gibi işler için kullanılır. mob_exp, mob_item, mob_gold gibi bazı adlar oyunun oranlarını doğrudan değiştirir; bunlar etkinlik bonusları yazısında.
game.drop_item(vnum, adet) oyuncunun yanına herkesin alabileceği, game.drop_item_with_ownership(vnum, adet, saniye) bir süre yalnız o oyuncunun alabileceği eşya düşürür. game.open_safebox() depo parola penceresini açar, game.set_safebox_level(seviye) depoyu büyütür; deponun oyuncu tarafı depo yazısında.
Temel (öneksiz) fonksiyonlar
Diyalog için say, say_title, say_reward, select, wait ve input kullanılır; setskin(NOWINDOW) pencere açmadan işlem yapmayı sağlar. syschat("metin") oyuncuya sistem iletisi, notice("metin") yalnız ona duyuru, notice_all("metin") bütün sunucuya duyuru gönderir.
timer("ad", saniye) oyuncuya, server_timer("ad", saniye, argüman) sunucuya zamanlayıcı kurar; ayrıntıları olaylar yazısında. number(a, b) iki değer arasında rastgele tamsayı, get_time() Unix zamanını döndürür. item_name(vnum) ve mob_name(vnum) adları sunucudaki protolardan okur. set_quest_state("quest", "durum") başka bir quest'in durumunu değiştirir; get_quest_state("quest") durumu sayı olarak döndürür, karşılaştırmak için quest_adi.durum biçimindeki değer kullanılır.
Zindan, grup ve hedef fonksiyonlarından birkaçı
Zindan quest'lerinin çatısı birkaç fonksiyondur: d.new_jump_party(harita, x, y) haritanın yeni bir zindan örneğini açıp grubu oraya ışınlar, d.regen_file("dosya") canavarları çıkarır, d.set_warp_at_eliminate(saniye, harita, x, y, regen) canavarlar bitince herkesi bir sonraki kata taşır. d.setf ve d.getf zindana ait, oyuncuya değil zindan örneğine bağlı bayraklardır. server_timer içinde zindana d.select(get_server_timer_arg()) ile ulaşılır. Zindanların oyuncu tarafı zindanlar yazısında.
Grup için party.is_party(), party.is_leader(), party.get_near_count() ve üyelerin kimliklerini çoklu değer olarak döndüren party.get_member_pids() en sık kullanılanlardır. target.vid("ad", vid, "açıklama") bir karaktere hedef işareti koyar, target.delete("ad") kaldırır.
d.get_kill_mob_count, d.get_kill_stone_count, d.is_use_potion ve d.revived kullanılmayan iki sayı parametresi ister; parametresiz çağrıldıklarında 0 ya da true döner. Bu tür ayrıntılar listede her fonksiyonun açıklamasında yazıyor.
Koordinat birimleri
Quest fonksiyonlarındaki en sık hata koordinat birimidir. Oyun içinde koordinatlar santimetre benzeri bir oyun birimiyle tutulur; 1 metre 100 oyun birimidir. "Yerel" koordinat haritanın köşesine göre, "genel" koordinat dünyanın başlangıcına göredir.
| Birim | Fonksiyonlar |
|---|---|
| Yerel metre | mob.spawn, mob.spawn_group, d.spawn_mob, d.spawn_group, target.pos |
| Genel metre | pc.get_x, pc.get_y, pc.set_warp_location, d.jump_all, d.warp_all, d.new_jump_all, d.new_jump_party, d.set_warp_at_eliminate |
| Genel oyun birimi (metre × 100) | pc.warp, d.new_jump, d.purge_area, building.get_land_id |
| Yerel oyun birimi | d.spawn_name_mob, pc.warp_local |
Topluluk ekleri ve uyumluluk
İncelenen kaynak, orijinal Metin2 koduna sonradan eklenmiş düzeltmeler ve özellikler içerir. Adı 0 ile biten fonksiyonların çoğu (pc.get_ip0, pc.is_busy0, item.get_attr0, npc.get_level0) ve mysql_* fonksiyonları bu eklerle gelir; ekin kapalı olduğu bir kaynakta bulunmazlar ve çağrıldıklarında quest çalışma anında hata verir. Listede bu fonksiyonların açıklamasında "Topluluk eki" notu var.
C++ tarafına yeni bir quest fonksiyonu eklendiğinde adını quest klasöründeki quest_functions dosyasına da eklemek gerekir. Fonksiyonun gerçekten var olup olmadığını derleyici her zaman denetlemez; tanımsız bir fonksiyon derlenmiş quest'te kalabilir ve ancak çalıştığı anda syserr'e LUA_ERROR olarak düşer.
Sık sorulan sorular
- pc.give_item ile pc.give_item2 arasındaki fark nedir?
- pc.give_item2 eşyayı hemen verir, envanter doluysa oyuncunun yanına düşürür ve eşyanın kimliğini döndürür. pc.give_item ise etiketli ödüldür: ilk argüman bir bayrak adıdır, bayrak 0 değilse eşyayı vermez ve eşya betik bitince verilir; bayrağı kendisi yazmadığı için ardından pc.setqf ile yazmak gerekir.
- pc.get_x neden pc.warp ile çalışmıyor?
- pc.get_x ve pc.get_y metre döndürür, pc.warp ise oyun birimi ister (metrenin 100 katı). Doğru kullanım pc.warp(x * 100, y * 100) biçimindedir.
- Sonu 0 ile biten fonksiyonlar (pc.get_ip0, item.get_attr0) neden bazı sunucularda yok?
- Bu fonksiyonlar orijinal koda sonradan eklenmiş bir topluluk ekiyle gelir. Ek açık derlenmemiş bir kaynakta bulunmazlar; çağrılırsa quest çalışma anında hata verir.
- item.remove eşyanın bir adedini mi siler?
- Hayır, eşyanın bütün yığınını siler. Yığından tek adet düşmek için pc.remove_item(vnum, 1) ya da adedi azaltan item.set_count0 kullanılır.
İlgili sayfalar
- Metin2 Depo Sistemi: Depo Boyutu, Şifre ve Nesne Market Deposu (Wiki)
- Metin2 EXP, Drop ve Yang Etkinlikleri: Krallık Bonusları Nasıl Çalışır? (Wiki)
- Metin2 NPC Marketi Nasıl Eklenir? shop ve shop_item Tabloları (Server kurma)
- Metin2 Quest Olayları: login, kill, levelup, timer ve Diğerleri (Server kurma)
- Metin2 Quest Nasıl Yazılır? Lua Quest Yapısı, State ve When Blokları (Server kurma)
Kategori: Server Kurma Quest Geliştirme quest npc lua quest fonksiyonları pc
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?