• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!
  • New resources must be posted under Resources tab. A discussion thread will be created automatically, you can't open threads manually anymore.

CreatureEvent NPC Grizzly Adams - almost how RL Tibia.

Hmm...

#Tastertur
Go to data/lib/50-function.lua and find 708 line and paste here.

#Dankoo
I'll fix it in near futher. Don't worry.

#Maraths
Send me your npc.lua and 50-function.lua.
 
I got it work but the questlog doesn't work :S I get these errors when I compile...
Code:
In member function 'std::string Mission::getDescription(Player*)': 
77  invalid conversion from 'int' to 'const char*' 
77 initializing argument 1 of 'std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, const _Alloc&) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]' 
97 invalid conversion from 'int' to 'const char*' 
97 initializing argument 1 of 'std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, const _Alloc&) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]' 
121 invalid conversion from 'int' to 'const char*' 
121 initializing argument 1 of 'std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, const _Alloc&) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]' 
121 *** [obj//quests.o] Error 1

this is my quests.cpp
PHP:
////////////////////////////////////////////////////////////////////////
// OpenTibia - an opensource roleplaying game
////////////////////////////////////////////////////////////////////////
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
////////////////////////////////////////////////////////////////////////
#include "otpch.h"

#include "quests.h"
#include "tools.h"

bool Mission::isStarted(Player* player)
{
        if(!player)
                return false;

        std::string value;
        player->getStorage(storageId, value);
        return atoi(value.c_str()) >= startValue;
}

bool Mission::isCompleted(Player* player)
{
        if(!player)
                return false;

        std::string value;
        player->getStorage(storageId, value);
        return atoi(value.c_str()) >= endValue;
}

std::string Mission::parseStorages(std::string state, std::string value)
{
        /*std::string::size_type start, end;
        while((start = state.find("|STORAGE:")) != std::string::npos)
        {
                if((end = state.find("|", start)) = std::string::npos)
                        continue;

                std::string value, storage = state.substr(start, end - start)
                player->getStorage(storage, value);
                state.replace(start, end, value);
        } requires testing and probably fixing, inspired by QuaS code*/

        replaceString(state, "|STATE|", value);
        return state;
}

std::string Mission::getDescription(Player* player)
{
    std::string value;
    int32_t find_storage;
    player->getStorage(storageId, value);
    if(state.size())
    {
        std::string ret = state;
        while((find_storage=ret.find("|STORAGE:"))>-1)
        {
              int32_t parsing_storage = find_storage+9;
              std::string temp;
              while((int) ret[parsing_storage] != (int)'|')
              {
                   temp += ret[parsing_storage];
                   parsing_storage++;
              }
              parsing_storage -=find_storage-1;
              player->getStorage(atoi(temp.c_str()), temp);
              ret.replace(find_storage, parsing_storage, temp);
        }
        replaceString(ret, "|STATE|", value);
        return ret;
    }

    if(atoi(value.c_str()) >= endValue)
    {
        std::string ret = states.rbegin()->second;
        while((find_storage=ret.find("|STORAGE:"))>-1)
        {
              int32_t parsing_storage = find_storage+9;
              std::string temp;
              while((int) ret[parsing_storage] != (int)'|')
              {
                   temp += ret[parsing_storage];
                   parsing_storage++;
              }
              parsing_storage -=find_storage-1;
              player->getStorage(atoi(temp.c_str()), temp);
              ret.replace(find_storage, parsing_storage, temp);
        }
        replaceString(ret, "|STATE|", value);
        return ret;
    }

    for(int32_t i = endValue; i >= startValue; --i)
    {
        player->getStorage(storageId, value);
        if(atoi(value.c_str()) != i)
            continue;

        std::string ret = states[i - startValue];
        while((find_storage=ret.find("|STORAGE:"))>-1)
        {
              int32_t parsing_storage = find_storage+9;
              std::string temp;
              while((int) ret[parsing_storage] != (int)'|')
              {
                   temp += ret[parsing_storage];
                   parsing_storage++;
              }
              parsing_storage -=find_storage-1;
              player->getStorage(atoi(temp.c_str()), temp);
              ret.replace(find_storage, parsing_storage, temp);
        }
        replaceString(ret, "|STATE|", value);
        return ret;

    }

    return "Couldn't retrieve any mission description, please report to a gamemaster.";
}  

Quest::~Quest()
{
        for(MissionList::iterator it = missions.begin(); it != missions.end(); it++)
                delete (*it);

        missions.clear();
}

bool Quest::isStarted(Player* player)
{
        if(!player)
                return false;

        std::string value;
        player->getStorage(storageId, value);
        return atoi(value.c_str()) >= storageValue;
}

bool Quest::isCompleted(Player* player) const
{
        for(MissionList::const_iterator it = missions.begin(); it != missions.end(); it++)
        {
                if(!(*it)->isCompleted(player))
                        return false;
        }

        return true;
}

uint16_t Quest::getMissionCount(Player* player)
{
        uint16_t count = 0;
        for(MissionList::iterator it = missions.begin(); it != missions.end(); it++)
        {
                if((*it)->isStarted(player))
                        count++;
        }

        return count;
}

void Quests::clear()
{
        for(QuestList::iterator it = quests.begin(); it != quests.end(); it++)
                delete (*it);

        quests.clear();
}

bool Quests::reload()
{
        clear();
        return loadFromXml();
}

bool Quests::loadFromXml()
{
        xmlDocPtr doc = xmlParseFile(getFilePath(FILE_TYPE_XML, "quests.xml").c_str());
        if(!doc)
        {
                std::clog << "[Warning - Quests::loadFromXml] Cannot load quests file." << std::endl;
                std::clog << getLastXMLError() << std::endl;
                return false;
        }

        xmlNodePtr p, root = xmlDocGetRootElement(doc);
        if(xmlStrcmp(root->name,(const xmlChar*)"quests"))
        {
                std::clog << "[Error - Quests::loadFromXml] Malformed quests file." << std::endl;
                xmlFreeDoc(doc);
                return false;
        }

        p = root->children;
        while(p)
        {
                parseQuestNode(p, false);
                p = p->next;
        }

        xmlFreeDoc(doc);
        return true;
}

bool Quests::parseQuestNode(xmlNodePtr p, bool checkDuplicate)
{
        if(xmlStrcmp(p->name, (const xmlChar*)"quest"))
                return false;

        int32_t intValue;
        std::string strValue;

        uint32_t id = m_lastId;
        if(readXMLInteger(p, "id", intValue) && id > 0)
        {
                id = intValue;
                if(id > m_lastId)
                        m_lastId = id;
        }

        std::string name;
        if(readXMLString(p, "name", strValue))
                name = strValue;

        std::string startStorageId;
        if(readXMLString(p, "startstorageid", strValue) || readXMLString(p, "storageId", strValue))
                startStorageId = strValue;

        int32_t startStorageValue = 0;
        if(readXMLInteger(p, "startstoragevalue", intValue) || readXMLInteger(p, "storageValue", intValue))
                startStorageValue = intValue;

        Quest* quest = new Quest(name, id, startStorageId, startStorageValue);
        if(!quest)
                return false;

        for(xmlNodePtr missionNode = p->children; missionNode; missionNode = missionNode->next)
        {
                if(xmlStrcmp(missionNode->name, (const xmlChar*)"mission"))
                        continue;

                std::string missionName, missionState, storageId;
                if(readXMLString(missionNode, "name", strValue))
                        missionName = strValue;

                if(readXMLString(missionNode, "state", strValue) || readXMLString(missionNode, "description", strValue))
                        missionState = strValue;

                if(readXMLString(missionNode, "storageid", strValue) || readXMLString(missionNode, "storageId", strValue))
                        storageId = strValue;

                int32_t startValue = 0, endValue = 0;
                if(readXMLInteger(missionNode, "startvalue", intValue) || readXMLInteger(missionNode, "startValue", intValue))
                        startValue = intValue;

                if(readXMLInteger(missionNode, "endvalue", intValue) || readXMLInteger(missionNode, "endValue", intValue))
                        endValue = intValue;

                if(Mission* mission = new Mission(missionName, missionState, storageId, startValue, endValue))
                {
                        if(missionState.empty())
                        {
                                // parse sub-states only if main is not set
                                for(xmlNodePtr stateNode = missionNode->children; stateNode; stateNode = stateNode->next)
                                {
                                        if(xmlStrcmp(stateNode->name, (const xmlChar*)"missionstate"))
                                                continue;

                                        uint32_t missionId;
                                        if(!readXMLInteger(stateNode, "id", intValue))
                                        {
                                                std::clog << "[Warning - Quests::parseQuestNode] Missing missionId for mission state" << std::endl;
                                                continue;
                                        }

                                        missionId = intValue;
                                        std::string description;
                                        if(readXMLString(stateNode, "description", strValue))
                                                description = strValue;

                                        mission->newState(missionId, description);
                                }
                        }

                        quest->newMission(mission);
                }
        }

        if(checkDuplicate)
        {
                for(QuestList::iterator it = quests.begin(); it != quests.end(); ++it)
                {
                        if((*it)->getName() == name)
                                delete *it;
                }
        }

        m_lastId++;
        quests.push_back(quest);
        return true;
}

uint16_t Quests::getQuestCount(Player* player)
{
        uint16_t count = 0;
        for(QuestList::iterator it = quests.begin(); it != quests.end(); it++)
        {
                if((*it)->isStarted(player))
                        count++;
        }

        return count;
}

Quest* Quests::getQuestById(uint16_t id) const
{
        for(QuestList::const_iterator it = quests.begin(); it != quests.end(); it++)
        {
                if((*it)->getId() == id)
                        return (*it);
        }

        return NULL;
}

using 0.3.6 pl1

thanks in advance (Y)
 
One thing, how do I add a new task?

Look:

Lua:
			[19] = {name = "barbarians", storage = 9980, expe = "yes", how_many = 15000,
					begin_storage_value = 40, finish_storage_value = 41, boss = "yes",
					before_kill_boss = 38, after_kill_boss = 39, talkstate = 19},

I've taken new storages values for everything, following the logics of the script. I've done the same at creaturescripts, and added this to the script too:

Lua:
elseif tasks[i].name == "barbarians" then
				doNPCTalkALot({"message '-'"},cid, 200)

when I say hi>task>barbarians, nothing happens.

Does it have something to do with the tasks? like, 19 is a invalid number? should I change it?
 
Dude, take a look:

I have replaced the whole code:

Lua:
std::string Mission::getDescription(Player* player)
{
	std::string value;
	player->getStorage(storageId, value);
	if(state.size())
		return parseStorages(state, value);

	if(atoi(value.c_str()) >= endValue)
		return parseStorages(states.rbegin()->second, value);

	for(int32_t i = endValue; i >= startValue; --i)
	{
		player->getStorage(storageId, value);
		if(atoi(value.c_str()) == i)
			return parseStorages(states[i - startValue], value);
	}

	return "Couldn't retrieve any mission description, please report to a gamemaster.";
}

With the code you've posted, but I receive this error:

59076317.jpg


Any ideas? Using REV 3884
 
dankoo i changed

doNPCTalkALot(cid, 200, {"message"})
to
doNPCTalkALot({"message"},cid, 200)
and dont work i receive the message

[07/11/2010 21:46:15] [Error - LuaScriptInterface::loadFile] data/npc/scripts/Grizzly Adams.lua:96: unexpected symbol near ')'
[07/11/2010 21:46:15] [Warning - NpcScript::NpcScript] Cannot load script: data/npc/scripts/Grizzly Adams.lua
[07/11/2010 21:46:15] data/npc/scripts/Grizzly Adams.lua:96: unexpected symbol near ')'


the line 96 is
doNPCTalkALot({"message"},cid, 200) {"You bought "..amount.." "..items[item].realName.." for "..items[item].buyPrice * amount.." gold coins."})
 
the same problem, danko speak to change doNPCTalkALot(cid, 200, {"message"}) to doNPCTalkALot({"message"},cid, 200) in grizzly adams.lua npc but for me dont work =[
 
lol by "message" it was suppose to be the content of the line, like this example:

What you have done:
Lua:
doNPCTalkALot({"message"},cid, 200) {"You bought "..amount.." "..items[item].realName.." for "..items[item].buyPrice * amount.." gold coins."})

Correct:
Lua:
doNPCTalkALot({"You bought "..amount.." "..items[item].realName.." for "..items[item].buyPrice * amount.." gold coins."},cid, 200))
 
i gat this error


dude, do as I said, just read the previous posts and you will find the solution
PS: at least it worked for me, I don't have the lib code here, I'm using the laptop, my OT is in another computer... I'll post it here later if it would be any useful... But the code Oskar posted I think it's the same as the mine
 
edit
working now!
i just removed the last character.

the post

doNPCTalkALot({"You bought "..amount.." "..items[item].realName.." for "..items[item].buyPrice * amount.." gold coins."},cid, 200))

the correct

doNPCTalkALot({"You bought "..amount.." "..items[item].realName.." for "..items[item].buyPrice * amount.." gold coins."},cid, 200)


Thank you very much
 
Last edited:
try

doNPCTalkALot({"You bought "..amount.." "..items[item].realName.." for "..items[item].buyPrice * amount.." gold coins."},200,cid)
 
I can't get it work. I get this error if I say "task" I added 'doNPCTALKALOT' in 050-function.lua

PHP:
function doCreatureSayWithDelay(cid,text,type,delay,e,pcid)
	if delay<=0 then
		doCreatureSay(cid,text,type, false,pcid)
	else
		local func=function(pars)
			doCreatureSay(pars.cid,pars.text,pars.type, false,pars.pcid)
			pars.e.done=TRUE
		end
		e.done=FALSE
		e.event=addEvent(func,delay,{cid=cid, text=text, type=type, e=e,pcid=pcid})
	end
end
 
function doNPCTalkALot(msgs,interval,pcid)
	local e={}
	local ret={}
	if interval==nil then interval=3000 end --10 seconds is default time between messages
		for aux=1,table.getn(msgs) do
		e[aux]={}
		doCreatureSayWithDelay(getNpcCid(),msgs[aux],TALKTYPE_PRIVATE_NP,(aux-1)*interval,e[aux],pcid)
		table.insert(ret,e[aux])
	end
	return(ret)
end


Code:
[14:26:25.918] [Error - NpcScript Interface]
[14:26:25.923] data/npc/scripts/Grizzly Adams.lua:onCreatureSay
[14:26:25.925] Description:
[14:26:25.927] data/lib/050-function.lua:708: bad argument #1 to 'getn' (table e
xpected, got number)
[14:26:25.931] stack traceback:
[14:26:25.933]  [C]: in function 'getn'
[14:26:25.935]  data/lib/050-function.lua:708: in function 'doNPCTalkALot'
[14:26:25.937]  data/npc/scripts/Grizzly Adams.lua:269: in function 'callback'
[14:26:25.940]  data/npc/lib/npcsystem/npchandler.lua:423: in function 'onCreatu
reSay'
[14:26:25.942]  data/npc/scripts/Grizzly Adams.lua:13: in function <data/npc/scr
ipts/Grizzly Adams.lua:13>

This is my Grizzly Adams.lua in npc/scripts...

PHP:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)
local talkState = {}
function onCreatureAppear(cid)			npcHandler:onCreatureAppear(cid)			end
function onCreatureDisappear(cid)		npcHandler:onCreatureDisappear(cid)			end
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)
local talkState = {}
function onCreatureAppear(cid)                          npcHandler:onCreatureAppear(cid)                        end
function onCreatureDisappear(cid)                       npcHandler:onCreatureDisappear(cid)                     end
function onCreatureSay(cid, type, msg)                  npcHandler:onCreatureSay(cid, type, msg)                end
function onThink()                                      npcHandler:onThink()									end
function creatureSayCallback(cid, type, msg)
        if(not npcHandler:isFocused(cid)) then
                return false
        end
local storages = {
				main_storage = 10001,
				points_storage = 10002,
				bosses_storage = 10003,
				promote_storage = 10004,
				demodras_storage = 10005,
				tiquandas_revenge_storage = 10006,
				demons_storage = 10007
				}
for i = 19970, 19999 do
	if getPlayerStorageValue(cid, i) == -1 then
		doPlayerSetStorageValue(cid, i, 0)
	end
end
local mainStorage = getPlayerStorageValue(cid, storages.main_storage)
local bossStorages = getPlayerStorageValue(cid, storages.bosses_storage)
local points = getPlayerStorageValue(cid, storages.points_storage)
local promote = getPlayerStorageValue(cid, storages.promote_storage)
local talkUser = NPCHANDLER_CONVBEHAVIOR == CONVERSATION_DEFAULT and 0 or cid
if promote == -1 then
	promote = 0
end
if points == -1 then
	points = 0
end
local good_hunting = {"Happy hunting, old chap! Come back to me when you are through with your {task}.", "Good show, old chap! Speak to me again when you are done hunting."}	
local good_job = {"That took some time, huh? Good hunting though. If you're up for another hunting mission just ask me for a {task}.", "If you're up for another hunting mission just ask me for a {task}."}
local huntsMan_rank = {
					{id=11208, buy=0, sell=50, name="antlers"},
					{id=10549, buy=0, sell=100, name="bloody pincers"},
					{id=11183, buy=0, sell=35, name="crab pincers"},
					{id=10573, buy=0, sell=55, name="cyclops toe"},
					{id=10564, buy=0, sell=30, name="frosty ear of a troll"},
					{id=11193, buy=0, sell=600, name="hydra head"},
					{id=11366, buy=0, sell=80, name="lancer beetle shell"},
					{id=10578, buy=0, sell=420, name="mutated bat ear"},
					{id=11222, buy=0, sell=400, name="sabretooth"},
					{id=11367, buy=0, sell=20, name="sandcrawler shell"},
					{id=10547, buy=0, sell=280, name="scarab pincers"},
					{id=11365, buy=0, sell=60, name="terramite legs"},
					{id=11363, buy=0, sell=170, name="terramite shell"},
					{id=11184, buy=0, sell=30000, name="terrorbird beak"},
					
					{id=7398, buy=0, sell=500, name="cyclops trophy"},
					{id=7401, buy=0, sell=500, name="minotaur trophy"}
					}

local bigGameHunter_rank = {
					{id=7397, buy=0, sell=3000, name="deer trophy"},
					{id=7400, buy=0, sell=3000, name="lion trophy"},
					{id=7394, buy=0, sell=3000, name="wolf trophy"}
					}
for k,v in pairs(huntsMan_rank) do
	table.insert(bigGameHunter_rank, k, v)
end

local trophyHunter_rank = {
					{id=7396, buy=0, sell=20000, name="behemoth trophy"},
					{id=7393, buy=0, sell=40000, name="demon trophy"},
					{id=7399, buy=0, sell=10000, name="dragon lord trophy"},
					
					{id=10518, buy=1000, sell=0, name="demon backpack"}
					}
for k,v in pairs(bigGameHunter_rank) do
	table.insert(trophyHunter_rank, k, v)
end

local items = {}
for _, item in ipairs(huntsMan_rank) do
	items[item.id] = {storage = item.storage, item_id = item.id, buyPrice = item.buy, sellPrice = item.sell, subType = 0, realName = item.name}
end

local items = {}
for _, item in ipairs(bigGameHunter_rank) do
	items[item.id] = {storage = item.storage, item_id = item.id, buyPrice = item.buy, sellPrice = item.sell, subType = 0, realName = item.name}
end

local items = {}
for _, item in ipairs(trophyHunter_rank) do
	items[item.id] = {storage = item.storage, item_id = item.id, buyPrice = item.buy, sellPrice = item.sell, subType = 0, realName = item.name}
end

local onBuy = function(cid, item, subType, amount, ignoreCap, inBackpacks)
	if items[item].buyPrice ~= 0 then
		doPlayerRemoveMoney(cid, amount * items[item].buyPrice)
		for i = 1, amount do
			doPlayerAddItem(cid, items[item].item_id, amount)
		end
		doNPCTalkALot(cid, 200, {"You bought "..amount.." "..items[item].realName.." for "..items[item].buyPrice * amount.." gold coins."})
	end
end
 
local onSell = function(cid, item, subType, amount, ignoreCap, inBackpacks)
	if items[item].sellPrice ~= 0 then
		doPlayerAddMoney(cid, items[item].sellPrice * amount)
		doPlayerRemoveItem(cid, items[item].item_id, amount)
		doNPCTalkALot(cid, 200, {"You sell "..amount.." "..items[item].realName.." for "..items[item].sellPrice * amount.." gold coins."})
	end
end
local tasks = {
			--level 5-49--
			[1] = {name = "carniphilas", storage = 9999, expe = "yes", how_many = 1500,
					begin_storage_value = 1, finish_storage_value = 2, talkstate = 1},
			[2] = {name = "crocodiles", storage = 9998, expe = "yes", how_many = 800,
					begin_storage_value = 3, finish_storage_value = 4, boss = "yes",
					before_kill_boss = 1, after_kill_boss = 2, talkstate = 2},
			[3] = {name = "tarantulas", storage = 9997, expe = "yes", how_many = 1500,
					begin_storage_value = 5, finish_storage_value = 6, boss = "yes",
					before_kill_boss = 3, after_kill_boss = 4, talkstate = 3},
			[4] = {name = "stone golems", storage = 9996, expe = "yes", how_many = 2000,
					begin_storage_value = 7, finish_storage_value = 8, talkstate = 4},
			[5] = {name = "mammoths", storage = 9995, expe = "yes", how_many = 4000,
					begin_storage_value = 9, finish_storage_value = 10, boss = "yes",
					before_kill_boss = 5, after_kill_boss = 6, talkstate = 5},
			--level 50-89--
			[6] = {name = "ice golems", storage = 9994, expe = "yes", how_many = 15000,
					begin_storage_value = 11, finish_storage_value = 12, boss = "yes",
					before_kill_boss = 7, after_kill_boss = 8, talkstate = 6},
			[7] = {name = "quaras", talkstate = 49},
			[8] = {name = "elementals", talkstate = 48},
			
			[9] = {name = "mutated rats", storage = 9987, expe = "yes", how_many = 10000,
					begin_storage_value = 13, finish_storage_value = 14, boss = "yes",
					before_kill_boss = 9, after_kill_boss = 10, talkstate = 7},
			[10] = {name = "giant spiders", storage = 9986, expe = "yes", how_many = 5000,
					begin_storage_value = 15, finish_storage_value = 16, boss = "yes",
					before_kill_boss = 11, after_kill_boss = 12, talkstate = 8},
			--level 90+ --
			[11] = {name = "hydras", storage = 9985,
					begin_storage_value = 17, finish_storage_value = 18, boss = "yes",
					before_kill_boss = 13, after_kill_boss = 14, talkstate = 9},
			[12] = {name = "sea serpents", storage = 9984,
					begin_storage_value = 19, finish_storage_value = 20, boss = "yes",
					before_kill_boss = 15, after_kill_boss = 16, talkstate = 10},
			[13] = {name = "behemoths", storage = 9983,
					begin_storage_value = 21, finish_storage_value = 22, boss = "yes",
					before_kill_boss = 17, after_kill_boss = 18, talkstate = 11},
			[14] = {name = "serpent spawns", storage = 9982,
					begin_storage_value = 23, finish_storage_value = 24, boss = "yes",
					before_kill_boss = 19, after_kill_boss = 20, talkstate = 12}
			}
local others_tasks = {
			--quaras--
			[1] = {name = "quaras", storage = 9992, expe = "yes", how_many = 12000,
					begin_storage_value = 24, finish_storage_value = 25, boss = "yes",
					before_kill_boss = 21, after_kill_boss = 22, talkstate = 13},
			[2] = {name = "quara scouts", storage = 9993, expe = "yes", how_many = 10000,
					begin_storage_value = 26, finish_storage_value = 27, talkstate = 14},
			--elementals--
			[3] = {name = "fire", storage = 9991, expe = "yes", how_many = 7000,
					begin_storage_value = 28, finish_storage_value = 29, talkstate = 15},
			[4] = {name = "water", storage = 9990, expe = "yes", how_many = 7000,
					begin_storage_value = 30, finish_storage_value = 31, talkstate = 16},
			[5] = {name = "earth", storage = 9989, expe = "yes", how_many = 10000,
					begin_storage_value = 32, finish_storage_value = 33, talkstate = 17},
			[6] = {name = "energy", storage = 9988, expe = "yes", how_many = 10000,
					begin_storage_value = 34, finish_storage_value = 35, talkstate = 18}
			}
local rank = {
			[1] = {need_points = 5, name = "Huntsman", storage_value = 0, talkstate = 50},
			[2] = {need_points = 10, name = "Ranger", storage_value = 1, talkstate = 51},
			[3] = {need_points = 20, name = "Big Game Hunter", storage_value = 2, talkstate = 52},
			[4] = {need_points = 30, name = "Trophy Hunter", storage_value = 3, talkstate = 53},
			[5] = {need_points = 50, name = "Elite Hunter", storage_value = 4, talkstate = 54}
			}
local promotion = {
				[1] = {talktype = 50, how_many_exp = 5000, finish_storage_values = 1},
				[2] = {talktype = 51, how_many_exp = 8000, finish_storage_values = 2},
				[3] = {talktype = 52, how_many_exp = 10000, finish_storage_values = 3},
				[4] = {talktype = 53, how_many_exp = 15000, item = "yes", what = 10518, count = 1, finish_storage_values = 4},
				[5] = {talktype = 54, how_many_exp = 30000, finish_storage_values = 5}
				}
if msgcontains(msg, 'special task') then
	if promote == 5 then
		if getPlayerLevel(cid) >= 90 then
			if getPlayerStorageValue(cid, storages.tiquandas_revenge_storage) == -1 then
				doNPCTalkALot(cid, 200, {"Have you heared about Tiquandas Revenge? It is said that the jungle itself is alive and takes revenge for all the bad things people have done to it. ..."})
				doNPCTalkALot(cid, 10000, {"I myself believe that there is some truth in this clap trap. Something 'real' which therefore must have a hideout somewhere. Go find it and take revenge yourself! Ask me about the special task when you're done."})
				doPlayerSetStorageValue(cid, storages.tiquandas_revenge_storage, 0)
				return true
			elseif getPlayerStorageValue(cid, storages.tiquandas_revenge_storage) == 1 then
				doNPCTalkALot(cid, 200, {"Great accievement, old chap! You are an outstanding hunter, no doubt about it!"})
				doPlayerSetStorageValue(cid, storages.tiquandas_revenge_storage, 2)
				return true
			end
		else
			doNPCTalkALot(cid, 200, {"You are an eager one. Your rank within our hunting elite is great buuuut I believe you're a little inexperienced for the special tasks. Gain more experience and then you will be equal to the special task! I don't want to send you to your death!"})
		end
		if getPlayerLevel(cid) >= 100 then
			if getPlayerStorageValue(cid, storages.tiquandas_revenge_storage) == 2 then
				if getPlayerStorageValue(cid, storages.demodras_storage) == -1 then
					doNPCTalkALot(cid, 200, {"Go kill Demodras."})
					doPlayerSetStorageValue(cid, storages.demodras_storage, 0)
				elseif getPlayerStorageValue(cid, storages.demodras_storage) == 1 then
					doNPCTalkALot(cid, 200, {"Good job."})
					doPlayerSetStorageValue(cid, storages.demodras_storage, 2)
				end
			end
			if getPlayerStorageValue(cid, storages.demodras_storage) == 2 then
				if getPlayerStorageValue(cid, storages.demons_storage) == -1 then
					doNPCTalkALot(cid, 200, {"Go kill 6666 Demons."})
					doPlayerSetStorageValue(cid, storages.demons_storage, 0)
					doPlayerSetStorageValue(cid, 9981, 0)
					doPlayerSetStorageValue(cid, storages.main_storage, 36)
				elseif getPlayerStorageValue(cid, storages.demons_storage) == 1 and getPlayerStorageValue(cid, storages.main_storage) == 37 then
					doNPCTalkALot(cid, 200, {"Amazing! You kill all 6666 dmeons!"})
					doPlayerSetStorageValue(cid, storages.demons_storage, 2)
					doPlayerSetStorageValue(cid, storages.main_storage, 0)
				end
			end
		else
			doNPCTalkALot(cid, 200, {"You are an eager one. Your rank within our hunting elite is great buuuut I believe you're a little inexperienced for the special tasks. Gain more experience and then you will be equal to the special task! I don't want to send you to your death!"})
		end
	end
elseif msgcontains(msg, 'trade') or msgcontains(msg, 'offer') then
	if isInArray({1,2,3,4,5}, promote) then
		if isInArray({1,2}, promote) then
			openShopWindow(cid, huntsMan_rank, onBuy, onSell)
		elseif isInArray({3}, promote) then
			openShopWindow(cid, bigGameHunter_rank, onBuy, onSell)
		elseif isInArray({4,5}, promote) then
			openShopWindow(cid, trophyHunter_rank, onBuy, onSell)
		end
		doNPCTalkALot(cid, 200, {"It's my offer."})
	else
		doNPCTalkALot(cid, 200, {"You don't have any rank."})
	end
elseif msgcontains(msg, 'cancel') then
	if (mainStorage > 0 or bossStorages > 0) then
		if isInArray({36,37}, mainStorage) == false then
			doNPCTalkALot(cid, 200, {"Do you want cancel actual mission?"})
			talkState[talkUser] = 103
		else
			doNPCTalkALot(cid, 200, {"You killed "..getPlayerStorageValue(cid, 9981).." of 6666 Demons."})
			return true
		end
	else
		doNPCTalkALot(cid, 200, {"You do not started any {task}."})
		return true
	end
elseif msgcontains(msg, 'yes') and talkState[talkUser] == 103 then
	doNPCTalkALot(cid, 200, {"Speak to me again when you are done hunting."})
	doPlayerSetStorageValue(cid, storages.main_storage, 0)
	doPlayerSetStorageValue(cid, storages.bosses_storage, -1)
	for i = 19970, 19999 do
		if getPlayerStorageValue(cid, i) ~= -1 then
			doPlayerSetStorageValue(cid, i, 0)
		end
	end
	for k,v in pairs(tasks) do
		if isInArray({0,1}, getPlayerStorageValue(cid, v.storage)) then
			doPlayerSetStorageValue(cid, v.storage, -1)
		end
	end
elseif msgcontains(msg, 'task') then
	if isInArray({-1,0}, mainStorage) and bossStorages == -1 then 
		if mainStorage == -1 then
			mainStorage = 0
		end
		if (getPlayerLevel(cid) > 5 and getPlayerLevel(cid) < 50) then
			doNPCTalkALot(cid, 200, {"All right, what would you like to hunt? {Crocodiles}, {tarantulas}, {carniphilas}, {stone golems} or {mammoths}?"})
			talkState[talkUser] = 100
		elseif (getPlayerLevel(cid) > 49 and getPlayerLevel(cid) < 90) then
			doNPCTalkALot(cid, 200, {"All right, what would you like to hunt? {Ice golems}, {quara}, {elementals}, {mutated rats} or {giant spiders}?"})
			talkState[talkUser] = 101
		elseif (getPlayerLevel(cid) > 89) then
			doNPCTalkALot(cid, 200, {"All right, what would you like to hunt? {Hydras}, {sea serpents}, {behemoths} or {serpent spawns}?"})
			talkState[talkUser] = 102
		end
	end
end

for i = 1, #tasks do
	if msgcontains(msg, tasks[i].name) then
		if talkState[talkUser] == 100 then
			if tasks[i].name == "carniphilas" then
				doNPCTalkALot(cid, 200, {"Damn walking weed-thingies! You'll find them deeper in the jungle. Weed out {150 "..tasks[i].name.."} for our society. Alright?"})
			elseif tasks[i].name == "crocodiles" then
				doNPCTalkALot(cid, 200, {"They are a nuisance! You'll find them here in the jungle near the river. Hunt {300 "..tasks[i].name.."} and you'll get a nice reward. Interested?"})
			elseif tasks[i].name == "tarantulas" then
				doNPCTalkALot(cid, 200, {"Do you want kill {300 tarantulas?}"})
			elseif tasks[i].name == "stone golems" then
				doNPCTalkALot(cid, 200, {"They can be found all over Tibia. You'll find them in mountain caves or rocky dungeons. Hunt {200} of them and come back to me. Understood?"})
			elseif tasks[i].name == "mammoths" then
				doNPCTalkALot(cid, 200, {"This particular species are found in Svargrond. Impressive beasts, but you wouldn't want one in your back garden. Hunt {300} of them. Alright?"})
			end
		elseif talkState[talkUser] == 101 then
			if tasks[i].name == "ice golems" then
				doNPCTalkALot(cid, 200, {"The ice golems on the glacier of Hrodmir are becoming a threat to the civilians in Svargrond. Travel to the Ice Islands and hunt {300 "..tasks[i].name.."}. Do you accept this task?"})
			elseif tasks[i].name == "quara" then
				doNPCTalkALot(cid, 200, {"What do you want, {quaras} or {quara scouts?}"})
			elseif tasks[i].name == "elementals" then
				doNPCTalkALot(cid, 200, {"What do you want, {fire}, {water}, {earth} or {energy?}"})
			elseif tasks[i].name == "mutated rats" then
				doNPCTalkALot(cid, 200, {"Recently, I heard of a disturbing development in Yalahar - a plague of monstrous Mutated rats! If they were to spread to the rest of Tibia.. <shudders> My task for you is to contain their numbers in Yalahar. Hunt {200} of them. What do you say?"})
			elseif tasks[i].name == "giant spiders" then
				doNPCTalkALot(cid, 200, {"Never liked spiders. Entirely too many legs. And I always find them in my bath! Those nasty creepy crawlies are a threat to the hygiene of every living being in Tibia. Hunt {500} of them. Okay?"})
			end
		elseif talkState[talkUser] == 102 then
			if tasks[i].name == "hydras" then
				doNPCTalkALot(cid, 200, {"Do you want kill {2000 "..tasks[i].name.."?}"})
			elseif tasks[i].name == "sea serpents" then
				doNPCTalkALot(cid, 200, {"Do you want kill {2000 "..tasks[i].name.."?}"})
			elseif tasks[i].name == "behemoths" then
				doNPCTalkALot(cid, 200, {"Do you want kill {2000 "..tasks[i].name.."?}"})
			elseif tasks[i].name == "serpent spawns" then
				doNPCTalkALot(cid, 200, {"Do you want kill {1500 "..tasks[i].name.."?}"})
			end
		end	
		talkState[talkUser] = tasks[i].talkstate
	elseif msgcontains(msg, 'yes') and talkState[talkUser] == tasks[i].talkstate and isInArray({-1,0}, mainStorage) then
		doPlayerSetStorageValue(cid, storages.main_storage, tasks[i].begin_storage_value)
		doNPCTalkALot(cid, 200, {good_hunting[math.random(1, #good_hunting)]})
		doPlayerSetStorageValue(cid, tasks[i].storage, 0)
		return true
	elseif msgcontains(msg, 'task') then
		if mainStorage == tasks[i].finish_storage_value and bossStorages == -1 then
			if tasks[i].boss == "yes" then
				doNPCTalkALot(cid, 200, {"Good job, go kill boss."})
				doPlayerSetStorageValue(cid, storages.bosses_storage, tasks[i].before_kill_boss)
				doPlayerSetStorageValue(cid, tasks[i].storage, 2)
				return true
			else
				doPlayerSetStorageValue(cid, storages.main_storage, 0)
				doPlayerSetStorageValue(cid, tasks[i].storage, -1)
				doNPCTalkALot(cid, 200, {good_job[math.random(1, #good_job)]})
				if tasks[i].expe == "yes" then
					doPlayerAddExp(cid, tasks[i].how_many)
					doSendAnimatedText(getPlayerPosition(cid), tasks[i].how_many, TEXTCOLOR_WHITE)
				end
				return true
			end
		elseif bossStorages == tasks[i].after_kill_boss then
			doPlayerSetStorageValue(cid, storages.main_storage, 0)
			doPlayerSetStorageValue(cid, storages.bosses_storage, -1)
			doNPCTalkALot(cid, 200, {good_job[math.random(1, #good_job)]})
			return true
		elseif  mainStorage == 36 then
			doNPCTalkALot(cid, 200, {"You killed "..getPlayerStorageValue(cid, 9981).." of 6666 Demons."})
			return true
		elseif isInArray(tasks[i].before_kill_boss, bossStorages) then
			doNPCTalkALot(cid, 200, {"You do not kill boss yet."})
		end
	elseif msgcontains(msg, 'no') and isInArray({i,15,16,17,18,48,49,50,51,52,53,54,100,101,102,103}, talkState[talkUser]) then 
		doNPCTalkALot(cid, 200, {"Ok then."})
	end
end

for i = 1, #others_tasks do
	if msgcontains(msg, others_tasks[i].name) then
		if talkState[talkUser] == 49 then
			if others_tasks[i].name == "quaras" then
				doNPCTalkALot(cid, 200, {"Do you want kill {300 quaras?}"})
			elseif others_tasks[i].name == "quara scouts" then
				doNPCTalkALot(cid, 200, {"Do you want kill {300 quara scouts?}"})
			end
		elseif talkState[talkUser] == 48 then
			if others_tasks[i].name == "fire" then
				doNPCTalkALot(cid, 200, {"Don't get burnt! Your challenge, should you choose to accept it, is to kill {70 fire elementals or massive fire elementals}. Are you ready?"})
			elseif others_tasks[i].name == "water" then
				doNPCTalkALot(cid, 200, {"Alright, go hunt {70 water elementals or massive water elementals}. Don't forget your umbrella! Alright?"})
			elseif others_tasks[i].name == "earth" then
				doNPCTalkALot(cid, 200, {"Good choice! I need you to slay {70 earth elementals or massive earth elementals}. There are some in the so called Taboo-area in the eastern jungle of Tiquanda and I heard about a cave in Edron where you'll find them. Are you game?"})
			elseif others_tasks[i].name == "energy" then
				doNPCTalkALot(cid, 200, {"A brave hunter! Kill {70 energy elementals or massive energy elementals}. You'll find them in the mountains between Darama and Tiquanda. Are you sure you want to do this?"})
			end
		end
		talkState[talkUser] = others_tasks[i].talkstate
	elseif msgcontains(msg, 'yes') and talkState[talkUser] == others_tasks[i].talkstate and isInArray({-1,0}, mainStorage) then
		doPlayerSetStorageValue(cid, storages.main_storage, others_tasks[i].begin_storage_value)
		doNPCTalkALot(cid, 200, {good_hunting[math.random(1, #good_hunting)]})
		if getPlayerStorageValue(cid, others_tasks[i].storage) < 0 then
			doPlayerSetStorageValue(cid, others_tasks[i].storage, 0)
		end
	elseif msgcontains(msg, 'task') then
		if mainStorage == others_tasks[i].finish_storage_value and bossStorages == -1 then
			if others_tasks[i].boss == "yes" then
				doPlayerSetStorageValue(cid, storages.main_storage, others_tasks[i].before_kill_boss)
			else 
				doPlayerSetStorageValue(cid, storages.main_storage, 0)
				doPlayerSetStorageValue(cid, others_tasks[i].storage, -1)
				doNPCTalkALot(cid, 200, {good_job[math.random(1, #good_job)]})
					if others_tasks[i].expe == "yes" then
						doPlayerAddExp(cid, others_tasks[i].how_many)
						doSendAnimatedText(getPlayerPosition(cid), others_tasks[i].how_many, TEXTCOLOR_WHITE)
					end
			end
		elseif getStorage == others_tasks[i].after_kill_boss then
			doPlayerSetStorageValue(cid, storages.main_storage, 0)
			doPlayerSetStorageValue(cid, others_tasks[i].storage, -1)
			doNPCTalkALot(cid, 200, {good_job[math.random(1, #good_job)]})
		elseif isInArray(tasks[i].begin_storage_value, mainStorage) then
			s = "You killed "
			for k,v in pairs(other_tasks) do
				if getPlayerStorageValue(cid, v.storage) >= 0 then
					count = getPlayerStorageValue(cid, v.storage)
					s = s ..count.." "..v.name.."."
				end
			end
			doNPCTalkALot(cid, 200, {s})
		elseif isInArray(others_tasks[i].before_kill_boss, bossStorages) then
			doNPCTalkALot(cid, 200, {"You do not kill boss yet."})
		end
	end
end

for i = 1, #rank do
	if msgcontains(msg, 'rank') then
		if points >= rank[i].need_points then
			if promote == rank[i].storage_value then
				if rank[i].need_points >= 5 and promote == 0 then
					doNPCTalkALot(cid, 200, {"Welcome back "..getCreatureName(cid)..". You have completed 5 tasks for our society. Ask me for a {promotion} to advance your rank!"})
				elseif rank[i].need_points >= 10 and promote == 1 then
					doNPCTalkALot(cid, 200, {"Welcome back "..getCreatureName(cid)..". You have completed 10 tasks for our society. Ask me for a {promotion} to advance your rank!"})
				elseif rank[i].need_points >= 20 and promote == 2 then
					doNPCTalkALot(cid, 200, {"Salutations "..getCreatureName(cid)..". You have completed 20 tasks for our society. Ask me for a {promotion} to advance your rank!"})
				elseif rank[i].need_points >= 30 and promote == 3 then
					doNPCTalkALot(cid, 200, {"Welcome back "..getCreatureName(cid)..". You have completed 30 tasks for our society. Ask me for a {promotion} to advance your rank!"})
				elseif rank[i].need_points == 50 and promote == 4 then
					doNPCTalkALot(cid, 200, {"By the gods....50 hunting tasks....this is austoding! Ask me for a {promotion} to advance your rank! And while you are here, I also have another special task for you."})
				end
				talkState[talkUser] = rank[i].talkstate
				return true
			end
		elseif points <= rank[i].need_points then
			if isInArray({-1,0}, promote) then
				doNPCTalkALot(cid, 200, {"You don't have any rank. You have "..points.." points. On next level you need "..rank[i].need_points - points.." points."})
			else
				doNPCTalkALot(cid, 200, {"Your actualy rank is "..rank[i-1].name..". You have "..points.." points. On next level you need "..rank[i].need_points - points.." points."})
			end
			return true
		end
	end
end
for i = 1, #promotion do
	if msgcontains(msg, 'promotion') then
		if talkState[talkUser] == promotion[i].talktype then
			if promote == promotion[i].finish_storage_values - 1 then
				doPlayerAddExp(cid, promotion[i].how_many_exp)
				doSendAnimatedText(getPlayerPosition(cid), promotion[i].how_many_exp, TEXTCOLOR_WHITE)
				doPlayerSetStorageValue(cid, storages.promote_storage, promotion[i].finish_storage_values)
					if talkState[talkUser] == 50 then
						doNPCTalkALot(cid, 200, {"You have completed 5 tasks! Let me promote you to the first rank: {Huntsman}. Congratulations! ..."})
						doNPCTalkALot(cid, 10000, {"If you find any trophies that you don't need, feel free to ask me for a {trade}."})
					elseif talkState[talkUser] == 51 then
						doNPCTalkALot(cid, 200, {"You have completed 10 hunting tasks. It's time for a promotion. You advance to the rank of {Ranger}. Congratulations! ..."})
						doNPCTalkALot(cid, 10000, {"Oh, I made a deal with Lorek. He ships Rangers from our society - and higher ranks of course - to Banuta, Chor or near the mountain pass to Darama. Just ask him for a passage."})
					elseif talkState[talkUser] == 52 then
						doNPCTalkALot(cid, 200, {"Good show! You have completed 20 hunting tasks for the 'Paw and Fur - Hunting Elite. You have earned the right to join the ranks of those known as {Big game} {hunter}. Congratulations! ..."})
						doNPCTalkALot(cid, 10000, {"From now on I'll buy more trophies from you!"})
					elseif talkState[talkUser] == 53 then
						doNPCTalkALot(cid, 200, {"Spiffing! You have done 30 hunting tasks! From now on you can call yourself a {Trophy hunter}. As a reward I have this special backpack for you and in addition you can sell some more rare trophies to me."})
					elseif talkState[talkUser] == 54 then
						doNPCTalkALot(cid, 200, {"Congratulations! You have made the highest rank: {Elite hunter}. If haven't yet done so ask me for the {special task}."})
							if promotion[i].item == "yes" then
								doPlayerAddItem(cid, promotion[i].what, promotion[i].count)
							end
					end
			end
		end
	end
end
return true
end
npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())

bump.. ;/
 
Delete this function with 50-function.lua and paste into npc.lua.

It's my 50-function.lua file:
PHP:
function doPlayerGiveItem(cid, itemid, amount, subType)
	local item = 0
	if(isItemStackable(itemid)) then
		item = doCreateItemEx(itemid, amount)
		if(doPlayerAddItemEx(cid, item, true) ~= RETURNVALUE_NOERROR) then
			return false
		end
	else
		for i = 1, amount do
			item = doCreateItemEx(itemid, subType)
			if(doPlayerAddItemEx(cid, item, true) ~= RETURNVALUE_NOERROR) then
				return false
			end
		end
	end

	return true
end

function doPlayerGiveItemContainer(cid, containerid, itemid, amount, subType)
	for i = 1, amount do
		local container = doCreateItemEx(containerid, 1)
		for x = 1, getContainerCapById(containerid) do
			doAddContainerItem(container, itemid, subType)
		end

		if(doPlayerAddItemEx(cid, container, true) ~= RETURNVALUE_NOERROR) then
			return false
		end
	end

	return true
end

function doPlayerTakeItem(cid, itemid, amount)
	return getPlayerItemCount(cid, itemid) >= amount and doPlayerRemoveItem(cid, itemid, amount)
end

function doPlayerBuyItem(cid, itemid, count, cost, charges)
	return doPlayerRemoveMoney(cid, cost) and doPlayerGiveItem(cid, itemid, count, charges)
end

function doPlayerBuyItemContainer(cid, containerid, itemid, count, cost, charges)
	return doPlayerRemoveMoney(cid, cost) and doPlayerGiveItemContainer(cid, containerid, itemid, count, charges)
end

function doPlayerSellItem(cid, itemid, count, cost)
	if(not doPlayerTakeItem(cid, itemid, count)) then
		return false
	end

	if(not doPlayerAddMoney(cid, cost)) then
		error('[doPlayerSellItem] Could not add money to: ' .. getPlayerName(cid) .. ' (' .. cost .. 'gp).')
	end

	return true
end

function doPlayerWithdrawMoney(cid, amount)
	if(not getBooleanFromString(getConfigInfo('bankSystem'))) then
		return false
	end

	local balance = getPlayerBalance(cid)
	if(amount > balance or not doPlayerAddMoney(cid, amount)) then
		return false
	end

	doPlayerSetBalance(cid, balance - amount)
	return true
end

function doPlayerDepositMoney(cid, amount)
	if(not getBooleanFromString(getConfigInfo('bankSystem'))) then
		return false
	end

	if(not doPlayerRemoveMoney(cid, amount)) then
		return false
	end

	doPlayerSetBalance(cid, getPlayerBalance(cid) + amount)
	return true
end

function isPremium(cid)
	return (isPlayer(cid) and (getPlayerPremiumDays(cid) > 0 or getBooleanFromString(getConfigInfo('freePremium'))))
end

function getMonthDayEnding(day)
	if(day == "01" or day == "21" or day == "31") then
		return "st"
	elseif(day == "02" or day == "22") then
		return "nd"
	elseif(day == "03" or day == "23") then
		return "rd"
	end

	return "th"
end

function getMonthString(m)
	return os.date("%B", os.time{year = 1970, month = m, day = 1})
end

function getArticle(str)
	return str:find("[AaEeIiOoUuYy]") == 1 and "an" or "a"
end

function isNumber(str)
	return tonumber(str) ~= nil
end

function doPlayerAddAddons(cid, addon)
	for i = 0, table.maxn(maleOutfits) do
		doPlayerAddOutfit(cid, maleOutfits[i], addon)
	end

	for i = 0, table.maxn(femaleOutfits) do
		doPlayerAddOutfit(cid, femaleOutfits[i], addon)
	end
end

function doPlayerWithdrawAllMoney(cid)
	return doPlayerWithdrawMoney(cid, getPlayerBalance(cid))
end

function doPlayerDepositAllMoney(cid)
	return doPlayerDepositMoney(cid, getPlayerMoney(cid))
end

function doPlayerTransferAllMoneyTo(cid, target)
	return doPlayerTransferMoneyTo(cid, target, getPlayerBalance(cid))
end

function playerExists(name)
	return getPlayerGUIDByName(name) ~= 0
end

function getTibiaTime()
	local minutes = getWorldTime()
	local hours = 0
	while (minutes > 60) do
		hours = hours + 1
		minutes = minutes - 60
	end

	return {hours = hours, minutes = minutes}
end

function doWriteLogFile(file, text)
	local f = io.open(file, "a+")
	if(not f) then
		return false
	end

	f:write("[" .. os.date("%d/%m/%Y %H:%M:%S") .. "] " .. text .. "\n")
	f:close()
	return true
end

function getExperienceForLevel(lv)
	lv = lv - 1
	return ((50 * lv * lv * lv) - (150 * lv * lv) + (400 * lv)) / 3
end

function doMutePlayer(cid, time)
	local condition = createConditionObject(CONDITION_MUTED)
	setConditionParam(condition, CONDITION_PARAM_TICKS, time * 1000)
	return doAddCondition(cid, condition)
end

function getPlayerGroupName(cid)
	return getGroupInfo(getPlayerGroupId(cid)).name
end

function getPlayerVocationName(cid)
	return getVocationInfo(getPlayerVocation(cid)).name
end

function getPromotedVocation(vid)
	return getVocationInfo(vid).promotedVocation
end

function doPlayerRemovePremiumDays(cid, days)
	return doPlayerAddPremiumDays(cid, -days)
end

function getPlayerMasterPos(cid)
	return getTownTemplePosition(getPlayerTown(cid))
end

function getHouseOwner(houseId)
	return getHouseInfo(houseId).owner
end

function getHouseName(houseId)
	return getHouseInfo(houseId).name
end

function getHouseEntry(houseId)
	return getHouseInfo(houseId).entry
end

function getHouseRent(houseId)
	return getHouseInfo(houseId).rent
end

function getHousePrice(houseId)
	return getHouseInfo(houseId).price
end

function getHouseTown(houseId)
	return getHouseInfo(houseId).town
end

function getHouseTilesCount(houseId)
	return getHouseInfo(houseId).tiles
end

function getItemNameById(itemid)
	return getItemDescriptionsById(itemid).name
end

function getItemPluralNameById(itemid)
	return getItemDescriptionsById(itemid).plural
end

function getItemArticleById(itemid)
	return getItemDescriptionsById(itemid).article
end

function getItemName(uid)
	return getItemDescriptions(uid).name
end

function getItemPluralName(uid)
	return getItemDescriptions(uid).plural
end

function getItemArticle(uid)
	return getItemDescriptions(uid).article
end

function getItemText(uid)
	return getItemDescriptions(uid).text
end

function getItemSpecialDescription(uid)
	return getItemDescriptions(uid).special
end

function getItemWriter(uid)
	return getItemDescriptions(uid).writer
end

function getItemDate(uid)
	return getItemDescriptions(uid).date
end

function getTilePzInfo(pos)
	return getTileInfo(pos).protection
end

function getTileZoneInfo(pos)
	local tmp = getTileInfo(pos)
	if(tmp.pvp) then
		return 2
	end

	if(tmp.nopvp) then
		return 1
	end

	return 0
end

function doShutdown()
	return doSetGameState(GAMESTATE_SHUTDOWN)
end

function doSummonCreature(name, pos, displayError)
	local displayError, cid = displayError or true, doCreateMonster(name, pos, displayError)
	if(not cid) then
		cid = doCreateNpc(name, pos, displayError)
	end

	return cid
end

function getOnlinePlayers()
	local tmp = getPlayersOnline()
	local players = {}
	for i, cid in ipairs(tmp) do
		table.insert(players, getCreatureName(cid))
	end

	return players
end

function getPlayerByName(name)
	local cid = getCreatureByName(name)
	return isPlayer(cid) and cid or nil
end

function isPlayer(cid)
	return isCreature(cid) and cid >= AUTOID_PLAYERS and cid < AUTOID_MONSTERS
end

function isPlayerGhost(cid)
	if(not isPlayer(cid)) then
		return false
	end

	return getCreatureCondition(cid, CONDITION_GAMEMASTER, GAMEMASTER_INVISIBLE) or getPlayerFlagValue(cid, PLAYERFLAG_CANNOTBESEEN)
end

function isMonster(cid)
	return isCreature(cid) and cid >= AUTOID_MONSTERS and cid < AUTOID_NPCS
end

function isNpc(cid)
	return isCreature(cid) and cid >= AUTOID_NPCS
end

function doPlayerSetExperienceRate(cid, value)
	return doPlayerSetRate(cid, SKILL__LEVEL, value)
end

function doPlayerSetMagicRate(cid, value)
	return doPlayerSetRate(cid, SKILL__MAGLEVEL, value)
end

function doPlayerAddLevel(cid, amount, round)
	local experience, level = 0, getPlayerLevel(cid)
	if(amount > 0) then
		experience = getExperienceForLevel(level + amount) - (round and getPlayerExperience(cid) or getExperienceForLevel(level))
	else
		experience = -((round and getPlayerExperience(cid) or getExperienceForLevel(level)) - getExperienceForLevel(level + amount))
	end

	return doPlayerAddExperience(cid, experience)
end

function doPlayerAddMagLevel(cid, amount)
	for i = 1, amount do
		doPlayerAddSpentMana(cid, (getPlayerRequiredMana(cid, getPlayerMagLevel(cid, true) + 1) - getPlayerSpentMana(cid)) / getConfigInfo('rateMagic'))
	end
	return true
end  

function doPlayerAddSkill(cid, skill, amount, round)
	if(skill == SKILL__LEVEL) then
		return doPlayerAddLevel(cid, amount, round)
	elseif(skill == SKILL__MAGLEVEL) then
		return doPlayerAddMagLevel(cid, amount)
	end

	return doPlayerAddSkillTry(cid, skill, (getPlayerRequiredSkillTries(cid, skill, getPlayerSkillLevel(cid, skill) + 1) - getPlayerSkillTries(cid, skill)) / getConfigInfo('rateSkill'))
end

function getPartyLeader(cid)
	local party = getPartyMembers(cid)
	if(type(party) ~= 'table') then
		return 0
	end

	return party[1]
end

function isInParty(cid)
	return type(getPartyMembers(cid)) == 'table'
end

function isPrivateChannel(channelId)
	return channelId >= CHANNEL_PRIVATE
end

function doPlayerResetIdleTime(cid)
	return doPlayerSetIdleTime(cid, 0)
end

function doBroadcastMessage(text, class)
	local class = class or MESSAGE_STATUS_WARNING
	if(type(class) == 'string') then
		local className = MESSAGE_TYPES[class]
		if(className == nil) then
			return false
		end

		class = className
	elseif(class < MESSAGE_FIRST or class > MESSAGE_LAST) then
		return false
	end

	local players = getPlayersOnline()
	for _, pid in ipairs(players) do
		doPlayerSendTextMessage(pid, class, text)
	end

	print("> Broadcasted message: \"" .. text .. "\".")
	return true
end

function doPlayerBroadcastMessage(cid, text, class, checkFlag, ghost)
	local checkFlag, ghost, class = checkFlag or true, ghost or false, class or TALKTYPE_BROADCAST
	if(checkFlag and not getPlayerFlagValue(cid, PLAYERFLAG_CANBROADCAST)) then
		return false
	end

	if(type(class) == 'string') then
		local className = TALKTYPE_TYPES[class]
		if(className == nil) then
			return false
		end

		class = className
	elseif(class < TALKTYPE_FIRST or class > TALKTYPE_LAST) then
		return false
	end

	local players = getPlayersOnline()
	for _, pid in ipairs(players) do
		doCreatureSay(cid, text, class, ghost, pid)
	end

	print("> " .. getCreatureName(cid) .. " broadcasted message: \"" .. text .. "\".")
	return true
end

function getBooleanFromString(input)
	local tmp = type(input)
	if(tmp == 'boolean') then
		return input
	end

	if(tmp == 'number') then
		return input > 0
	end

	local str = string.lower(tostring(input))
	return (str == "yes" or str == "true" or (tonumber(str) ~= nil and tonumber(str) > 0))
end

function doCopyItem(item, attributes)
	local attributes = attributes or false

	local ret = doCreateItemEx(item.itemid, item.type)
	if(attributes) then
		if(item.actionid > 0) then
			doItemSetAttribute(ret, "aid", item.actionid)
		end
	end

	if(isContainer(item.uid)) then
		for i = (getContainerSize(item.uid) - 1), 0, -1 do
			local tmp = getContainerItem(item.uid, i)
			if(tmp.itemid > 0) then
				doAddContainerItemEx(ret, doCopyItem(tmp, true).uid)
			end
		end
	end

	return getThing(ret)
end

function doRemoveThing(uid)
	if(isCreature(uid)) then
		return doRemoveCreature(uid)
	end

	return doRemoveItem(uid)
end

function setAttackFormula(combat, type, minl, maxl, minm, maxm, min, max)
	local min, max = min or 0, max or 0
	return setCombatFormula(combat, type, -1, 0, -1, 0, minl, maxl, minm, maxm, min, max)
end

function setHealingFormula(combat, type, minl, maxl, minm, maxm, min, max)
	local min, max = min or 0, max or 0
	return setCombatFormula(combat, type, 1, 0, 1, 0, minl, maxl, minm, maxm, min, max)
end

function doChangeTypeItem(uid, subtype)
	local thing = getThing(uid)
	if(thing.itemid < 100) then
		return false
	end

	local subtype = subtype or 1
	return doTransformItem(thing.uid, thing.itemid, subtype)
end

function doSetItemText(uid, text, writer, date)
	local thing = getThing(uid)
	if(thing.itemid < 100) then
		return false
	end

	doItemSetAttribute(uid, "text", text)
	if(writer ~= nil) then
		doItemSetAttribute(uid, "writer", tostring(writer))
		if(date ~= nil) then
			doItemSetAttribute(uid, "date", tonumber(date))
		end
	end

	return true
end

function getFluidSourceType(itemid)
	local item = getItemInfo(itemid)
	return item and item.fluidSource or false
end

function getDepotId(uid)
	return getItemAttribute(uid, "depotid") or false
end

function getItemDescriptions(uid)
	local thing = getThing(uid)
	if(thing.itemid < 100) then
		return false
	end

	local item = getItemInfo(thing.itemid)
	return {
		name = getItemAttribute(uid, "name") or item.name,
		plural = getItemAttribute(uid, "pluralname") or item.plural,
		article = getItemAttribute(uid, "article") or item.article,
		special = getItemAttribute(uid, "description") or "",
		text = getItemAttribute(uid, "text") or "",
		writer = getItemAttribute(uid, "writer") or "",
		date = getItemAttribute(uid, "date") or 0
	}	
end

function getItemWeightById(itemid, count, precision)
	local item, count, precision = getItemInfo(itemid), count or 1, precision or false
	if(not item) then
		return false
	end

	if(count > 100) then
		-- print a warning, as its impossible to have more than 100 stackable items without "cheating" the count
		print('[Warning] getItemWeightById', 'Calculating weight for more than 100 items!')
	end

	local weight = item.weight * count
	--[[if(precision) then
		return weight
	end

	local t = string.explode(tostring(weight), ".")
	if(table.maxn(t) == 2) then
		return tonumber(t[1] .. "." .. string.sub(t[2], 1, 2))
	end]]--

	return weight
end

function getItemWeaponType(uid)
	local thing = getThing(uid)
	if(thing.itemid < 100) then
		return false
	end

	return getItemInfo(thing.itemid).weaponType
end

function getItemRWInfo(uid)
	local thing = getThing(uid)
	if(thing.itemid < 100) then
		return false
	end

	local item, flags = getItemInfo(thing.itemid), 0
	if(item.readable) then
		flags = 1
	end

	if(item.writable) then
		flags = flags + 2
	end

	return flags
end

function getItemLevelDoor(itemid)
	local item = getItemInfo(itemid)
	return item and item.levelDoor or false
end

function isItemStackable(itemid)
	local item = getItemInfo(itemid)
	return item and item.stackable or false
end

function isItemRune(itemid)
	local item = getItemInfo(itemid)
	return item and item.clientCharges or false
end

function isItemDoor(itemid)
	local item = getItemInfo(itemid)
	return item and item.type == 5 or false
end

function isItemContainer(itemid)
	local item = getItemInfo(itemid)
	return item and item.group == 2 or false
end

function isItemFluidContainer(itemid)
	local item = getItemInfo(itemid)
	return item and item.group == 12 or false
end

function isItemMovable(itemid)
	local item = getItemInfo(itemid)
	return item and item.movable or false
end

function isCorpse(uid)
	local thing = getThing(uid)
	if(thing.itemid < 100) then
		return false
	end

	local item = getItemInfo(thing.itemid)
	return item and item.corpseType ~= 0 or false
end

function getContainerCapById(itemid)
	local item = getItemInfo(itemid)
	if(not item or item.group ~= 2) then
		return false
	end

	return item.maxItems
end

function getMonsterAttackSpells(name)
	local monster = getMonsterInfo(name)
	return monster and monster.attacks or false
end

function getMonsterHealingSpells(name)
	local monster = getMonsterInfo(name)
	return monster and monster.defenses or false
end

function getMonsterLootList(name)
	local monster = getMonsterInfo(name)
	return monster and monster.loot or false
end

function getMonsterSummonList(name)
	local monster = getMonsterInfo(name)
	return monster and monster.summons or false
end

function checkForwardPos(cid)
 pos = getCreaturePosition(cid)
 if getCreatureLookDirection(cid) == NORTH then
  pos.y = pos.y - 1
 elseif getCreatureLookDirection(cid) == SOUTH then
  pos.y = pos.y + 1
 elseif getCreatureLookDirection(cid) == WEST then
  pos.x = pos.x - 1
 elseif getCreatureLookDirection(cid) == EAST then
  pos.x = pos.x + 1
 end
 return pos
end

function isNear (cid, key, dist, value)
local pos=getCreaturePosition(cid)
local players = getPlayersOnline()
local areaPosition =
{
        {x=pos.x-dist, y=pos.y-dist, z=pos.z, stackpos = 255},
        {x=pos.x+dist, y=pos.y+dist, z=pos.z, stackpos = 255}
}
 
if key == "item" then
   for i=1, 255 do
	for areax = (pos.x - dist), (pos.x + dist) do
		for areay = (pos.y - dist), (pos.y + dist) do
			local area = {x = areax, y = areay, z = pos.z, stackpos = i}
			if getThingFromPos(area).itemid == value then
				return true
			end
		end
	end
   end
 
elseif key == "player" then
	if value ~=nil then
		local jug = getCreatureByName(value)
			if isPlayer(jug) == true then
				if isInRange(getCreaturePosition(jug), areaPosition[1], areaPosition[2]) == true then
                   return true
				end
			end
	else
		for _, pid in ipairs(players) do
				if isInRange(getCreaturePosition(pid), areaPosition[1], areaPosition[2]) == true then
                   return true
				end
		end				
	end
elseif key == "npc" then
	if value ~=nil then
		local getNpc = getCreatureByName(value)
		if isNpc(getNpc) == true then
			if isInRange(getCreaturePosition(getNpc), areaPosition[1], areaPosition[2]) == true then
				return true
			end
		end
	end
elseif key == "monster" then
	if value ~=nil then
		local getNpc = getCreatureByName(value)
		if isMonster(getNpc) == true then
			if isInRange(getCreaturePosition(getNpc), areaPosition[1], areaPosition[2]) == true then
				return true
			end
		end
	else	
	local monsters = {}
	pos=getCreaturePosition(cid)
	for x=1,17 do
		for y=1,17 do
			getpos={x=pos.x-9+x,y=pos.y-9+y,z=pos.z,stackpos=STACKPOS_TOP_CREATURE}
			if isCreature(getTopCreature(getpos).uid) == true then
			table.insert(monsters, getTopCreature(getpos).uid)
			end
		end
	end
 
	for i=1, #monsters do
		if isMonster(monsters[i]) == true then
			if isInRange(getCreaturePosition(monsters[i]), areaPosition[1], areaPosition[2]) == true then
                   return true
			end
		end
	end
	end
end
end

function doTradeItem(cid, olditem, count, newitem, amount)
	if getPlayerItemCount(cid, olditem) >= count then
		doPlayerRemoveItem(cid, olditem, count)
		return doPlayerAddItem(cid, newitem, amount) and true or false
	end
end
And npc.lua:
PHP:
dofile(getDataDir() .. 'npc/lib/npcsystem/npcsystem.lua')
function doNPCTalkALot(cid,delay,messages)
		for i = 1,#messages do
			addEvent(doCreatureSay,delay * i, getNpcCid(), messages[i], TALKTYPE_PRIVATE_NP, false, cid)
		end
end
function selfIdle()
	following = false
	attacking = false

	selfAttackCreature(0)
	target = 0
end

function selfSayChannel(cid, message)
	return selfSay(message, cid, false)
end

function selfMoveToCreature(id)
	if(not id or id == 0) then
		return
	end

	local t = getCreaturePosition(id)
	if(not t.x or t.x == nil) then
		return
	end

	selfMoveTo(t.x, t.y, t.z)
	return
end

function getNpcDistanceToCreature(id)
	if(not id or id == 0) then
		selfIdle()
		return nil
	end

	local c = getCreaturePosition(id)
	if(not c.x or c.x == 0) then
		return nil
	end

	local s = getCreaturePosition(getNpcId())
	if(not s.x or s.x == 0 or s.z ~= c.z) then
		return nil
	end

	return math.max(math.abs(s.x - c.x), math.abs(s.y - c.y))
end

function doMessageCheck(message, keyword)
	if(type(keyword) == "table") then
		return table.isStrIn(keyword, message)
	end

	local a, b = message:lower():find(keyword:lower())
	if(a ~= nil and b ~= nil) then
		return true
	end

	return false
end

function doNpcSellItem(cid, itemid, amount, subType, ignoreCap, inBackpacks, backpack)
	local amount = amount or 1
	local subType = subType or 1
	local ignoreCap = ignoreCap and true or false

	local item = 0
	if(isItemStackable(itemid)) then
		item = doCreateItemEx(itemid, amount)
		if(doPlayerAddItemEx(cid, item, ignoreCap) ~= RETURNVALUE_NOERROR) then
			return 0, 0
		end

		return amount, 0
	end

	local a = 0
	if(inBackpacks) then
		local container = doCreateItemEx(backpack, 1)
		local b = 1
		for i = 1, amount do
			item = doAddContainerItem(container, itemid, subType)
			if(itemid == ITEM_PARCEL) then
				doAddContainerItem(item, ITEM_LABEL)
			end

			if(isInArray({(getContainerCapById(backpack) * b), amount}, i)) then
				if(doPlayerAddItemEx(cid, container, ignoreCap) ~= RETURNVALUE_NOERROR) then
					b = b - 1
					break
				end

				a = i
				if(amount > i) then
					container = doCreateItemEx(backpack, 1)
					b = b + 1
				end
			end
		end

		return a, b
	end

	for i = 1, amount do
		item = doCreateItemEx(itemid, subType)
		if(itemid == ITEM_PARCEL) then
			doAddContainerItem(item, ITEM_LABEL)
		end

		if(doPlayerAddItemEx(cid, item, ignoreCap) ~= RETURNVALUE_NOERROR) then
			break
		end

		a = i
	end

	return a, 0
end

function doRemoveItemIdFromPos (id, n, position)
	local thing = getThingFromPos({x = position.x, y = position.y, z = position.z, stackpos = 1})
	if(thing.itemid == id) then
		doRemoveItem(thing.uid, n)
		return true
	end

	return false
end

function getNpcName()
	return getCreatureName(getNpcId())
end

function getNpcPos()
	return getCreaturePosition(getNpcId())
end

function selfGetPosition()
	local t = getNpcPos()
	return t.x, t.y, t.z
end

msgcontains = doMessageCheck
moveToPosition = selfMoveTo
moveToCreature = selfMoveToCreature
selfMoveToPosition = selfMoveTo
selfGotoIdle = selfIdle
isPlayerPremiumCallback = isPremium
doPosRemoveItem = doRemoveItemIdFromPos
doNpcBuyItem = doPlayerRemoveItem
doNpcSetCreatureFocus = selfFocus
getNpcCid = getNpcId
getDistanceTo = getNpcDistanceTo
getDistanceToCreature = getNpcDistanceToCreature
 
#Oskar, I bump'ed the wrong one this is already fixed :) but now I have a problem with compiling ... using 0.3.6 pl1



I got it work but the questlog doesn't work :S I get these errors when I compile...
Code:
In member function 'std::string Mission::getDescription(Player*)': 
77  invalid conversion from 'int' to 'const char*' 
77 initializing argument 1 of 'std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, const _Alloc&) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]' 
97 invalid conversion from 'int' to 'const char*' 
97 initializing argument 1 of 'std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, const _Alloc&) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]' 
121 invalid conversion from 'int' to 'const char*' 
121 initializing argument 1 of 'std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, const _Alloc&) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]' 
121 *** [obj//quests.o] Error 1

this is my quests.cpp
PHP:
////////////////////////////////////////////////////////////////////////
// OpenTibia - an opensource roleplaying game
////////////////////////////////////////////////////////////////////////
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
////////////////////////////////////////////////////////////////////////
#include "otpch.h"

#include "quests.h"
#include "tools.h"

bool Mission::isStarted(Player* player)
{
        if(!player)
                return false;

        std::string value;
        player->getStorage(storageId, value);
        return atoi(value.c_str()) >= startValue;
}

bool Mission::isCompleted(Player* player)
{
        if(!player)
                return false;

        std::string value;
        player->getStorage(storageId, value);
        return atoi(value.c_str()) >= endValue;
}

std::string Mission::parseStorages(std::string state, std::string value)
{
        /*std::string::size_type start, end;
        while((start = state.find("|STORAGE:")) != std::string::npos)
        {
                if((end = state.find("|", start)) = std::string::npos)
                        continue;

                std::string value, storage = state.substr(start, end - start)
                player->getStorage(storage, value);
                state.replace(start, end, value);
        } requires testing and probably fixing, inspired by QuaS code*/

        replaceString(state, "|STATE|", value);
        return state;
}

std::string Mission::getDescription(Player* player)
{
    std::string value;
    int32_t find_storage;
    player->getStorage(storageId, value);
    if(state.size())
    {
        std::string ret = state;
        while((find_storage=ret.find("|STORAGE:"))>-1)
        {
              int32_t parsing_storage = find_storage+9;
              std::string temp;
              while((int) ret[parsing_storage] != (int)'|')
              {
                   temp += ret[parsing_storage];
                   parsing_storage++;
              }
              parsing_storage -=find_storage-1;
              player->getStorage(atoi(temp.c_str()), temp);
              ret.replace(find_storage, parsing_storage, temp);
        }
        replaceString(ret, "|STATE|", value);
        return ret;
    }

    if(atoi(value.c_str()) >= endValue)
    {
        std::string ret = states.rbegin()->second;
        while((find_storage=ret.find("|STORAGE:"))>-1)
        {
              int32_t parsing_storage = find_storage+9;
              std::string temp;
              while((int) ret[parsing_storage] != (int)'|')
              {
                   temp += ret[parsing_storage];
                   parsing_storage++;
              }
              parsing_storage -=find_storage-1;
              player->getStorage(atoi(temp.c_str()), temp);
              ret.replace(find_storage, parsing_storage, temp);
        }
        replaceString(ret, "|STATE|", value);
        return ret;
    }

    for(int32_t i = endValue; i >= startValue; --i)
    {
        player->getStorage(storageId, value);
        if(atoi(value.c_str()) != i)
            continue;

        std::string ret = states[i - startValue];
        while((find_storage=ret.find("|STORAGE:"))>-1)
        {
              int32_t parsing_storage = find_storage+9;
              std::string temp;
              while((int) ret[parsing_storage] != (int)'|')
              {
                   temp += ret[parsing_storage];
                   parsing_storage++;
              }
              parsing_storage -=find_storage-1;
              player->getStorage(atoi(temp.c_str()), temp);
              ret.replace(find_storage, parsing_storage, temp);
        }
        replaceString(ret, "|STATE|", value);
        return ret;

    }

    return "Couldn't retrieve any mission description, please report to a gamemaster.";
}  

Quest::~Quest()
{
        for(MissionList::iterator it = missions.begin(); it != missions.end(); it++)
                delete (*it);

        missions.clear();
}

bool Quest::isStarted(Player* player)
{
        if(!player)
                return false;

        std::string value;
        player->getStorage(storageId, value);
        return atoi(value.c_str()) >= storageValue;
}

bool Quest::isCompleted(Player* player) const
{
        for(MissionList::const_iterator it = missions.begin(); it != missions.end(); it++)
        {
                if(!(*it)->isCompleted(player))
                        return false;
        }

        return true;
}

uint16_t Quest::getMissionCount(Player* player)
{
        uint16_t count = 0;
        for(MissionList::iterator it = missions.begin(); it != missions.end(); it++)
        {
                if((*it)->isStarted(player))
                        count++;
        }

        return count;
}

void Quests::clear()
{
        for(QuestList::iterator it = quests.begin(); it != quests.end(); it++)
                delete (*it);

        quests.clear();
}

bool Quests::reload()
{
        clear();
        return loadFromXml();
}

bool Quests::loadFromXml()
{
        xmlDocPtr doc = xmlParseFile(getFilePath(FILE_TYPE_XML, "quests.xml").c_str());
        if(!doc)
        {
                std::clog << "[Warning - Quests::loadFromXml] Cannot load quests file." << std::endl;
                std::clog << getLastXMLError() << std::endl;
                return false;
        }

        xmlNodePtr p, root = xmlDocGetRootElement(doc);
        if(xmlStrcmp(root->name,(const xmlChar*)"quests"))
        {
                std::clog << "[Error - Quests::loadFromXml] Malformed quests file." << std::endl;
                xmlFreeDoc(doc);
                return false;
        }

        p = root->children;
        while(p)
        {
                parseQuestNode(p, false);
                p = p->next;
        }

        xmlFreeDoc(doc);
        return true;
}

bool Quests::parseQuestNode(xmlNodePtr p, bool checkDuplicate)
{
        if(xmlStrcmp(p->name, (const xmlChar*)"quest"))
                return false;

        int32_t intValue;
        std::string strValue;

        uint32_t id = m_lastId;
        if(readXMLInteger(p, "id", intValue) && id > 0)
        {
                id = intValue;
                if(id > m_lastId)
                        m_lastId = id;
        }

        std::string name;
        if(readXMLString(p, "name", strValue))
                name = strValue;

        std::string startStorageId;
        if(readXMLString(p, "startstorageid", strValue) || readXMLString(p, "storageId", strValue))
                startStorageId = strValue;

        int32_t startStorageValue = 0;
        if(readXMLInteger(p, "startstoragevalue", intValue) || readXMLInteger(p, "storageValue", intValue))
                startStorageValue = intValue;

        Quest* quest = new Quest(name, id, startStorageId, startStorageValue);
        if(!quest)
                return false;

        for(xmlNodePtr missionNode = p->children; missionNode; missionNode = missionNode->next)
        {
                if(xmlStrcmp(missionNode->name, (const xmlChar*)"mission"))
                        continue;

                std::string missionName, missionState, storageId;
                if(readXMLString(missionNode, "name", strValue))
                        missionName = strValue;

                if(readXMLString(missionNode, "state", strValue) || readXMLString(missionNode, "description", strValue))
                        missionState = strValue;

                if(readXMLString(missionNode, "storageid", strValue) || readXMLString(missionNode, "storageId", strValue))
                        storageId = strValue;

                int32_t startValue = 0, endValue = 0;
                if(readXMLInteger(missionNode, "startvalue", intValue) || readXMLInteger(missionNode, "startValue", intValue))
                        startValue = intValue;

                if(readXMLInteger(missionNode, "endvalue", intValue) || readXMLInteger(missionNode, "endValue", intValue))
                        endValue = intValue;

                if(Mission* mission = new Mission(missionName, missionState, storageId, startValue, endValue))
                {
                        if(missionState.empty())
                        {
                                // parse sub-states only if main is not set
                                for(xmlNodePtr stateNode = missionNode->children; stateNode; stateNode = stateNode->next)
                                {
                                        if(xmlStrcmp(stateNode->name, (const xmlChar*)"missionstate"))
                                                continue;

                                        uint32_t missionId;
                                        if(!readXMLInteger(stateNode, "id", intValue))
                                        {
                                                std::clog << "[Warning - Quests::parseQuestNode] Missing missionId for mission state" << std::endl;
                                                continue;
                                        }

                                        missionId = intValue;
                                        std::string description;
                                        if(readXMLString(stateNode, "description", strValue))
                                                description = strValue;

                                        mission->newState(missionId, description);
                                }
                        }

                        quest->newMission(mission);
                }
        }

        if(checkDuplicate)
        {
                for(QuestList::iterator it = quests.begin(); it != quests.end(); ++it)
                {
                        if((*it)->getName() == name)
                                delete *it;
                }
        }

        m_lastId++;
        quests.push_back(quest);
        return true;
}

uint16_t Quests::getQuestCount(Player* player)
{
        uint16_t count = 0;
        for(QuestList::iterator it = quests.begin(); it != quests.end(); it++)
        {
                if((*it)->isStarted(player))
                        count++;
        }

        return count;
}

Quest* Quests::getQuestById(uint16_t id) const
{
        for(QuestList::const_iterator it = quests.begin(); it != quests.end(); it++)
        {
                if((*it)->getId() == id)
                        return (*it);
        }

        return NULL;
}

using 0.3.6 pl1

thanks in advance (Y)
 
Back
Top