Class for "multi quests"
Note: The code is untested (cookie for whoever tests it for me!)
Example [part of] NPC code
Now you also need to make so when you kill that rabbit and demon it will add as he's been killed. Example script for rabbit:
Functions:
What's done and what's confirmed?
When you finish a mission it's usually done. But when you go speak to the NPC he will see it as done and skip it right? So then I have this confirmed thingy, that will be set after he has done it and then spoken to NPC or whatever.
Note that this must not be used only for NPC's. You can use as talkaction/action/movement or whatever you want!
BAD: Code is untested
GOOD: Code r0x meenz
Note: The code is untested (cookie for whoever tests it for me!)
Code:
missionQuest = {}
missionQuest.__index = missionQuest
function missionQuest.new(doneStorage, confirmedStorage)
if(type(doneStorage) ~= 'number') then
return FALSE, error("missionQuest: Requiring number for 'doneStorage' (got " .. type(doneStorage) .. ")")
end
local mt = {
doneStorage = doneStorage,
confirmedStorage = confirmedStorage,
missions = {}
}
setmetatable(mt, missionQuest)
return mt
end
function missionQuest.add(name)
table.insert(self.missions, name)
_G["MISSION_" .. name:gsub(" ", "_"):upper()] = #self.missions
end
function missionQuest.check(cid, storageValue)
local flags = getPlayerStorageValue(cid, storageValue)
local found = 0
local success = TRUE
for k, name in ipairs(self.missions) do
local flag = k ^ 2
if(bit.band(flags, flag) == flag) then
found = found + 1
elseif(success == TRUE) then
success = FALSE
end
end
return success, found
end
function missionQuest.checkDone(cid)
return self:check(cid, self.doneStorage)
end
function missionQuest.checkConfirmed(cid)
return self:check(cid, self.confirmedStorage)
end
function missionQuest.has(cid, flag, storageValue)
flag = flag ^ 2
local flags = getPlayerStorageValue(cid, storageValue)
return (bit.band(flags, flag) == flag) and TRUE or FALSE
end
function missionQuest.hasDone(cid, flag)
return self:has(cid, flag, self.doneStorage)
end
function missionQuest.doneTakeItems(cid, flag, ...)
if(self:hasDone(cid, flag) == FALSE) then
return FALSE
end
for _, v in ipairs(arg) do
local count, itemid = 1
if(type(v) == 'table') then
itemid, count = unpack(v)
else
itemid = v
end
if(getPlayerItemCount(cid, itemid) < count) then
return FALSE, itemid, count
end
end
for _, v in ipairs(arg) do
local count, itemid = 1
if(type(v) == 'table') then
itemid, count = unpack(v)
else
itemid = v
end
if(isItemStackable(itemid) == TRUE) then
doPlayerRemoveItem(cid, itemid, count)
else
for i = 1, count do
doPlayerRemoveItem(cid, itemid, 1)
end
end
end
return TRUE
end
function missionQuest.hasConfirmed(cid, flag)
return self:has(cid, flag, self.confirmedStorage)
end
function missionQuest.set(cid, flag, storageValue)
local flags = getPlayerStorageValue(cid, storageValue)
setPlayerStorageValue(cid, storageValue, bit.bor(flags, flag))
end
function missionQuest.setDone(cid, flag)
self:set(cid, flag, self.doneStorage)
end
function missionQuest.setConfirmed(cid, flag)
self:set(cid, flag, self.confirmedStorage)
end
-- Simplification function for adding missions using table.
function createMission(t, doneStorage, confirmedStorage)
local missionQ = missionQuest.new(doneStorage, confirmedStorage)
for _, name in ipairs(t) do
missionQ:add(name)
end
return missionQ
end
Example [part of] NPC code
Code:
-- Would be best if this was placed in constant.lua
local missions = {
"kill the rabbit", "slay the demon", "bring the key"
}
local missionQ = createMission(t, 4353)
-- End "best in constant.lua"
if(msgcontains(msg, "quest")) then
if(missionQ:hasDone(cid, MISSION_KILL_THE_RABBIT) == FALSE) then
selfSay('Please go kill the evil rabbit located at {Demon Shire}.', cid)
elseif(missionQ:hasConfirmed(cid, MISSION_KILL_THE_RABBIT) == FALSE) then
selfSay('Thank you so much! I never liked that rabbit.', cid)
missionQ:setConfirmed(MISSION_KILL_THE_RABBIT)
elseif(missionQ:hasDone(cid, MISSION_SLAY_THE_DEMON) == FALSE) then
selfSay('Please go SLAY the Demon!', cid)
elseif(missionQ:hasConfirmed(cid, MISSION_SLAY_THE_DEMON) == FALSE) then
selfSay('Good Job!', cid)
missionQ:setConfirmed(MISSION_SLAY_THE_DEMON)
-- and so on
end
elseif(msgcontains(msg, "rabbit"))
if(missionQ:hasDone(cid, MISSION_KILL_THE_RABBIT) == FALSE) then
selfSay('Please go kill the evil rabbit located at {Demon Shire}.', cid)
elseif(missionQ:hasConfirmed(cid, MISSION_KILL_THE_RABBIT) == FALSE) then
selfSay('Thank you so much! I never liked that rabbit.', cid)
missionQ:setConfirmed(MISSION_KILL_THE_RABBIT)
else
selfSay('You already killed the Rabbit!', cid)
end
end
Now you also need to make so when you kill that rabbit and demon it will add as he's been killed. Example script for rabbit:
Code:
-- Would be best if this was placed in constant.lua
local missions = {
"kill the rabbit", "slay the demon", "bring the key"
}
local missionQ = createMission(missions, 4353)
function onDeath(cid, killer)
if(isPlayer(killer) == TRUE) then
if(missionQ:hasDone(killer, MISSION_KILL_THE_RABBIT) == FALSE) then
doPlayerSendTextMessage(killer, MESSAGE_INFO_DESCR, "Congratulations! You killed the evil rabbit.")
missionQ:setDone(killer, MISSION_KILL_THE_RABBIT)
end
end
return TRUE
end
Functions:
Code:
missionQuest.checkDone(cid) -- checks whether player has done all the missions. returns TRUE/FALSE and as second return value how many he has done.
missionQuest.checkConfirmed(cid) -- same as above, but checks if he has confirmed all missions.
missionQuest.hasDone(cid, flag) -- checks whether player has done a certain mission. returns TRUE/FALSE
missionQuest.hasConfirmed(cid, flag) -- same as above, but checks if he has confirmed a certain mission.
missionQuest.doneTakeItems(cid, flags, items) -- returns TRUE if player has done quest + has all items needed.
-- but if he has done quest but does not have required items, it will return FALSE, itemid, count of the item he did not have (will only return one, even though there could be many...)
-- example: missionQ:doneTakeItems(cid, MISSION_HELP_GEORGE, 4433, {1004, 5}, 4324, 1923, 5403, {7433, 4})
-- This would require 1x of itemid 4433, 5x of itemid 1004 etc...
missionQuest.setDone(cid, flag) -- sets a certain flag to done, so it will be classed as it has been done.
missionQuest.setConfirmed(cid, flag) -- same as above, but sets flag to confirmed.
What's done and what's confirmed?
When you finish a mission it's usually done. But when you go speak to the NPC he will see it as done and skip it right? So then I have this confirmed thingy, that will be set after he has done it and then spoken to NPC or whatever.
Note that this must not be used only for NPC's. You can use as talkaction/action/movement or whatever you want!
BAD: Code is untested
GOOD: Code r0x meenz
Last edited: