Action Hermes' powerful quest system, LUA. Tutorial included.

Discussion in 'Actions, MoveEvents & TalkActions' started by Hermes, Feb 10, 2010.

Thread Status:
Not open for further replies.
  1. Hermes

    Hermes dziwki kola gramy w lola

    Joined:
    Nov 17, 2007
    Messages:
    1,867
    thank you, I won't release anything again
     
    Last edited: Feb 21, 2010
  2. Ldrozd

    Ldrozd Piszę skrypty w zeszycie.

    Joined:
    Dec 13, 2008
    Messages:
    429
    awesome :w00t:
     
  3. Szakal

    Szakal Frank Jaeger

    Joined:
    Apr 16, 2008
    Messages:
    1,337
    Nice work Hermes , you own.

    :D
     
  4. zakius

    zakius Enter the Ninja!

    Joined:
    Apr 30, 2009
    Messages:
    2,630
    Actually for just one chest quests I preffer default system(less writing for me, mapper have to care about it:D)
    if you could integrate it with old one(like:if aid == 2000 use old system, else use new one, not hard but useful[no need of rewriting all existing chests, easy quest are 100% made by mapper etc and you still have power of the new system])
     
  5. Hermes

    Hermes dziwki kola gramy w lola

    Joined:
    Nov 17, 2007
    Messages:
    1,867
    Well, you can use just:
    Code:
    [UID] = {itemReward = {id, 1}}
    It's better to have less scripts (chest scripts) for even advanced quests.
     
  6. zakius

    zakius Enter the Ninja!

    Joined:
    Apr 30, 2009
    Messages:
    2,630
    yeah, I know, you wanted suggestions right? ;d
    I like it for advanced quests, but writing all chests here can take some time(I don't have many of them on map, but some poeple can have a lot of)

    I mean sth like
    Code:
    function onUse(cid, item, fromPosition, itemEx, toPosition)
    	if item.actionid == 2000 then
    		storage = item.uid
    		if(storage > 65535) then
    			return false
    		end
    		if(getPlayerStorageValue(cid, storage) > 0) then
    			doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "It is empty.")
    			return true
    		end
    		local items = {}
    		local reward = 0
    		local size = isContainer(item.uid) and getContainerSize(item.uid) or 0
    		if(size == 0) then
    			reward = doCopyItem(item, false)
    		else
    			for i = 0, size do
    				local tmp = getContainerItem(item.uid, i)
    				if(tmp.itemid > 0) then
    					table.insert(items, tmp)
    				end
    			end
    		end
    		size = table.maxn(items)
    		if(size == 1) then
    			reward = doCopyItem(items[1], true)
    		end
    		local result = ""
    		if(reward ~= 0) then
    			local ret = getItemDescriptions(reward.uid)
    			if(reward.type > 0 and isItemRune(reward.itemid)) then
    				result = reward.type .. " charges " .. ret.name
    			elseif(reward.type > 0 and isItemStackable(reward.itemid)) then
    				result = reward.type .. " " .. ret.plural
    			else
    				result = ret.article .. " " .. ret.name
    			end
    		else
    			if(size > 20) then
    				reward = doCopyItem(item, false)
    			elseif(size > 8) then
    				reward = getThing(doCreateItemEx(1988, 1))
    			else
    				reward = getThing(doCreateItemEx(1987, 1))
    			end
    			for i = 1, size do
    				local tmp = doCopyItem(items[i], true)
    				if(doAddContainerItemEx(reward.uid, tmp.uid) ~= RETURNVALUE_NOERROR) then
    					print("[Warning] QuestSystem:", "Could not add quest reward")
    				else
    					local ret = ", "
    					if(i == 2) then
    						ret = " and "
    					elseif(i == 1) then
    						ret = ""
    					end
    					result = result .. ret
    					ret = getItemDescriptions(tmp.uid)
    					if(tmp.type > 0 and isItemRune(tmp.itemid)) then
    						result = result .. tmp.type .. " charges " .. ret.name
    					elseif(tmp.type > 0 and isItemStackable(tmp.itemid)) then
    						result = result .. tmp.type .. " " .. ret.plural
    					else
    						result = result .. ret.article .. " " .. ret.name
    					end
    				end
    			end
    		end
    		if(doPlayerAddItemEx(cid, reward.uid, false) ~= RETURNVALUE_NOERROR) then
    			result = "You have found a reward weighing " .. getItemWeight(reward.uid) .. " oz. It is too heavy or you have not enough space."
    		else
    			result = "You have found " .. result .. "."
    			setPlayerStorageValue(cid, storage, 1)
    			if(questsExperience[storage] ~= nil) then
    				doPlayerAddExp(cid, questsExperience[storage])
    				doSendAnimatedText(getCreaturePosition(cid), questsExperience[storage], TEXTCOLOR_WHITE)
    			end
    		end
    		doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, result)
    	else
    
            --CREDITS: HERMES :* :* :*
            --TODO: Check space in player backpack before giving reward.
            --              "customMessage" parameter, ability to set own message like "You've got access to X."
            --              support for multiple containers, to handle more than 20 slots
            --              support for stackable items, it's concerned with this /\
            --BTW. DO NOT mess with the script unless you know what you're doing.
           
            local QUESTSYSTEM_LIST = {
            --[UNIQUE_ID] = {itemReward = {ITEM1, ITEM1_COUNT, ITEM2, ITEM2_COUNT...}, containerId = CUSTOM_CONTAINER_ID, experience = EXPERIENCE, neededLevel = LEVEL_TO_OPEN_CHEST, neededStorage = {STORAGE_TO_OPEN, VALUE}, setStorage = {SET_CUSTOM_STORAGE, VALUE}}
                    --let's fill one table using all parameters we can
                    [12345] = {itemReward = {2160, 10, 2195, 2}, containerId = 1990, experience = 2000, neededLevel = 10, neededStorage = {12345, 5}, setStorage = {12345, 6}},
                    --this one will work too
                    [12346] = {experience = 1000},
                    --same as this
                    [12347] = {itemReward = {2160, 2}, setStorage = {12345, 5}, neededStorage = {12345, -1}}
            }
    
            local QS_ALLOW_GM, QS_TOTAL_WEIGHT, QS_CONTAINER, QUEST = true, 0, 1988, QUESTSYSTEM_LIST[item.uid]
            local QS_MSG = {TOO_HEAVY = {"You have found something weighing ", " oz, it's too heavy."}, LEVEL_TOO_LOW = {"You need to have ", " level in order to open this chest."}, IT_IS_EMPTY = "It is empty."}
            local message = function (cid, m)
                    return doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, m)
            end
            if not QUEST or item.uid == 0 or (getPlayerCustomFlagValue(cid, PLAYERCUSTOMFLAG_GAMEMASTERPRIVILEGES) and not QS_ALLOW_GM) then
                    return false
            end
            if(QUEST.neededStorage and type(QUEST.neededStorage) == "table" and #QUEST.neededStorage == 2 and getPlayerStorageValue(cid, QUEST.neededStorage[1]) ~= QUEST.neededStorage[2]) or getPlayerStorageValue(cid, QUEST.uniqueId) == 1 then
                    message(cid, QS_MSG.IT_IS_EMPTY)
                    return true
            end
            if QUEST.neededLevel and getPlayerLevel(cid) < QUEST.neededLevel then
                    message(cid, QS_MSG.LEVEL_TOO_LOW[1] .. QUEST.neededLevel .. QS_MSG.LEVEL_TOO_LOW[2])
                    return true
            end
            if QUEST.containerId then
                    QS_CONTAINER = QUEST.containerId
            end
            if QUEST.itemReward and type(QUEST.itemReward) == "table" and #QUEST.itemReward % 2 == 0 and #QUEST.itemReward < 40 then
                    if #QUEST.itemReward == 2 then
                            QS_TOTAL_WEIGHT = getItemWeightById(QUEST.itemReward[1], QUEST.itemReward[2], false)
                            if getPlayerFreeCap(cid) < QS_TOTAL_WEIGHT then
                                    message(cid, QS_MSG.TOO_HEAVY[1] .. QS_TOTAL_WEIGHT .. QS_MSG.TOO_HEAVY[2])
                            else
                                    doPlayerAddItem(cid, QUEST.itemReward[1], QUEST.itemReward[2])
                                    message(cid, "You have found " .. QUEST.itemReward[2] .. " " .. getItemNameById(QUEST.itemReward[1]) .. ".")
                            end
                    elseif #QUEST.itemReward > 2 then
                            tmp = 1
                            while tmp < #QUEST.itemReward do
                                    QS_TOTAL_WEIGHT = QS_TOTAL_WEIGHT + getItemWeightById(QUEST.itemReward[tmp], QUEST.itemReward[tmp+1], false)
                                    tmp = tmp + 2
                            end
                            if getPlayerFreeCap(cid) < QS_TOTAL_WEIGHT + getItemWeightById(QS_CONTAINER) then
                                    message(cid, QS_MSG.TOO_HEAVY[1] .. QS_TOTAL_WEIGHT .. QS_MSG.TOO_HEAVY[2])
                            else
                                    local bp = doPlayerAddItem(cid, QS_CONTAINER, 1)
                                    tmp = 1
                                    while tmp + 1 <= #QUEST.itemReward do
                                            doAddContainerItem(bp, QUEST.itemReward[tmp], QUEST.itemReward[tmp+1])
                                            tmp = tmp + 2
                                    end
                                    message(cid, "You have found " .. getItemArticleById(QS_CONTAINER) .. " " .. getItemNameById(QS_CONTAINER) .. ".")
                            end
                    end
            elseif QUEST.experience and QUEST.experience > 0 then
                    doPlayerAddExp(cid, QUEST.experience)
                    doSendAnimatedText(fromPosition, QUEST.experience, 215)
            elseif QUEST.setStorage and type(QUEST.setStorage) == "table" and #QUEST.setStorage == 2 then
                    setPlayerStorageValue(cid, QUEST.setStorage[1], QUEST.setStorage[2])
            elseif not QUEST.setStorage then
                    setPlayerStorageValue(cid, QUEST.uniqueId, 1)
            end
    		end
            return true
    end 
    not tested, but should work


    hmm, your way(parameter onMap) will still need adding quest to script right?
    its the thing that I want to exclude from my serv

    But go ahead, its your script so do it how you like :D
     
    Last edited: Feb 11, 2010
  7. Hermes

    Hermes dziwki kola gramy w lola

    Joined:
    Nov 17, 2007
    Messages:
    1,867
    Oh, I will consider merging questsystems so you can use only parameter onMap = {true, type = uniqueIdReward/copyItem}. But it's a bit difficult :p
     
  8. Zlorek

    Zlorek New Member

    Joined:
    Apr 14, 2008
    Messages:
    2
    Hermes Nup <Blain Here> ;>>
     
  9. Colandus

    Colandus Ådministrator

    Joined:
    Jun 6, 2007
    Messages:
    2,247
    "great", "cool", "awesome", "OMG ROX"

    but unfortunately nobody will use 'em :( yes it's pleasant to read those comments, to know that people respect your work... i've lived that life, but in fact it's pretty damn pointless because none uses it !!

    now im not saying ur system is bad, it's good... but none will use it!!
     
  10. Snow

    Snow Member

    Joined:
    Jan 16, 2008
    Messages:
    379
    looks nice, too bad I don't know who to really make it useful :(
     
  11. Hermes

    Hermes dziwki kola gramy w lola

    Joined:
    Nov 17, 2007
    Messages:
    1,867
    Okay, from now I won't release anything. Thank you for your appreciation... -.-
     
Thread Status:
Not open for further replies.

Share This Page