• 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!

Fix/Patch Parsing Storage Values Inside of Quest.xml

I delete elf comment and put your code and i get same error of Dankoo.

I'm using TFS 0.4 last rev.
 
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
 
when uncomment it got errors
Code:
 In member function 'std::string Mission::parseStorages(std::string, std::string)': 
51 C:\Users\Venn\Desktop\trunk.r4086\quests.cpp 'player' was not declared in this scope 
51 C:\Users\Venn\Desktop\trunk.r4086\quests.cpp *** [obj//quests.o] Error 1
quests.cpp
Code:
std::string Mission::parseStorages(std::string state, std::string value[B][COLOR="red"], Player* player[/COLOR][/B])
{
	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);
	}

	replaceString(state, "|STATE|", value);
	return state;
}
Code:
std::string Mission::getDescription(Player* player)
{
	std::string value;
	player->getStorage(storageId, value);
	if(state.size())
		return parseStorages(state, value[B][COLOR="red"], player[/COLOR][/B]);

	if(atoi(value.c_str()) >= endValue)
		return parseStorages(states.rbegin()->second, value[B][COLOR="red"], player[/COLOR][/B]);

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

	return "Couldn't retrieve any mission description, please report to a gamemaster.";
}
quests.h
Code:
		std::string parseStorages(std::string state, std::string value[B][COLOR="red"], Player* player[/COLOR][/B]);
 
I'm using dev 0.4, rev 3884 (I was donator like a month ago)

With the code displayed in the first page, I got those errors I've mentioned... With cyk's code, it compiles, I add it to quests.xml, but when I open the mission, server crashes.

My quests.cpp and quests.h have been modified as Cyk said:

quests.cpp
[cpp]std::string Mission::parseStorages(std::string state, std::string value, Player* player)
{
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);
}

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

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

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

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

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

quests.h

[cpp]typedef std::map<uint32_t, std::string> StateMap;
class Mission
{
public:
Mission(std::string _name, std::string _state, std::string _storageId, int32_t _startValue, int32_t _endValue)
{
name = _name;
state = _state;
startValue = _startValue;
endValue = _endValue;
storageId = _storageId;
}
virtual ~Mission() {states.clear();}

void newState(uint32_t id, const std::string& description) {states[id] = description;}

bool isStarted(Player* player);
bool isCompleted(Player* player);

std::string getName(Player* player) {return (isCompleted(player) ? (name + " (completed)") : name);}
std::string getDescription(Player* player);

private:
std::string parseStorages(std::string state, std::string value, Player* player);

std::string name, state;
StateMap states;

int32_t startValue, endValue;
std::string storageId;
};[/cpp]

Heres the quests.xml's part I've modified... of course it won't be like that in final version, I was just debugging and testing:

Lua:
		<quest name="The Tomes of Knowledge Quest" startstorageid="36049" startstoragevalue="0" endvalue="1">
        <mission name="Finding the Tomes of Knowledge" storageid="36049" startvalue="-1" endvalue="11">
			<missionstate id="1" description="You have found one Tome of Knowledge."/>
			<missionstate id="2" description="You have found two Tomes of Knowledge."/>
			<missionstate id="3" description="You have found three Tomes of Knowledge."/>
			<missionstate id="4" description="You have found four Tomes of Knowledge."/>
			<missionstate id="5" description="You have found five Tomes of Knowledge."/>
			<missionstate id="6" description="You have delivered |STORAGE:36069|/12 Tomes of Knowledge to Cael."/>
			<missionstate id="7" description="You have found seven Tomes of Knowledge."/>
			<missionstate id="8" description="You have found eight Tomes of Knowledge."/>
			<missionstate id="9" description="You have found nine Tomes of Knowledge."/>
			<missionstate id="10" description="You have found ten Tomes of Knowledge."/>
			<missionstate id="11" description="You have found eleven Tomes of Knowledge."/>
			<missionstate id="12" description="You have found twelve Tomes of Knowledge."/>
        </mission>
		<mission name="Delivering the Tomes of Knowledge to Cael" storageid="36069" startvalue="-1" endvalue="11">
            <missionstate id="1" description="You have delivered one Tome of Knowledge."/>
			<missionstate id="2" description="You have delivered two Tomes of Knowledge."/>
			<missionstate id="3" description="You have delivered three Tomes of Knowledge."/>
			<missionstate id="4" description="You have delivered four Tomes of Knowledge."/>
			<missionstate id="5" description="You have found |STORAGE:36049|/12 Tomes of Knowledge."/>
			<missionstate id="6" description="You have delivered six Tomes of Knowledge."/>
			<missionstate id="7" description="You have delivered seven Tomes of Knowledge."/>
			<missionstate id="8" description="You have delivered eight Tomes of Knowledge."/>
			<missionstate id="9" description="You have delivered nine Tomes of Knowledge."/>
			<missionstate id="10" description="You have delivered ten Tomes of Knowledge."/>
			<missionstate id="11" description="You have delivered eleven Tomes of Knowledge."/>
			<missionstate id="12" description="You have delivered twelve Tomes of Knowledge."/>
        </mission>
		
    </quest>
 
quests.xml part is correct? It was suppose to work? quests.h's line is positioned correctly?
 
dankoo, change it like this;
put */ and */ on parsin storage and let it be like this
[cpp]/*
std::string Mission::parseStorages(std::string state, std::string value, Player* player)
{
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);
}

replaceString(state, "|STATE|", value);
return state;
}*/[/cpp]

now also go to quest.h and put // here
[cpp]
// std::string parseStorages(std::string state, std::string value, Player* player);
[/cpp]

PS. this will made this code to not be loaded, if you want you can exclude them too.. now get the working one..
change your get description to this:
(this code dont work on latest 0.4 cause getstorage are not reading the first var as int, its reading it as string, so when you use atoi to convert stg into int it returns console errors...
it should be like this.. player->getStorage(temp, temp); :p

[cpp]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(temp, 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(temp, 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(temp, 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.";
} [/cpp]
 
@knightxd

Works like a charm! Thanks a lot!!!!!!!!!!!!!!

repped++
 
quests.cpp
Code:
std::string Mission::parseStorages(std::string state, std::string value[B][COLOR="red"], Player* player[/COLOR][/B])
{
	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);
	}

	replaceString(state, "|STATE|", value);
	return state;
}
Code:
std::string Mission::getDescription(Player* player)
{
	std::string value;
	player->getStorage(storageId, value);
	if(state.size())
		return parseStorages(state, value[B][COLOR="red"], player[/COLOR][/B]);

	if(atoi(value.c_str()) >= endValue)
		return parseStorages(states.rbegin()->second, value[B][COLOR="red"], player[/COLOR][/B]);

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

	return "Couldn't retrieve any mission description, please report to a gamemaster.";
}
quests.h
Code:
		std::string parseStorages(std::string state, std::string value[B][COLOR="red"], Player* player[/COLOR][/B]);



Didn't understand where to put that
 
dankoo, change it like this;
put */ and */ on parsin storage and let it be like this
[cpp]/*
std::string Mission::parseStorages(std::string state, std::string value, Player* player)
{
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);
}

replaceString(state, "|STATE|", value);
return state;
}*/[/cpp]

now also go to quest.h and put // here
[cpp]
// std::string parseStorages(std::string state, std::string value, Player* player);
[/cpp]

PS. this will made this code to not be loaded, if you want you can exclude them too.. now get the working one..
change your get description to this:
(this code dont work on latest 0.4 cause getstorage are not reading the first var as int, its reading it as string, so when you use atoi to convert stg into int it returns console errors...
it should be like this.. player->getStorage(temp, temp); :p

[cpp]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(temp, 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(temp, 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(temp, 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.";
} [/cpp]

Didn't understand that, why change quests.h?

I'm 0.4 user, rev 3884
 
Lucas, read the name of the function:

In quests.cpp, look for Mission::parseStorages

You should find this line:

[cpp]std::string Mission::parseStorages(std::string state, std::string value, Player* player)[/cpp]

Above this, add /*
This is used to invalidate a code, scroll down until the end of the mentioned function and add */, to invalidate that whole code.

Now go to quests.h and "invalidate" this line

[cpp]std::string parseStorages(std::string state, std::string value, Player* player);[/cpp]

So quests.h don't try to look for that function in quests.cpp, the function you just disabled.

Now simply change the function Mission::getDescription from quests.cpp with this new one, it should work perfectly, I use the same REV as you and it worked here.

Feedback if not solved, good luck
 
Dev team should commit something like this, Its a really useful feature to have. Plus gets rid of combat issues with updated versions :p
 
dankoo, change it like this;
put */ and */ on parsin storage and let it be like this
[cpp]/*
std::string Mission::parseStorages(std::string state, std::string value, Player* player)
{
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);
}

replaceString(state, "|STATE|", value);
return state;
}*/[/cpp]

now also go to quest.h and put // here
[cpp]
// std::string parseStorages(std::string state, std::string value, Player* player);
[/cpp]

PS. this will made this code to not be loaded, if you want you can exclude them too.. now get the working one..
change your get description to this:
(this code dont work on latest 0.4 cause getstorage are not reading the first var as int, its reading it as string, so when you use atoi to convert stg into int it returns console errors...
it should be like this.. player->getStorage(temp, temp); :p

[cpp]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(temp, 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(temp, 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(temp, 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.";
} [/cpp]

Where I have to paste this last code?
 
:eek:

This code is in quests.cpp, it already exists, you should replace that function with this new one.
 
well open your quests.cpp then find for
[cpp]std::string Mission::parseStorages(std::string state, std::string value, Player* player)[/cpp]
after you have found it, delete the hole code..
then next to it you should find
[cpp]std::string Mission::getDescription(Player* player)[/cpp]
change it all into
[cpp]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(temp, 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(temp, 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(temp, 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.";
}[/cpp]

then save and open your quests.h; there look up for
[cpp]std::string parseStorages(std::string state, std::string value, Player* player);[/cpp]
once you've found it, delete...
 
Back
Top