NPC "Tasker"
Witam,
Aby zrobić prostego NPC Taskowego nie potrzeba dużej znajomości języka, wystarczy trochę uwagi po pierwsze do pliku:
data/npc/scripts/lib/npc.lua dodajemy następująca treść:
Kod PHP:
function taskLoop(cid, msg, tasks, talkStages) local choice = { {id=2, sendmsgpl="Chce wybrac inne polowanie."}, {id=2, sendmsgpl="Dowidzenia."}, } local stage = getTalkStage(talkStages, cid) if(stage == "task_choice")then local lvl = getPlayerLevel(cid) local tmp_stage = {"choice_monster", {}} for i,v in pairs(tasks) do if((lvl >= v.lvl.min and lvl <= v.lvl.max) or v.lvl.always)then table.insert(choice, {id=1, sendmsgpl=i .. " {" .. v.reqcount .. "}"}) table.insert(tmp_stage[2], i) end end selfSay("Oto lista potworow na ktore mozesz zapolowac:", cid, false) Show(cid, 1, choice) setTalkStage(talkStages, cid, tmp_stage) elseif(type(stage) == "table" and stage[1] == "choice_monster")then local c = tonumber(msg) if(c ~= nil)then local name = stage[2][c] if(not name:lower():find("group"))then setPlayerStorageValue(cid, tasks[name].sv, getGlobalKilledMonsterCount(cid, name)) else for _,v in pairs(tasks[name].group) do setPlayerStorageValue(cid, v.sv, getGlobalKilledMonsterCount(cid, v.name)) end end end selfSay("Swietnie i co teraz?", cid, false) Show(cid, 2, choice) setTalkStage(talkStages, cid, "menu_back") elseif(stage == "check_task")then local state = "Stan Twoich polowan:\n" local zero = true for i,v in pairs(tasks) do if(not i:lower():find("group"))then local tmp = getPlayerStorageValue(cid, v.sv) if(tmp ~= -1)then local count = v.reqcount - (getGlobalKilledMonsterCount(cid, i) - tmp) state = state .. i .. ": " .. (count >= 0 and count or 0) zero = false end else local sum = 0 for _,w in pairs(v.group) do local tmp = getPlayerStorageValue(cid, w.sv) if(tmp ~= -1)then sum = sum + (getGlobalKilledMonsterCount(cid, w.name) - tmp) zero = false end end if(sum > 0)then state = state .. i .. ": " .. (v.reqcount - sum >= 0 and v.reqcount - sum or 0) end end end if(not zero)then selfSay(state, cid, false) Show(cid, 2, choice) setTalkStage(talkStages, cid, "menu_back") else selfSay("Jeszcze nie polujesz!", cid, false) Show(cid, 2, choice) setTalkStage(talkStages, cid, "menu_back") end elseif(stage == "complete_tasks")then local tmp_stage = {"get_rewards", {}} for i,v in pairs(tasks) do if(not i:lower():find("group"))then local tmp = getPlayerStorageValue(cid, v.sv) if(tmp ~= -1)then local count = v.reqcount - (getGlobalKilledMonsterCount(cid, i) - tmp) if(count <= 0)then table.insert(choice, {id=1, sendmsgpl=i}) table.insert(tmp_stage[2], i) end end else local sum = 0 for _,w in pairs(v.group) do local tmp = getPlayerStorageValue(cid, w.sv) if(tmp ~= -1)then sum = sum + (getGlobalKilledMonsterCount(cid, w.name) - tmp) end end if((v.reqcount - sum) <= 0)then table.insert(choice, {id=1, sendmsgpl=i}) table.insert(tmp_stage[2], i) end end end if(#tmp_stage[2] ~= 0)then selfSay("Oto lista zakonczonych polowan:", cid, false) Show(cid, 1, choice) setTalkStage(talkStages,cid, tmp_stage) else selfSay("Zadne polowanie nie zostalo zakonczone!", cid, false) Show(cid, 2, choice) setTalkStage(talkStages, cid, "menu_back") end elseif(type(stage) == "table" and stage[1] == "get_rewards")then local c = tonumber(msg) if(c ~= nil)then for i,v in pairs(tasks[stage[2][c]].rewards) do if(i == "exp")then addExperience(cid, v) elseif(i == "sv")then if(v.add ~= nil and v.add)then local tmp = getPlayerStorageValue(cid, v.id) setPlayerStorageValue(cid, v.id, (tmp == -1 and 0 or tmp) + v.count) else setPlayerStorageValue(cid, v.id, v.count) end end end end selfSay("Oto twoje nagroda!", cid, false) Show(cid, 2, choice) setTalkStage(talkStages, cid, "menu_back") end end
następne w data/npc tworzymy plik przykładowego npc powiedzmy tasker.xml:
Kod PHP:
<?xml version="1.0" encoding="UTF-8"?> <npc name="Tasker" script="npc/scripts/tasker.lua" walkinterval="2000" access="1" floorchange="0"> <health now="100" max="100"/> <look type="155" head="95" body="40" legs="21" feet="114" addons="1"/> </npc>
Następnie w data/npc/scripts tworzymy plik tasker.lua i wypełniamy go następującą treścią:
Kod PHP:
local focuses = {} local talkStages = {}
local tasks = { --WAZNE NIE ZMIENIAC KOLEJNOSCI W TABLICY. ZAWSZE DOPISYWAC NOWE QUESTY NA KONIEC ["Wolf"] = { -- to chyba jasne lecz wazna jest konstrukcja ma to dokladnie tak wygladac zmieniamy tylko tekst w "" lvl = {always=false, min=6, max=49}, -- always - czy task jest widoczny mimo levelu(true/false), min - minimalny lvl na taska, max analogicznie sv = 20000, -- SV przechowujace liczbe zabitych potworow reqcount = 300, -- wymagana ilosc potworów do zakonczenia taska rewards = { -- nagrody ["exp"] = 800, -- ilosc expa jaki otrzymamy za taska } }, ["Group Jakas"] = { -- kazda grupa w nazwie musi zawierac slowo `group` wielkosc liter nie ma zbaczenia group = { -- definicja grupy {name="Troll", sv=20001}, -- sv - SV przechowujace liczbe zabitych potworow o nazwie `name` {name="Rotworm", sv=20002}, -- j/w -- {name="i tak dalej", sv=XXXX}, }, --tutaj reszta bez zmian lvl = {always=true, min=6, max=49}, reqcount = 10, rewards = { ["exp"] = 1500, ["sv"] = {id=rank_sv, add=true, count=2} } }, }
function onCreatureSay(cid, type, msg, language) local choice = { {id=1, sendmsgpl="Tak!"}, {id=1, sendmsgpl="Moze innym razem."}, {id=2, sendmsgpl="Na co moge zapolowac?"}, {id=2, sendmsgpl="Chcialbym sprawdzic stan swoich polowan."}, {id=2, sendmsgpl="Chcialbym odebrac nagrody za polowania."}, {id=2, sendmsgpl="Wroce pozniej..."}, {id=3, sendmsgpl="Chce wybrac inne polowanie."}, {id=3, sendmsgpl="Dowidzenia."}, }
msg = string.lower(msg) local stage = getTalkStage(talkStages, cid) if (isStillSaying(cid) == 1) then return end if(getDistanceTo(cid) < 5)then if(not isFocused(focuses, cid))then if (msg == "hi" or msg == "hello") then addFocus(focuses, cid) selfSay("Witaj czy chcialbys na cos zapolowac??", cid, false) Show(cid, 1, choice) setTalkStage(talkStages, cid, "task_menu") end elseif(isFocused(focuses, cid))then if(stage == "task_menu" and msg == "1")then stage = "task_menu" end if(stage == "task_menu")then if(msg == "1")then selfSay("Dobrze wiec, opissss... :D", cid, false) Show(cid, 2, choice) setTalkStage(talkStages, cid, "task_menu_choose") elseif(msg == "2")then doEndTalk(cid, false, focuses, talkStages, special_steps, special_flags) end elseif(stage == "task_menu_choose")then if(msg == "4")then doEndTalk(cid, false, focuses, talkStages, special_steps, special_flags) return end if(msg == "1")then setTalkStage(talkStages, cid, "task_choice") elseif(msg == "2")then setTalkStage(talkStages, cid, "check_task") elseif(msg == "3")then setTalkStage(talkStages, cid, "complete_tasks") end taskLoop(cid, msg, tasks, talkStages) elseif(stage == "menu_back")then if(msg == "1")then Show(cid, 2, choice) setTalkStage(talkStages, cid, "task_menu_choose") elseif(msg == "2")then doEndTalk(cid, false, focuses, talkStages, special_steps, special_flags) end else taskLoop(cid, msg, tasks, talkStages) end end end end function onThink() -- Remember if XML File have moving = "1" add "--": -- Pamietaj gdy w pliku XML atrybut moving = "1" komentowaæ poni¿sze warunki warunek: if #focuses == 0 then if isMoving() > 0 then startMoving() end return end -------------------------------------------------------------------------------- for i, cid in pairs(focuses) do local distance = getDistanceTo(cid) or -1 if distance > 4 or distance == -1 then doEndTalk(cid, false, focuses, talkStages) end end end function onThingMove(cid, pos) end function onCreatureAppear(cid) end function onPlayerEndTrade(cid) end
function onPlayerCloseChannel(cid) if isFocused(focuses, cid) then doEndTalk(cid, false, focuses, talkStages) end end
function onCreatureDisappear(cid, pos) if isFocused(focuses, cid) then doEndTalk(cid, false, focuses, talkStages) end end
Teraz przystępujemy do konfiguracji zawartej w tablicy tasks, opatrzyłem ją dość dobrze komentarzami która linia co znaczy, aby dodać nowego taska po prostu kopiujemy poprzedniego i odpowiednio wyedytowujemy zgodnie z komentarzami zawartymi po podwójnym myślniku( -- ), w razie problemów proszę o kontakt.
Pozdrawiam.
|