İçeriğe geç

Metin2 Quest Fonksiyonları: En Çok Kullanılan pc, npc, item ve game Fonksiyonları

Hazırlayan: Metin2VIP Editörleri Yayın: 10 dk okuma

Kısaca: Metin2 quest fonksiyonları sunucu kaynak kodunun Lua'ya açtığı modüllerde 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 önek almaz. En çok kullanılanlar pc.get_level, pc.count_item, pc.remove_item, pc.give_item2, pc.getqf ve pc.setqf, npc.get_race, item.get_vnum ve game.get_event_flag'dir.
İçindekiler
  1. Fonksiyonlar nasıl gruplanır?
  2. Geçerli oyuncu, NPC ve eşya
  3. En çok kullanılan pc fonksiyonları
    1. Oyuncu bilgisi
    2. Yang
    3. Eşya sayma, silme ve verme
    4. EXP
    5. Bayraklar
    6. Işınlanma
  4. npc fonksiyonları
  5. item fonksiyonları
  6. game fonksiyonları
  7. Temel (öneksiz) fonksiyonlar
  8. Zindan, grup ve hedef fonksiyonlarından birkaçı
  9. Koordinat birimleri
  10. Topluluk ekleri ve uyumluluk

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

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?

Bu sayfa işine yaradı mı?

Giriş yap, oy ver ya da sayfayı kaydet. Okumak için üyelik gerekmez. WhatsApp X'te paylaş
Yanlış ya da eksik bir bilgi mi gördün? Bildir
Neyin yanlış olduğunu, doğrusunun ne olduğunu ve bunu nereden bildiğini yaz. Mesajın editörlere gider; yazı, kontrol edildikten sonra düzeltilir.
Yalnız editör görür.

Tartışma

Kurallar

Henüz yorum yok. Bu konuda bir deneyimin ya da sorun varsa ilk yorumu sen yaz.

Giriş yap ya da kayıt ol, sonra yorum yaz. Metin2VIP üyeliği hiçbir oyun sunucusunun hesabı değildir.