Merhabalar ;
Arkadaşımız bana özelden mesaj atmış,küçük bir ayrıntıda takılmış sanırım.Bende bildiğimce sorununa yardımcı olmaya çalışacağım..Özelden değilde buradan paylaşırsam belki birileri de yararlanır.
Quest dosyanızı paylaştığınız için teşekkür ederim. Bu sayede sorunun kaynağını net bir şekilde tespit edebiliriz.
İlk analizimde belirttiğim gibi, sorun gereksiz yere yeniden zindan ataması yapılmasından kaynaklanıyor. Kodunuzu inceledim ve sizin dosyanızda bu duruma sebep olan yer, when dragonlair_grupgiris.timer bloğunda kullandığınız d.join_coords(...) fonksiyonudur.
İlk önce sorunun detaylı analiz edelim.
Sizin quest yapınızda, benim ilk örnekte gösterdiğim gibi bir döngü içerisinde d.set(pid) komutu bulunmuyor. Ancak probleminiz, kullandığınız d.join_coords fonksiyonunun C++ tarafındaki iç yapısından kaynaklanıyor.
Bu d.join_coords fonksiyonu, muhtemelen sizin kaynak kodunuza özel olarak eklenmiş bir fonksiyondur ve şu şekilde çalışmaktadır:
1- Önce zindanı oluşturur ve onu parti liderine atar.
2- Ardından partideki tüm üyeleri zindana ışınlar.
3- Işınlama sırasında, her bir üyeye tekrar zindanı atamaya çalışır.
İşte bu 3. adım, SYSERR hatasını almanıza neden oluyor. Yani sorun, Lua kodunuzdan çok, bu özel fonksiyonun yazılım mantığıyla ilgilidir.
Tespitlerimin sonucunda ulaşabildiğim çözüm budur : Quest Dosyasını Düzenleyerek Fonksiyonu Devre Dışı Bırakmak
C++ kaynak kodunu düzenlemek yerine, bu sorunu doğrudan quest dosyanızdan, yani Lua tarafından çözebiliriz. Yapacağımız şey, o sorunlu d.join_coords fonksiyonunu kullanmak yerine, zindan oluşturma ve oyuncuları ışınlama işlemlerini manuel olarak yapmaktır.
Aşağıda, when dragonlair_grupgiris.timer bloğunuzun olması gereken doğru halini paylaşıyorum. Lütfen kendi dosyanızdaki ilgili bloğu bununla değiştirin:
DOĞRU KOD (Bu Kodu Kullan):
[CODE title="Lua"]when dragonlair_grupgiris.timer begin
-- 1. ADIM: Zindanı sadece mevcut oyuncu (lider) için oluştur.
-- Bu komut, zindanı otomatik olarak tüm partiye atayacaktır.
if d.join(208) == false then
return
end
-- 2. ADIM: Zindanın map_index'ini al ve diğer işlemleri yap.
local map_idx = d.get_map_index()
if map_idx == 0 then
return
end
-- Seçili zindan üzerinde işlem yapmak için d.select kullanılır.
d.select(map_idx)
-- Sizin orijinal kodunuzdaki temizleme ve ayar fonksiyonları
dragonlair.Temizle()
server_timer("dragonlair_timeup", 30*60, map_idx)
server_timer("dragonlair_25left", 5*60, map_idx)
d.setf("party_leader_pid", party.get_leader_pid())
party.setf("dragonlair_mapindex", map_idx)
d.setf("dungeon_endtime", get_global_time()+30*60*1)
-- 3. ADIM: Partideki diğer üyeleri manuel olarak zindana ışınla.
local pids = party.get_member_pids()
for i, pid in ipairs(pids) do
-- Lideri tekrar ışınlamaya gerek yok, o zaten d.join ile girdi.
if pid ~= pc.get_player_id() then
-- Diğer üyeleri zindan giriş koordinatlarına ışınla.
local target_pc = pc.select_by_pid(pid)
if target_pc then
pc.warp(8436, 10669, map_idx)
end
end
end
-- Lideri tekrar seçili oyuncu yapalım.
pc.select_by_pid(party.get_leader_pid())
end[/CODE]
Yapılan değişikliklerin açıklamasınıda yapayım:
* Sorunlu d.join_coords fonksiyonunu kaldırdık.
* Yerine, sadece lideri içeri alan ve zindanı tüm partiye atayan standart d.join(map_index) fonksiyonunu kullandık.
* Ardından partideki diğer üyeleri bir döngü yardımıyla, pc.warp komutunu kullanarak manuel olarak zindana ışınladık.
Bu yöntemle, her oyuncu zindana sadece bir kez atanmış olacak ve SYSERR hatasını artık almayacaksınız.
Umarım bu detaylı açıklama ve kod, sorununuzu tam olarak çözer.Sıkıntı çözülmez ise buradan yazmaya devam edelim..
Senin yorulmaman için güncelleme yapayım dedim..Bütün olarak düzenlenmiş hali:
[CODE title="Lua"]quest dragonlair begin
state start begin
------ fonksiyonlar ----------------
function GrupKontrol()
local user_fail_level = {}
local user_fail_cd = {}
local user_fail_item = {}
local pids = {party.get_member_pids()}
local need_level = 75
for i = 1, table.getn(pids), 1 do
q.begin_other_pc_block(pids)
if pc.get_level() < need_level then
table.insert(user_fail_level, table.getn(user_fail_level) +1, pc.get_name())
end
if pc.getf("dragonlair","dungeon_time") > get_time() then
table.insert(user_fail_cd, table.getn(user_fail_cd) +1, pc.get_name())
end
if pc.count_item(30179) < 3 then
table.insert(user_fail_item, table.getn(user_fail_item) +1, pc.get_name())
end
q.end_other_pc_block()
end
if table.getn(user_fail_level) == 0 and table.getn(user_fail_cd) == 0 and table.getn(user_fail_item) == 0 then
return true
end
say_npc()
say("Grubun bazı üyeleri ")
say("içeriye girmeye uygun değil.")
if table.getn(user_fail_level) >= 1 then
say(need_level.." seviyeye ulaşmamış:")
for x = 1, table.getn(user_fail_level), 1 do
say(color(1,1,0), " "..user_fail_level[x])
end
end
if table.getn(user_fail_cd) >= 1 then
say("Giriş süresi dolmayanlar :")
for x = 1, table.getn(user_fail_cd), 1 do
say(color(1,1,0), " "..user_fail_cd[x])
end
end
if table.getn(user_fail_item) >= 1 then
say("Giriş bileti olmayanlar :")
for x = 1, table.getn(user_fail_item), 1 do
say(color(1,1,0), " "..user_fail_item[x])
end
end
return false
end
function GrupSok()
local pids = {party.get_member_pids()}
for i = 1, table.getn(pids), 1 do
q.begin_other_pc_block(pids)
pc.remove_item(30179,3)
q.end_other_pc_block()
end
end
function Temizle()
local d_index = d.get_map_index()
clear_server_timer("dragonlair_timeup",d_index)
clear_server_timer("dragonlair_25left",d_index)
clear_server_timer("dragonlair_20left",d_index)
clear_server_timer("dragonlair_15left",d_index)
clear_server_timer("dragonlair_10left",d_index)
clear_server_timer("dragonlair_5left",d_index)
clear_server_timer("dragonlair_out",d_index)
d.setf("party_leader_pid",0)
d.setf("dungeon_endtime",0)
d.setf("dragon_dead",0)
d.setf("dragonlair_regen",0)
d.setf("sure_doldu",0)
d.clear_regen()
d.kill_all()
end
------------------------------------
when 30121.chat."Ejderhayı öldürmek istiyorum!" with pc.get_map_index() == 73 begin
if game.get_event_flag("ejder_open") == 0 then
if pc.is_gm() then
say_title("Event Flag : ejder_open ")
end
say("Dungeon henüz aktif değil!")
return
end
local isparty = false
if party.is_party() then
isparty = true
end
if isparty then
if not party.is_leader() then
say("Bu işlemi sadece grup lideri yapabilir.")
return
end
say_npc()
say("")
say("Ejderha odasına girmek istediğinize ")
say("emin misiniz ?")
say("")
local gir = select(locale.yes,locale.no)
if gir == 1 then
if dragonlair.GrupKontrol() == false then
return
else
dragonlair.GrupSok()
-- pc.remove_item(30179,1)
timer("dragonlair_grupgiris",2)
end
else
return
end
else
if pc.get_level() < 75 then
say_npc()
say("")
say("İçeriye sadece 75 seviye ve üstü oyuncular girebilir.")
return
end
if pc.getf("dragonlair","dungeon_time") > get_time() then
say_npc()
say("")
say("Henüz odaya giremezsin.")
say("Bekleme süren dolunca tekrar gel.")
say("")
say_reward("Kalan Süre : "..LIB_duration(pc.getf("dragonlair","dungeon_time")-get_time()))
return
end
if pc.count_item(30179) < 3 then
say_npc()
say("")
say("Gerekli eşya 3x: "..item_name(30179)..":")
say_item_vnum(30179)
return
end
say_npc()
say("")
say("Ejderha odasına girmek istediğine ")
say("emin misin ?")
say("")
local gir = select(locale.yes,locale.no)
if gir == 1 then
if pc.count_item(30179) < 3 then
return
end
pc.remove_item(30179,3)
timer("dragonlair_sologiris",2)
else
return
end
end
end -- when
when dragonlair_sologiris.timer begin
d.join_coords(208,8436,10669)
dragonlair.Temizle()
server_timer("dragonlair_timeup", 30*60, d.get_map_index())
server_timer("dragonlair_25left", 5*60, d.get_map_index())
d.setf("party_leader_pid",pc.get_player_id())
d.setf("dungeon_endtime",get_global_time()+30*60*1)
end
-- ############### BAŞLANGIÇ: DÜZELTİLEN BÖLÜM ###############
when dragonlair_grupgiris.timer begin
-- 1. Zindanı sadece lider için oluştur, bu işlem zindanı tüm partiye atar.
if d.join(208) == false then
return
end
-- 2. Zindanın map_index'ini al ve diğer ayarları yap.
local map_idx = d.get_map_index()
if map_idx == 0 then
return
end
-- Seçili zindan üzerinde işlem yapmak için d.select kullanılır.
d.select(map_idx)
-- Orijinal kodunuzdaki temizleme ve ayar fonksiyonları
dragonlair.Temizle()
server_timer("dragonlair_timeup", 30*60, map_idx)
server_timer("dragonlair_25left", 5*60, map_idx)
d.setf("party_leader_pid", party.get_leader_pid())
party.setf("dragonlair_mapindex", map_idx)
d.setf("dungeon_endtime", get_global_time()+30*60*1)
-- 3. Partideki diğer üyeleri manuel olarak zindana ışınla.
local pids = party.get_member_pids()
for i, pid in ipairs(pids) do
-- Lideri tekrar ışınlamaya gerek yok, o zaten d.join ile girdi.
if pid ~= pc.get_player_id() then
-- Diğer üyeleri zindan giriş koordinatlarına ışınla.
local target_pc = pc.select_by_pid(pid)
if target_pc then
pc.warp(8436, 10669, map_idx)
end
end
end
-- Son olarak lideri tekrar seçili oyuncu yapalım.
pc.select_by_pid(party.get_leader_pid())
end
-- ############### BİTİŞ: DÜZELTİLEN BÖLÜM ###############
when login begin
local map = pc.get_map_index()
if map >= (208 * 10000) and map < (208 * 10000 + 9000) then
pc.set_warp_location(73 , 1801, 12204)
if pc.get_level() < 35 then
chat("Odaya girmek için seviyen yeterli değil.")
d.exit()
return
end
if party.is_party() then
if d.getf("party_leader_pid") != party.get_leader_pid() then
chat("Sizin grubunuz içeride değil.")
d.exit()
return
end
if party.is_leader() then
if d.getf("dragonlair_regen") == 0 then
d.regen_file("data/dungeon/skia_deliboss.txt")
d.notice("30 dakika içerisinde mavi ejderhayı mağlup et!")
d.setf("dragonlair_regen",1)
end
end
else
if d.getf("party_leader_pid") != pc.get_player_id() then
chat("Bu senin girdiğin zindan değil.")
d.exit()
return
end
if d.getf("dragonlair_regen") == 0 then
d.regen_file("data/dungeon/skia_deliboss.txt")
d.notice("30 dakika içerisinde mavi ejderhayı mağlup et!")
d.setf("dragonlair_regen",1)
end
end
pc.setqf("dungeon_ch",pc.get_channel_id())
pc.setqf("dungeonorgindex",208)
syschat("Ejderin 3 kere can yenilemesini engellemek için 4 tane intikam metni bırakmanız gerekiyor.")
end
end
when logout begin
local map = pc.get_map_index()
if map >= (208 * 10000) and map < (208 * 10000 + 9000) then
pc.setf("dragonlair","dungeon_time",get_global_time() + 60*60*1)
end
end
when kill begin
local map = pc.get_map_index()
if map >= (208 * 10000) and map < (208 * 10000 + 9000) then
if npc.get_race() == 8031 or npc.get_race() == 8032 or npc.get_race() == 8033 or npc.get_race() == 8034 then
local t = number(1,4)
d.regen_file("data/dungeon/skia_boss"..t..".txt")
elseif npc.get_race() == 2493 then
notice_all(pc.get_name().." grubu, Mavi Ejderha'yı öldürdü!")
if game.get_event_flag("boss_iade") == 1 then
game.drop_item_with_ownership(30179,1)
end
d.setf("dragon_dead",1)
clear_server_timer("dragonlair_timeup",d.get_map_index())
server_timer("dragonlair_out",1*60, d.get_map_index())
d.kill_all()
end
end
end
when dragonlair_out.server_timer begin
if d.select(get_server_timer_arg()) then
d.exit_all()
end
end
when dragonlair_timeup.server_timer begin
if d.select(get_server_timer_arg()) then
d.notice("Zaman doldu.")
d.setf("sure_doldu",1)
d.exit_all()
end
end
when dragonlair_25left.server_timer begin
if d.select(get_server_timer_arg()) then
d.notice("25 dakika kaldı!")
server_timer("dragonlair_20left", 5*60, d.get_map_index())
end
end
when dragonlair_20left.server_timer begin
if d.select(get_server_timer_arg()) then
d.notice("20 dakika kaldı!")
server_timer("dragonlair_15left", 5*60, d.get_map_index())
end
end
when dragonlair_15left.server_timer begin
if d.select(get_server_timer_arg()) then
d.notice("15 dakika kaldı!")
server_timer("dragonlair_10left", 5*60, d.get_map_index())
end
end
when dragonlair_10left.server_timer begin
if d.select(get_server_timer_arg()) then
d.notice("10 dakika kaldı!")
server_timer("dragonlair_5left", 5*60, d.get_map_index())
end
end
when dragonlair_5left.server_timer begin
if d.select(get_server_timer_arg()) then
d.notice("5 dakika kaldı!")
end
end
end -- state
end[/CODE]
İyi çalışmalar dilerim.