Whistle

Ruhsuz Filozof
Kurucu
Kurumsal Üye
Geliştirici
Yardımsever Üye
Mesaj
11.495
Çözümler
546
Beğeni
12.048
Puan
5.864
Quest, kelime anlamı görev, misyon demek. metin2 oyununda quest uzantısı kullanılarak çeşitli şeyler yapılmış ve bu dosyaların yazılımında kullanılan dil "lua"dır. Bu da demek oluyor ki işini bilen biri lua öğrenip istedi lua komutunu metin2 içinde kullanabilir. Çoğu kişi bu dilde Türkçe'nin kullanılamadığını sanıyor ama basit bir yöntemi var. Şimdilik Türkçe karakter kullanmadan yazın ya da diğer forumlardan nasıl yapıldığını araştırın.

Bu rehberi okumaya devam etmeden önce videolu quest derslerimizin olduğunu da belirtmek istiyorum. Yazılı rehber yerine videolu rehber arıyorsanız buradan izleyebilirsiniz;


Öncelikle kullanacağınız program notepad++ olsun çok kullanışlıdır. Hata yapma riskinizi en aza indirir. Hatta Eğer programlama dillerine girip "lua" yı seçerseniz renklendirerek yazacağından hatanızı bile çok kolay görebilirsiniz.

Öncelikle Quest uzantılı dosya yapmayı anlatayım bilmeyen arkadaşlar vardır. Öncelikle herhangi bir klasöre girip orada sol üstte bulunan düzenle'ye tıklayın sonra klasör seçeneklerine girip orada bilinen dosyalar için uzantıları gizle seçeneğindeki işareti kaldırın. Şimdi notepad++ programı ya da başka bir program ile (normal notepad bile olur) questi yazmaya başlıyorsunuz. Diyelimki questi yazdık bitirdik.
Lua (Quest):
quest xxx begin
Bu queste bu şekilde başladıysak dosyamızın adı xxx.quest olmalı. Uzantısını .quest yapıyoruz. Bu questi filezillada usr/game/share/locale/turkey/quest içerisine atıyoruz. Sonra putty i açıp login oluyoruz.
Kod:
cd /usr/game/share/locale/turkey/quest
yazıyoruz.
Kod:
ee hongkong_list
yazıyoruz ve oraya bizim questimizi yazıp yani en alta xxx.quest yazıp kaydedip çıkıyoruz. daha sonra ./qc xxx.quest yazıp questimizi object dosyalarına işletiyoruz.

Şunu söyleyeyim object dosyalarının içine attığınız hiç bir dosya sağlıklı değil. Çünkü object klasörünün içindeki şeyler sizin sh make.sh çektikten sonra oraya yazılır. Yani object dosyasının içine attığınız dosyaların questi yoksa her sh make.sh çektiğinizde o dosya silinir. Yerine questte ne varsa o yazılır. Bu yüzden ne yapacaksanız quest olarak yapın.

Ders Listesi;
  1. Quest Yazma Dersleri 1. post
İlk olarak adı üstünde quest yazdığımız için şu şekilde başlamamız gerekiyor.
Lua (Quest):
quest xxx begin
ardından
Lua (Quest):
state start begin
başlanır. Şimdi bu state çok güzel bir şey. quest içinde bu state i değiştirerek farklı şeyler yapabilirsiniz. Mesela bir görevi 2. aşamaya geçirebilirsiniz. Neyse onlar ilerki konular.

quest ve state başlangıcımızı yaptıktan sonra daha iç kısımlara giriyoruz. Bundan sonra when ve function komutu kullanabiliriz. Peki bu komutlar ne işe yarar?

when komutu adı üstünde yazdığınız questin ne zaman ya da ne yapıldığı zaman işleyeceğini söyler. Örnek vermek gerekirse;
Lua (Quest):
when 20000.use begin
20000 kodlu itemi kullandığınızda quest başlayacak demektir. when komutunun çeşitli şekillerde kullanımı var ona da değineceğim ileride.

function komutu ile kendi komutunuzu yapabilirsiniz. Bu biraz daha ileri seviyelerde. İşinizi çok kolaylaştırabilecek bir komut fakat bu olmadan da bir çok şey yapılabilir. O yüzden şimdilik atlıyorum.

Şimdi işin püf noktalarından birine geldik. Kullandığınız her quest, state, when ve if komutu için bir "end" kullanmanız gerekir. Kısaca bir örnek verecek olursak;
Lua (Quest):
quest ornek begin
   state start begin
      when 2000.use begin
         say("ornek questtir.")
      end
   end
end
Buradaki şekilde [tab] tuşunu kullanarak içeri doğru piramitler oluşturarak yazarsanız hangi komut için end koyduğunuzu bilirsiniz.

Burayı da anladıysak if komutuna geçiyoruz. if kelime anlamı ingilizcede çoğunuzun bildiği gibi "eğer" demektir. Yani anlayacağınız üzere queste herhangi bir şart ekleminizi sağlar ve yine her kullandığınız if komutunu da bir "end" ile sonlandırmak zorundasınız. Örnek verecek olursak şöyle olmassa olmazlarımızla başlıyoruz. Bizim muhteşem üçlümüz quest, state ve when.
Lua (Quest):
quest ornek_quest begin
   state start begin
      when login begin
        if pc.level() == 86 then
          pc.give_item2("12019",1)
        end
      end
   end
end
Gördüğünüz üzere if'ten sonra then kullandım. then'in anlamı Türkçe'de (tam karşılamasa da) o zamandır. Yani ben üstteki questte şunu yaptım: when login diyerek kişi oyuna girdiğinde questin çalışmasını sağladım.
if pc.level() == 86 then diyerek giren kişi eğer 86. seviyedeyse adama 12019 kodlu itemi ver demek istedim. Bu quest oyuncunun her oyuna girişinde ona 1 adet 12019 kodlu itemi vermenizi sağlar. Ve önemli nokta olarak 4 tane end komutu kullandım. quest, state, when ve if komutu için.

Şimdi diğer bir komut else.

else demek öyle değilse demektir. Yukarıda yazdığım son queste dikkat ederseniz sadece 86 level için 12019 kodlu itemi verdim. Peki diğerleri nolacak? Onlar içinde else komutunu kullanabilrim ve bu else komutu if e bağlı olarak kullanılır. if ile bi şart belirlersiniz ve bu şartın dışında kalanlar için de else komutunu kullanırsınız. else komutu end gerektirmez. if için koyduğunuz end kodu else için de geçerlidir. Örnek verecek olursak:
Lua (Quest):
quest ornek_quest begin
   state start begin
      when login begin
        if pc.level() == 86 then
          pc.give_item2("12019",1)
        else
          say("86. seviyede olmadığın için herhangi bir eşya kazanamadın.")
        end
      end
   end
end
Bu questle şunu yaptık: 86. seviyedeki oyuncular login olunca 12019 verdik. Diğerleri yani 86 level olmayan oyuncular login olduklarında ise onlaraın ekranında 86. seviye olmadıkları için bir eşya kazanamadıklarını söyleyen bir uyarı çıkmasını sağladık. Dikkat edin else'den sonra then kullanmıyoruz. Bu quest de gördüğünüz gibi oyuncu her oyuna giriş yaptığında çalışacaktır. Yani oyuncu her karakter attığında tekrar 12019 alacaktır. İlerde bunu engellemeyi de öğreticem.

Şimdi yine if e bağlı olarak kullanılan elseif komutuna geldik. elseif komutu if ile belirlediğiniz bir şartın dışındaki durumları sınıflandırmak için kullanılabilir. elseif için de ayrı bir end ile bitirmenize gerek yoktur. Örnekle daha güzel anlayacağınızı düşünüyorum.
Lua (Quest):
quest ornek_quest begin
   state start begin
      when login begin
        if pc.level() == 86 then
          pc.give_item2("12019",1)
        elseif pc.level() == 85 then
          say("Sen 85. seviyesin.")
        elseif pc.level() == 81 then
          say("Sen 81. seviyesin.")
        end
      end
   end
end
Yukarıdaki questte gördüğünüz üzere elseif den sonra da then kullanıyor. Anlamı şu oluyor: "eğer öyle değil de böyleyse o zaman şunu yap."

Ne yaptık peki? 86. seviye ile login olan kişiye item verdik. 85. ve 81. seviye ile login olan kişinin ise ekranında yazı çıkmasını sağladık. Umarım daha açıklayıcı olmuştur. Peki yukarıda son yazmış olduğum questi başka nasıl yazabilirdik? elseif kullanmadan da yazabilir miydik? Evet yazardık. Her şart için ayrı if kullanırdık.

Şu şekilde yapalım:
Lua (Quest):
quest ornek_quest begin
   state start begin
      when login begin
        if pc.level() == 86 then
          pc.give_item2("12019",1)
        end
        if pc.level() == 85 then
          say("Sen 85. seviyesin.")
        end
        if pc.level() == 81 then
          say("Sen 81. seviyesin.")
        end
      end
   end
end
Yukarıda gördüğünüz questte her şart için ayrı if kullandık ve her if sonucunda bir end kullandık. Gördüğünüz üzere bir if ile işimizi bitirdikten sonra hemen end komutunu yapıştırıyoruz. Aksi taktirde kafanız karışabilir.

Devam edelim. Şimdi when ile ne yapabiliriz ona bi bakalım. whenle kullanılabilecek komutların bazıları şunlardır: login, logout, levelup, use, click, chat, letter, button, info, enter, kill. Benim aklıma gelenler bunlar. Şimdi bunlarla neler yapabileceğimize bir bakalım.

login: Oyuna giriş demek. Karakter atma da olabilir.
logout: Oyundan çıkış demek. Mesela kuleden çıkmak için karakter attığınızda sizi dışarı atması için bu komut kullanılmıştır.
levelup: Oyuncu level aldığında questin çalışmasını sağlar.
use: Bir iteme sağ tıkladığınızda questin çalışmasını sağlar. Önemli bir nokta: Her item çalışmaz. Navicattan girip type 18 yapmanız gerekir ki item quest itemi olsun.
click: Bir npcye tıkladığınızda direk konuşmaya başlar. Şehir bekçisindeki ya da lonca demircilerindeki gibi.
chat: Bir npcye tıkladığınızda çeşitli seçeneklerle karşılaşırsınız. Mesela Demirciye tıkladığınızdaki gibi.
letter: Görev yazma da kullanılan bir komut. Ayrıntısına ileride giricem.
button: Görev butonu ile ilgili.(ekranın sol tarafında çıkan mektuplar)
info: "n" harfine bastığınızda karşınıza çıkan seçeneklerle ilgili.
enter: Bunu ben de tam bilmiyorum hiç kullanmadım. Yani gerek duymadım.
kill: Bir mobu öldürdüğünüzde questin çalışmasını sağlar.

Bu komutları mantık çerçevesinde beraber kullanabiliriz. Yani bunları or ve and ile birbirine bağlayabiliriz. Örnek verecek olursak.
Lua (Quest):
quest ornek_quest begin
    state start begin
       when login or logout begin
          pc.remove_item("11111",5)
       end
    end
end
Bu questte şunu yaptık: Oyuncu oyuna giriş yaptığı ya da oyundan çıktığı zaman envanterinden 11111 kodlu itemden 5 tane silinmesini sağladık. Tanıdık gelmesi için şunu örnek vereyim. Şeytan kulesinden çıktığınız zaman envanterinizde 7. kat haritalarının kalmadığını görürsünüz. Bu şekilde sağlanmıştır.

Diğer komutlarımıza örnek verecek olursak:
Lua (Quest):
quest ornek_quest begin
    state start begin
       when 40004.use begin
         pc.warp(111100,2222200)
       end
     end
end
İşte ışınlanma yüzüğünün mantığı. 40004 numaralı iteme sağ tıkladığınızda sizi yukarıdaki koordinatlara ışınlatan bir quest.
Lua (Quest):
quest ornek_quest begin
    state start begin
       when 20000.chat."Quest yazıyoruz." begin
         say("Oyle mi? kolay gelsin o zaman.")
       end
     end
end
Son questte ise 20000 kodlu npcye tıkladığımızda Quest yazıyoruz. diye bir seçenek çıkar. Tıkladığınızda ise Oyle mi? kolay gelsin o zaman. diyecektir.
Lua (Quest):
quest ornek_quest begin
    state start begin
       when 20000.click begin
         say("Questte yazarmış bak bak bak.")
       end
     end
end
Bu questte 20000 kodlu npcye tıkladığınızda direk konuşmaya başlayacaktır.
Lua (Quest):
quest ornek_quest begin
    state start begin
       when 1093.kill begin
         notice_all("Adamın biri ne azraili öldürdü!")
       end
     end
end
Yukarıdaki quest tanıdık geldi mi? Azraili öldürdüğünüzde duyuru geçmesini sağlayan questtir kendisi. Bu kadar basit yapılır işte. kill komutunun or lu kullanımına bakmak için biyolog görevi questlerini inceleyebilirsiniz.

Sonraki aşamaya geçelim. Şimdi de "local" komutunu inceleyelim. local'in kelime anlamı "yerel" demektir. Bu komut sizin herhangi bir kelimeye ya da sayıya bir anlam yüklemenizi sağlar. Örnekle açıklayacak olursak:
Lua (Quest):
quest ornek_quest begin
   state start begin
      when 40002.use begin
         say("Nereye gidelim?")
         local naber = select("1.köy","2. köy","vazgec")
         if naber == 1 then
         pc.warp(111222,4444333)
         elseif naber == 2 then
         pc.warp(36666,55555)
         elseif naber == 3 then
         return
         end
       end
    end
end
Şimdi yukarıdaki questte sadece local komutunu kullanmadım. Daha önce kullanmadığım bir kaç komut daha kullandım. select() komutu sizin karşınıza seçenekler çıkartır. Işınlanma yüzüğünü düşünün. Tıkladığınızda karşınıza çıkan seçenekler bu komut ile yapılmıştır. Tırnak içinde seçeneği yazarsınız sonra virgül koyup 2. seçeneği tırnak içinde yazarsınız. Yazdığınız sıraya göre if komutu ile bağlayıp ne yapacağını yazarsınız. Bu questle şunu yaptık:
"naber" kelimesini local olarak yani sadece bu quest için seçeneklere atadık. naber demek artık bu questte bizim için seçtiğimiz şey demek.
Yani if naber == 1 then diyerek select() komutu ile yazdığımız seçeneklerden 1. sini seçersek questin ne yapacağını belirledik.

return demek adı üstünde geri demek. Burada şu püf nokta var. Eğer ben bu questi sadece naber == 2 ye kadar yazarsam, 3. seçeneğe tıkladığımda hiç bişey olmayacaktır. Yani ben yukarıdaki questi şöyle yazsam:
Lua (Quest):
quest ornek_quest begin
   state start begin
      when 40002.use begin
         say("Nereye gidelim?")
         local naber = select("1.köy","2. köy","vazgec")
         if naber == 1 then
         pc.warp(111222,4444333)
         elseif naber == 2 then
         pc.warp(36666,55555)
         end
       end
    end
end
vazgec i seçtiğimde yine hiç bir şey yapmayacak. İşte bu return komutu bunu yapıyor. Yani hiç bişey yapmıyor. Kullanmasak da olur.
 
Son düzenleme:
Quest Yazma Dersleri 2

Şimdi daha fazla içlere girmeden önce with komutunun kullanılışına bakalım. Bu komutu hem if komutu hem de when komutu ile kullanabilirsiniz. Aslından bir bakıma when ile beraber kullanıldığında sizi if komutu kullanmaktan kurtarır. with Türkçede "bununla birlikte" anlamına gelir. Kullanışı için örnek verelim:
Lua (Quest):
quest ornek_quest begin
   state start begin
     when login with pc.level() == 75 begin
        say("Tebrikler. 75. seviye olmuşsun.")
     end
   end
end
Yukarıdaki questte şunu yaptık. Bir oyuncu 75. seviye olarak oyuna giriş yaptığında ekranında Tebrikler. 75.seviye olmuşsun. yazısı çıkar. Hatırlarsanız daha önce şöyle yapmıştık:
Lua (Quest):
quest ornek_quest begin
   state start begin
     when login begin
        if pc.level() == 75 then
          say("Tebrikler. 75. seviye olmuşsun.")
        end
     end
   end
end
Bu son yazdığım 2 quest aynı şeyi yapar. Tek fark gereksiz yere if kullanmadan with ile olayı bağladım. Eğer 75 level olmayanlar için de bir şeyler yapacaksam, if kullanmakta fayda var. Çünkü diğerleri için elseif ya da else kullanacağım. with ile de bu yapılabilir fakat iş daha da uzar. Hangi komutu ne zaman kullanacağımızı bilmek lazım.

Şimdi basit bir komut olan wait() komutundan bahsedelim kısaca. Diyelim ki chat ya da use kullanarak hazırladığınız bir quest var. say("") komutu kullanarak bir sayfa yazı yazdınız ve sayfa yetmiyor. Diğer sayfaya geçmek için araya wait() koyuyorsunuz. Bu oyunun içine "Devam" olarak yansıyor. Örneğin;
Lua (Quest):
quest ornek_quest begin
   state start begin
      when 20000.chat."deneme quest" begin
      say("bilmem ne bilmem ne")
      say("kem küm kem küm")
      wait()
      say("Bilmem ne bilmem ne")
      end
   end
end
Yukarıdaki gibi kullanabilirsiniz.

Sırada daha önce söylediğim şeyi anlatmaya geldi. Mesela bir oyuncuya oyuna ilk girişinde item vermek istiyorsunuz. Örneğin give_start_weapon.quest dosyasındaki gibi. Şimdi şöyle bir şey var. Eğer questi şu şekilde yazarsanız;
Lua (Quest):
quest ornek_quest begin
   state start begin
      when login begin
      pc.give_item2("109",1)
      end
   end
end
Bu oyuncu her karakter attığında tekrar item alacaktır. Bunu nasıl engelleriz. İşte bizim jokerimiz: pc.setqf() ve pc.getqf(). Bu komutları çok sevin. :D

Şimdi bu komutlar ne yapar? Bu komutlar mysql deki player> quest dizinine kayıt yapar. Yani siz bir questte bu komutu kullanırsanız kayıt tutulacak. 2. defa aynı şeyi yaptığınızda o quest sizin için çalışmayacak. Örneğin;
Lua (Quest):
quest ornek_quest begin
   state start begin
      when login with pc.getqf("yaptinmi") == 0 begin
       pc.give_item2("109",1)
       pc.setqf("yaptinmi",1)
       end
   end
end
Ne yaptık? pc.getqf("yaptinmi") ile daha önce bu kelime için bir kayıt yapılmış mı baktık. Eğer bu quest içinde hiç pc.setqf("yaptinmi",1) ya da 2,3... gibi bir şey kullanmadıysanız o kişi için pc.getqf("yaptinmi") 0'dır. Ben şimdi yazdığım pc.setqf("yaptinmi",1) ile bu oyuncuya eşyayı verdikten sonra kayıt tutturdum. Bir daha ki girişlerinde aynı eşyayı alamayacak. Peki bu qf ne zaman silinir derseniz sonsuza kadar kalır. Tabi siz mysql player içindeki questi silmezseniz.

Şimdi ise diğer jokerlerimize geçelim. game.set_event_flag() ve game.get_event_flag()'ı da çok sevin
biggrin.png
Bu komutları şöyle düşünün. qf komutları yani bir üstteki komutlar sadece bir oyuncu içindi. bu game.set_event_flag() ve game.get_event_flag() oyunun tamamı için aynı şeyi yapıyor. Ama bunun daha güzel bir yanı var gm karakterinizle bu komutu oyun içinde kontrol edebilirsiniz. Ve ayrıca bu komut sadece tek quest için değildir. Tüm questleri etkiler. Yani bi questte bu komutu kullandıysanız diğer questlerde de bu komuta bağlı bir şey varsa onu da etkiler. Ama yanlış anlamanızı istemem. Aynı kelime için kullandığınız komutlardan bahsediyorum. Örnekle daha güzel anlatacağıma inanıyorum.
Lua (Quest):
quest ornek_quest begin
   state start begin
      when login with game.get_event_flag("uyari") == 1 begin
         notice("xxx etkinliği devam ediyor.")
      end
   end
end
Şimdi bu quest napar? eğer event_flag("uyari") 1 ise oyuna giren oyuncuya uyarı verir. Oyun içinden bu komutu kontrol edebileceğimizi söylemiştim peki nasıl yapıcaz? Şu şekilde. Gm karakterinizden /e uyari 1 yazdığınızda bu quest çalışmaya başlar. Yani oyuna giren oyuncuya uyarı vermeye başlayacaktır. Bu komut nelerde var? Mesela o x yarışması'nın questi bu komutla ilgili. /e uyari 0 ya da 1 den farklı bir sayı yazarsanız bu quest çalışmayacaktır.
 
Quest Yazma Dersleri 3

Sırada timer var. 3 çeşit timer vardır.
timer()
server_timer()
loop_timer()

Bunlar adı üstünde zamanlayıcılar. Yani bir şey yaparsınız. Sonuna timer koyarsınız. Belirlediğiniz süre geçtikten sonra istediğiniz bir şeyi yapar. Peki neden 3 çeşit timer var? Farkları ne?

timer(): normal bir zamanlayıcıdır. Ek bir fonksiyonu yoktur.
server_timer(): Bu da timer() komutu ile aynı şeyi yapar. Ama bu komutla yine güzel bir komut olan get_server_timer_arg() kullanılabilir. Ayrıntısından birazdan bahsedeceğim.
loop_timer(): Adı üstünde bir döngü şeklindedir. Bir süre belirlersiniz ve bu timer sürekli kendini tekrarlar. Şimdi örneklerle daha kolay anlayacaksınız.

Ayrıca timerlara başladığımıza göre artık bir quest içinde birden fazla when komutu kullanımını da bu örneklerle açıklayabiliriz.

Önce bir queste başlayalım.
Lua (Quest):
quest ornek_quest begin
   state start begin
      when login with not pc.is_gm() and pc.get_map_index() == 79 and pc.getqf("lider") == 1 begin
      timer("disari_yolla",600)
      notice_in_map("10 dakika sonra dışarı ışınlanacaksınız.")
      end

      when disari_yolla.timer begin
      warp_all_to_village(79)
      end
   end
end
Buradaki "lider" e takılmayın onu kafadan salladım.

Şimdi bu questte bir timer kullandım. Ayrıca 2 defa when kullandım. Bu nasıl oldu? Şimidye kadar hep bir defa when kullandık.
Arkadaşlar bir quest içinde when i de state i de istediğiniz kadar kullanabilirsiniz. Yeter ki bir önceki when i ya da state i end komutu ile bitirin. whenin kullanımı basittir ama state i sonlandırıp yeni bir state başlatmak için araya bağlantıyı sağlayacak komutu girmek lazım. Neyse şimdi state i geçelim bizim işimiz when ile.

Bu end olayı şöyledir. ilk koyduğunuz end son kullandığınız komutu bitirir. Yani ben burda ne kullandım? quest, state, when. ilk koyduğum end son koyduğum when i bitirdi. Eğerki ben bu whenden sonra bir de if kullansaydım, bu when kısmını bitirmem için 2 tane end kullanmam gerekecekti. Tahmin edersiniz ki state'i bitirmek için de bir end daha koymak gerekecekti.

Bu quesste ne yaptık? Bir kişi map index i 79 olan bir haritaya girdi ve bu kişinin qf("lider")'i 1. Şartları sağladığını düşünüyoruz. Bunlar hikaye kısmı. Her neyse oyuncu haritaya giriş yaptı ve haritadaki tüm oyuncuları 10 dakika sonra dışarı atacağım diye uyardım.(notice_in_map komutu) Sonra 10 dakika dolunca da dışarı yollamak (burada tüm oyuncuları köye yollama kodunu kullandım) için when disari_yolla.timer begin le yeni bir when başlattım. Bu questin bir sakıncası var. Hazır yeri gelmişken ona değinelim. Burada haritaya giriş yapan oyuncu eğer bu haritadan timer dolmadan çıkarsa nolur? timer işlemez. Bunun önüne de şu şekilde geçeriz;
Lua (Quest):
quest ornek_quest begin
   state start begin
      when login with not pc.is_gm() and pc.get_map_index() == 79 and pc.getqf("lider") == 1 begin
      server_timer("disari_yolla",600,get_server_timer_arg())
      notice_in_map("10 dakika sonra dışarı ışınlanacaksınız.")
      end

      when disari_yolla.server_timer begin
      warp_all_to_village(79)
      end
   end
end
Yukarıdaki gibi server_timer kullanırsak oyuncu o haritadan çıksa bile orada timer işlemeye devam eder. Bir de loop_timer a örnek verip timerları bitirelim.
Lua (Quest):
quest ornek_quest begin
   state start begin
      when login with pc.is_gm() begin
      cleartimer("duyuru")
      loop_timer("duyuru",600)
      end
    
      when duyuru.timer begin
      notice_all("Bu oyun bilmem ne bilişime aittir.")
      end
   end
end
Bu quest ne yapar? Oyuna bir gm girdiğinde işlemeye başlar. Peki neden cleartimer koydum? Login komutundan dolayı. Eğer bu komutu koymazsam gm her oyuna girdiğinde ya da bi yere ışınlandığında bu timer tekrar tekrar başlayacak. Bu da sürekli saçma sapan zamanlarda duyuru geçmesine neden olabilir. Benim yaptğım şekilde gm oyuna her girdiğinde bir önceki timer sıfırlanıp tekrar timer başlatılır. Bu quest 10 dakikada bir duyuru geçer.
 
Quest Yazma Dersleri 4

Sırada kısaca "not" komutu var. Bu komutta işimizi oldukça kolaylaştıracak. when ve if komutu ile birlikte kullanılabilir. Mesela şöyle bir örnek verelim. Bir görev yazdınız ve bunun gm karakterlere gelmesini istemiyorsunuz. Şu şekilde yaparsınız;
Lua (Quest):
quest ornek_quest begin
   state start begin
      when login or levelup with pc.level() == 90 and not pc.is_gm() begin
      send_letter("Gorev")
      end
   end
end
Yukarıda gördüğünüz gibi "not" komutunu and veya with ile beraber kullanırız genelde. "not" Türkçe karşılığı "değil" kelimesine karşılık gelir. Yani yukarıdaki quest şunu yapar. 90. seviyede olup gm olmayan kişilere Gorev adında bir quest butonu gidecek. Bu tür komutlar yazdığınız questlerdeki bugları gidermenize yardımcı olacak. Quest yazmaya başladığınızda ne demek istediğimi daha rahat anlayacaksınız.

Sırada pc.get_name() gibi komutları say(""), notice("") ... gibi komutlar içinde nasıl kullanacağımıza bakalım. Bu tür komutları beraber kullanmak istiyorsak "..pc.get_name().." şeklinde yazmamız gerekir. Şimdi bir örnekle açıklayalım.
Lua (Quest):
quest ornek_quest begin
   state start begin
      when 1093.kill with pc.get_map_index() == 66 begin
         notice_all(""..pc.get_name()..", "..pc.get_level()..". seviyede Azrail'i öldürdü!")
      end
   end
end

Yukarıdaki quest, indexi 66 olan bir haritada azrail öldürüldüğünde "xxx, xx. seviyede Azrail'i öldürdü!" şeklinde duyuru geçmesini sağlayacak. Bunun sadece oyuncuya gitmesini istersek "notice_all" yerine "notice" kullanırız. Ya da duyuru şeklinde çıkmasını istemiyorsak "chat" kullanırız. Bildiğim tüm kodları ileride tek tek açıklayacağım. Şimdilik bir questin iskeleti nasıl oluşturulur onu öğreniyoruz.

Aynı şeyi kendimiz local kullanarak da yapabiliriz. Yine işimizi kolaylaştıran bir şeyden bahsedeyim. Daha sonra input() komutuna geçeceğim.
Lua (Quest):
quest ornek_quest begin
   state start begin
      when 20000.chat."İçeri girmek istiyorum." with game.get_event_flag("harita_acik") == 1 begin
         local level = pc.level()
         local isim = pc.get_name()
         if level >= 90 then
         say("Merhaba "..isim..", seni içeriye alabilirim.")
         pc.warp(111100,222200)
         else
         say("Üzgünüm "..isim..". Yeteri kadar güçlü değilsin.")
         end
      end
   end
end
Yukarıdaki quest için "isim" ve "level" kelimelerine, local komutunu kullanarak, bazı komutları atadım. Bu questin daha da uzadığını düşünün. Her seferinde komut yazmaktansa bu belirlediğim kelimeleri kullanmam bana zaman kazandıracaktır. Ayrıca with game.get_event_flag("harita_acik") == 1 kullandım. Bunun bana ne yararı var? Eğer gm karakterimle /e harita_acik 1 yazmadıysam, kimse 20000 numaralı npcye tıkladığında "İçeri girmek istiyorum." diye bir sçenek göremeyecek. Bu da oyun içinde size bazı haritaları istediğiniz zaman kapatıp açma kolaylığını sağlar.

input() komutu ile devam ediyoruz. Bu komut ruh taşı questindeki gibi ya da ejderha odasına girerken şifre yazdığınız kutular için kullanılır. Peki kullanımı nasıldır? Örnekle açıklamaya çalışacağım.
Lua (Quest):
quest ornek_quest begin
   state start begin
      when 40000.use begin
      say("Yazdığın yazı tüm imparatorluklarda görülecek.")
      say("Aşağıda gördüğün kutuya söylemek istediğini yaz.")
      local duyuru = input()
      notice_all(""..pc.get_name().." adlı oyuncu şunları söylüyor:")
      notice_all(""..duyuru.."")
      end
   end
end
input() komutundan sonra da end kullanmıyoruz. Kullanımı yukarıdaki gibidir. Ne yaptık? "duyuru" kelimesine input() komutunu atadık ve oyuncunun yazdığı her şey bu sayede "duyuru" kelimesi üzerine kaydedildi. Daha önce yaptığımız gibi "..duyuru.." kullanarak oyuncunun yazdığı şeyleri tüm oyunculara duyurduk.

Geldik 1 quest içinde birden fazla state kullanmaya. Öncelikle bu ne işe yarar? TR deki görevleri düşünün. Uriel'e bir şey götürüyorsunuz sonra size bir şey öldürmenizi söylüyor o dediğini de yapıyorsunuz bu sefer başka bir şey istiyor. Bunları nasıl yapacağımızı küçük örneklerle göstereceğim. Öncelikle hatırlarsanız bir quest içinde birden fazla when kullanırken son kullandığımız when'i end komutu ile bitirip yeni bir when'e başlıyorduk. Burada da aynı şeyi yapacağız fakat son state'te bir komut kullanıp 2. state'i çalıştırmamız lazım. Örnek verecek olursak;
Lua (Quest):
quest ornek_quest begin
   state start begin
      when 20000.chat."Göreve başla" begin
      say("Demek göreve başlamak istiyorsun.")
      say("Pekala 20 tane xxx canavarı öldür bakalım.")
      setstate(oldur)
      end
   end
 
   state oldur begin
      when 2401.kill begin
         if pc.getqf("oldurdum") < 19 then
         pc.setqf("oldurdum", pc.getqf("oldurdum") + 1)
         else,f pc.getqf("oldurdum") == 19 then
         pc.setqf("oldurdum",20)
         setstate(oldurdum)
         end
      end
   end

   state oldurdum begin
      when letter begin
      send_letter("Görev tamam")
      end
      when button or info begin
      say("20 tane xxx öldürdün.")
      say("20000 no'lu npc ye geri dön.")
      end
   
      when 20000.chat"Görev tamam" with pc.getqf("oldurdum") >= 20 begin
      say("Harika görevi bitirmişsin.")
      say("Al bu da ödülün.")
      pc.give_item2("xxxx",1)
      clear_letter()
      setstate(complete)
      end
   end

   state complete begin
   end
end
Yukarıda gördüğünüz gibi şimdiye kadarki en uzun questimizi yazdık. 4 tane state kullandık. Basit bir canavar öldürme questi oldu. Stateleri bağlamak için setstate() komutunu kullandık. Bu komut bir önceki state içinde yadığınız her şeyi devredışı bırakır. Yani state start begin yazdınız içinde atıyorum bir npcyi konuşturdunuz ve ardına setstate() komutu kullanarak diğer bir state'e geçirdiniz. Artık O kişi az önce konuştuğu npcye tekrar tıkladığında aynı şeyleri görmeyecek. Yukarıda ne yaptık? İlk önce 20000 numaralı npc ile konuştuk. Bize görev verdi. Öldürdüğü mob sayısını qf komutuyla kayıt ettim. Her kestiği mob için bir ekleyecek şekilde. Dikkat edin pc.getqf("oldurdum") + 1 yaptım. Bu demek oluyor ki her öldürdüğü mobdan sonra bir önceki qf nin üzerine 1 ekleyip kaydedecek. Bu 19 a kadar böyle devam edecek. 19 olduktan sonra 20 yaptığında hemen diğer bir state'e geçmesi için setstate() kullandım ve oyuncunun ekranın solunda bir send_letter() komutu ile bir quest butonu çıkmasını sağladım. Ayrıca Bu quest butonuna tıkladığında da(when button or info begin) bilgi vermesini sağladım. Npc'ye gittiğinde ise Ödülünü verdim ve quest butonunu clear_letter() ile sildim. Sonra görev bug'a görmesin diye yeni bir state e geçirdim.(setstate(complete)) Bu state'te hiç bir şey yapmadan questi bitirdim. Artık tekrar görev gelmeyecek. Peki ben bu görevin sürekli baştan yapılmasını istiyorsam ne yaparım? En sondaki setstate(complete) yazdığım yeri setstate(start) olarak yazarım. İlk state tekrar çalışır.

Arkadaşlar state'ler mysql quest tablosuna kaydedilir. Siz quest tablosunu boşaltmadığınız sürece statelerde kayma olmaz başa sarmaz.

Şimdi ise state ile 2 quest arasında bağlantı kurmayı gösterelim. Bunu set_quest_state("questadı","stateadı") şeklinde yapıcaz. Biyolog görevlerini hatırlayın. Seviyeniz 40 ı geçse bile 30 görevini bitirmeden 40 görevine başlayamazsınız. Bunu nasıl yaparız? Örnek verelim. İlk önce 1. questimizi yazalım.
Lua (Quest):
quest ornek_quest begin
   state start begin
      when 2493.kill begin
         set_quest_state("ornek_quest2","run")
      end
   end
end
Bu quest ile 2. questimiz olan ornek_quest2'yi başlatıyoruz. Bir kere bir questin ilk state'i start ile başlamak zorunda. İyi de ben 2. questim için yapacaklarımı start içinde yazarsam bu kullandığım komut bir işe yaramayacak. Nasıl yapacağım? Şu şekilde;
Lua (Quest):
quet ornek_quest2 begin
   state start begin
   end
   state run begin
      when 20000.chat."Göreve başla." begin
      say("2493 mobunu öldürdüğüne göre artık bu görevi yapabilirsin.")
      end
   end
end
Ne yaptık? state start'a başlar başlamaz hemen end komutu ile sonlandırdık. Starttan sonra setstate(run) yazmadığım için 2. state çalışmayacaktır. Ama 1. questimizde set_quest_state("ornek_quest2","run") yazdığımız için 2493 mobunu her öldürdüğümüzde bu 2. questimiz çalışacaktır. 2. quest herhangi bir görev questi değil uzatmak istemedim örnek olsun diye hemen kısaca sonlandırdım. Onu uzatabilirsiniz. Şimdilik bu kadar.
 
Quest Yazma Dersleri 5

get_time() ile devam edelim. Kelime anlamı olarak tam karşılamasa da o an için zamanın tam olarak ne olduğunu kaydeder.

Bu fonksiyon timer'a benzer. Farkı tek bir oyuncu için çalışabilir olmasıdır. setqf veya event_flag ile kullanılabilir. Çok işe yarar bir komuttur. Örnekle açıklayalım.
Lua (Quest):
quest ornek_quest begin
   state start begin
      when 20000.use begin
      if pc.getqf("actinmi") - get_time() > 0 then
      say("Bu eşyayı 30 dakikada bir kullanabilirsin.")
      else
      pc.give_item2("12222",1)
      pc.setqf("actinmi",get_time() + 1800)
      end
   end
end
Yukarıdaki quest ile bir eşyaya süre koydum. Sadece yarım saat içinde 1 kere kullanılabilir oldu. Nasıl oldu peki? Oyuncunun ilk tıklayışında qf("actinmi") kayıtını o anki zamanın üzerine 1800 ekleyerek kaydettirdim. 1800, 30 dakika yapar. Eğer 2. tıkladığında yarım saat geçmemiş ise 12222 numaralı eşyayı vermeyecektir. Zaman süreki işlediğinden dolayı oyuncunun ilk tıkladığı zamanın 1800 fazlasına da elbet gelecektir. Çıkarma işlemi ile aradaki farktan yararlanıyorum. Bu iki sayısal değer birbirne eşit olduğunda çıkarma işlemi yaptığınızda 0 olacak. Eğer get_time() + 1800 hala oyuncunun 2. tıkladığı zamandaki get_time() dan büyük ise yarım saat geçmemiş demektir. Çok iyi anlatamadım burayı. O yüzden yukarıdaki questi dikkatle inceleyin umarım anlarsınız.

İkinci kodumuz ise setf(). Bu komutu kullanarak 2 quest arasında bağlantı kurabiliriz. Mesela şöyle yapalım.
Lua (Quest):
quest ornek_quest begin
   state start begin
      when 1093.kill begin
      pc.setf("azrail_kesildi",get_time() + 24*60*60)
      end
   end
end
Lua (Quest):
quest ornek_quest2 begin
   state start begin
      when 20005.chat."İçeri gir" begin
         if pc.getf("azrail_kesildi","ornek_quest") - get_time() > 0 then
         say("içeri girebilirsin.")
         else
         say("son 24 saat içinde azraili öldürmüş olman gerekiyor.")
         end
      end
   end
end
2 questi nasıl birletirdiğime bakın. 1. questte setf komutu ile yine bir kelime üzerine o anı bir sayısal değer olarak düşünürsek 24*60*60 fazlasını kaydettirdim. 2. questte nasıl bağladımı dikkatlice inceleyin. pc.getf("azrail_kesildi","ornek_quest") Önce kelimemiz sonra ilk questin adı. Bu şekilde bağlamayı yapabiliriz. Bunu d.getf ya da d.setf ile de yapabiliriz. d. koyarak yaptığımızda o an orada olan herkes için kayıt yapılır.
 
Eğitim serisini 4 gözle bekliyorum :D
Server için panel kodlamaları, üniversiteye hazırlık sık sık video çekemiyorum. Önceden depoladıklarımı paylaşıyorum. :D O üniteler için de önceden hazırlamam gereken şeyler olabilir. Aklımda şey var. İlk önce lua derslerini ayrı olarak mı ele aliyim.? İf, foreach, query gibi şeyleri gösterdikten sonra mı oyun için tam anlamıyla quest yazmayı anlatım diyorum. Sizin bu konuda fikriniz nedir?
 
Server için panel kodlamaları, üniversiteye hazırlık sık sık video çekemiyorum. Önceden depoladıklarımı paylaşıyorum. :D O üniteler için de önceden hazırlamam gereken şeyler olabilir. Aklımda şey var. İlk önce lua derslerini ayrı olarak mı ele aliyim.? İf, foreach, query gibi şeyleri gösterdikten sonra mı oyun için tam anlamıyla quest yazmayı anlatım diyorum. Sizin bu konuda fikriniz nedir?
İlk temel konuları anlat
 
Mrb

Questimde soyle bir sorun var

timer("kilitat",10) geri sayimi yapiyor

when kilitat.timer begin

pc.disconnect_with_delay(0)

end

Sayım bitiğinde oyundan atmıyor
Gerekli kotlar quest pc cpp de ekli diğer kodlarda ekliki saten kod calışıyor

timerin altına
pc.disconnect_with_delay("kilitat",0)
Bu şekil atıgımda ise geri sayım bitiyoroyundan atıyor lakin oyuna gitiş yapıp şifreyi girdiğimde ise
cleartimer("kilitat") timeri geri saymiyor ve oyundan yine atıyor yardımcı olurmusunuz tşkler.
 
En son bir moderatör tarafından düzenlenmiş:
Mrb

Questimde soyle bir sorun var

timer("kilitat",10) geri sayimi yapiyor

when kilitat.timer begin

pc.disconnect_with_delay(0)

end

Sayım bitiğinde oyundan atmıyor
Gerekli kotlar quest pc cpp de ekli diğer kodlarda ekliki saten kod calışıyor

timerin altına
pc.disconnect_with_delay("kilitat",0)
Bu şekil atıgımda ise geri sayım bitiyoroyundan atıyor lakin oyuna gitiş yapıp şifreyi girdiğimde ise
cleartimer("kilitat") timeri geri saymiyor ve oyundan yine atıyor yardımcı olurmusunuz tşkler.
Konuyu açtığım zaman site xf kullanmıyordu. O yüzden bildirim gelmemiş kusura bakmayın yeni gördüm ama aradan baya bi vakit geçti galiba. :'(
 
Yalnız baya geçmiş :D
Aynen genellikle foruma gelen üyelerin hangi konulara baktığını kontrol ediyorum. Bi üye de buna bakıyormuş. Girdiğimde arkadaşın mesajını gördüm. :D Neyse şimdi bildirimlere eklendi. Gerçi yakında quest eğitimi üzerinde yeni içerikler olacak. Bu konu alıntıydı. :)
 
Merhaba Quest videolarınızı bulamadım acaba ulaşabileceğim biryer mevcutmudur yada sadece yazılı olarak mı anlatım mevcut.
 
Quest Yazma Dersleri 2

Şimdi daha fazla içlere girmeden önce with komutunun kullanılışına bakalım. Bu komutu hem if komutu hem de when komutu ile kullanabilirsiniz. Aslından bir bakıma when ile beraber kullanıldığında sizi if komutu kullanmaktan kurtarır. with Türkçede "bununla birlikte" anlamına gelir. Kullanışı için örnek verelim:
Lua (Quest):
quest ornek_quest begin
   state start begin
     when login with pc.level() == 75 begin
        say("Tebrikler. 75. seviye olmuşsun.")
     end
   end
end
Yukarıdaki questte şunu yaptık. Bir oyuncu 75. seviye olarak oyuna giriş yaptığında ekranında Tebrikler. 75.seviye olmuşsun. yazısı çıkar. Hatırlarsanız daha önce şöyle yapmıştık:
Lua (Quest):
quest ornek_quest begin
   state start begin
     when login begin
        if pc.level() == 75 then
          say("Tebrikler. 75. seviye olmuşsun.")
        end
     end
   end
end
Bu son yazdığım 2 quest aynı şeyi yapar. Tek fark gereksiz yere if kullanmadan with ile olayı bağladım. Eğer 75 level olmayanlar için de bir şeyler yapacaksam, if kullanmakta fayda var. Çünkü diğerleri için elseif ya da else kullanacağım. with ile de bu yapılabilir fakat iş daha da uzar. Hangi komutu ne zaman kullanacağımızı bilmek lazım.

Şimdi basit bir komut olan wait() komutundan bahsedelim kısaca. Diyelim ki chat ya da use kullanarak hazırladığınız bir quest var. say("") komutu kullanarak bir sayfa yazı yazdınız ve sayfa yetmiyor. Diğer sayfaya geçmek için araya wait() koyuyorsunuz. Bu oyunun içine "Devam" olarak yansıyor. Örneğin;
Lua (Quest):
quest ornek_quest begin
   state start begin
      when 20000.chat."deneme quest" begin
      say("bilmem ne bilmem ne")
      say("kem küm kem küm")
      wait()
      say("Bilmem ne bilmem ne")
      end
   end
end
Yukarıdaki gibi kullanabilirsiniz.

Sırada daha önce söylediğim şeyi anlatmaya geldi. Mesela bir oyuncuya oyuna ilk girişinde item vermek istiyorsunuz. Örneğin give_start_weapon.quest dosyasındaki gibi. Şimdi şöyle bir şey var. Eğer questi şu şekilde yazarsanız;
Lua (Quest):
quest ornek_quest begin
   state start begin
      when login begin
      pc.give_item2("109",1)
      end
   end
end
Bu oyuncu her karakter attığında tekrar item alacaktır. Bunu nasıl engelleriz. İşte bizim jokerimiz: pc.setqf() ve pc.getqf(). Bu komutları çok sevin. :D

Şimdi bu komutlar ne yapar? Bu komutlar mysql deki player> quest dizinine kayıt yapar. Yani siz bir questte bu komutu kullanırsanız kayıt tutulacak. 2. defa aynı şeyi yaptığınızda o quest sizin için çalışmayacak. Örneğin;
Lua (Quest):
quest ornek_quest begin
   state start begin
      when login with pc.getqf("yaptinmi") == 0 begin
       pc.give_item2("109",1)
       pc.setqf("yaptinmi",1)
       end
   end
end
Ne yaptık? pc.getqf("yaptinmi") ile daha önce bu kelime için bir kayıt yapılmış mı baktık. Eğer bu quest içinde hiç pc.setqf("yaptinmi",1) ya da 2,3... gibi bir şey kullanmadıysanız o kişi için pc.getqf("yaptinmi") 0'dır. Ben şimdi yazdığım pc.setqf("yaptinmi",1) ile bu oyuncuya eşyayı verdikten sonra kayıt tutturdum. Bir daha ki girişlerinde aynı eşyayı alamayacak. Peki bu qf ne zaman silinir derseniz sonsuza kadar kalır. Tabi siz mysql player içindeki questi silmezseniz.

Şimdi ise diğer jokerlerimize geçelim. game.set_event_flag() ve game.get_event_flag()'ı da çok sevin
biggrin.png
Bu komutları şöyle düşünün. qf komutları yani bir üstteki komutlar sadece bir oyuncu içindi. bu game.set_event_flag() ve game.get_event_flag() oyunun tamamı için aynı şeyi yapıyor. Ama bunun daha güzel bir yanı var gm karakterinizle bu komutu oyun içinde kontrol edebilirsiniz. Ve ayrıca bu komut sadece tek quest için değildir. Tüm questleri etkiler. Yani bi questte bu komutu kullandıysanız diğer questlerde de bu komuta bağlı bir şey varsa onu da etkiler. Ama yanlış anlamanızı istemem. Aynı kelime için kullandığınız komutlardan bahsediyorum. Örnekle daha güzel anlatacağıma inanıyorum.
Lua (Quest):
quest ornek_quest begin
   state start begin
      when login with game.get_event_flag("uyari") == 1 begin
         notice("xxx etkinliği devam ediyor.")
      end
   end
end
Şimdi bu quest napar? eğer event_flag("uyari") 1 ise oyuna giren oyuncuya uyarı verir. Oyun içinden bu komutu kontrol edebileceğimizi söylemiştim peki nasıl yapıcaz? Şu şekilde. Gm karakterinizden /e uyari 1 yazdığınızda bu quest çalışmaya başlar. Yani oyuna giren oyuncuya uyarı vermeye başlayacaktır. Bu komut nelerde var? Mesela o x yarışması'nın questi bu komutla ilgili. /e uyari 0 ya da 1 den farklı bir sayı yazarsanız bu quest çalışmayacaktır.
merhaba @Whistle videolu hali mevcut mu 1.dersten baslayıp udemy üzerinde vs. kaldırılmış olarak gözüküyor da yardımcı olabilirsen sevinirm
 
Geri
Üst