Log in

View Full Version : adding new code help


spider661
07-04-2008, 02:47 PM
im trying to add a new command for quest i came up with the ideal when i was trying to do a quest that did not work the way i wanted. well someone posted code that should work the way i wanted but i decided to go ahead and make the code just to do it as a learning exp well i am havering problems so ill post it here to see if anyone can see whats wrong.

what this should do is read a variable from a new table called server_globals and then the quest should return the correct int.
questmgr.cpp

////////////////////////////////////////////ADDED/////////////////////////////////////
int QuestManager::GetServerInt(const char *varname, int npcid, int zoneid)
{
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
int var = 0;

if(npcid < 1){
npcid = 0;}

if(zoneid < 1){
zoneid = 0;}

if (database.RunQuery(query, MakeAnyLenString(&query, "SELECT value FROM server_globals WHERE name='%s' AND npcid = %i AND zoneid = %i", varname, npcid, zoneid), errbuf, &result)){
safe_delete_array(query);
if (mysql_num_rows(result) == 1){
row = mysql_fetch_row(result);
if (row[0])
var = atoi(row[0]);
}
mysql_free_result(result);
}
else{
LogFile->write(EQEMuLog::Error, "Error in GetServerInt query", query, errbuf);
//cerr << "Error in GetServerInt query '" << query << "' " << errbuf << endl;
safe_delete_array(query);
}

return var;
}
///////////////END ADD//////////////////////////////////////////////////////////////////////


questmgr.h

///////////////////ADDED//////////////////////////////////////////////////
int QuestManager::GetServerInt(const char *varname, int npcid = 0, int zoneid = 0);
///////////////////DONE ADD///////////////////////////////////////////////


perlparser.cpp

/////////////////////////ADDED//////////////////////////////////////////////////
XS(XS__GetServerInt);
XS(XS__GetServerInt)
{
dXSARGS;
if (items == 1)
{
char * varname = (char *)SvPV_nolen(ST(0));
quest_manager.GetServerInt(varname);
}
else if(items == 3)
{
char * varname = (char *)SvPV_nolen(ST(0));
int npcid = (int)SvIV(ST(1));
int zoneid = (int)SvIV(ST(2));
quest_manager.GetServerInt(varname, npcid, zoneid);
}
else
{
Perl_croak(aTHX_ "Usage: GetServerInt(varname,npcid = 0,zoneid = 0)");
}
XSRETURN_EMPTY;
}
//////////////////////////END ADD////////////////////////////////////////////
/*



added at end
/////////////////////ADDED//////////////////////////////////////////////////////
newXS(strcpy(buf, "GetServerInt"), XS__GetServerInt, file);
////////////////////END ADDED///////////////////////////////////////////////////


the quest on the npc

sub EVENT_SAY
{
if ($text =~/Hail/i)
{
if(quest::GetServerInt("myquest") == 10)
{
quest::say ("yay it worked");
}
else
{
quest::say ("no 10 here");
}
}
}



the error eqemu_quest_zone_3236.log

[07.04. - 07:40:02] Use of uninitialized value in numeric eq (==) at quests/qrg/testpet.pl line 6.


i have tryed the quest file many ways and still cant get it working. same error or close to it every time.

spider661
07-05-2008, 04:21 PM
ok i tried it a diff way and still getting same error.. basically i set it up like the quest_globals scripts. maybe this easier to figure out?
embparser.cpp
added

////////ADDED/////////////////////////////////////////////////
if(!isPlayerQuest){
if(npcmob && npcmob->GetQglobal()){

map<string, string> globhash;

// Load global variables
database.RunQuery(query, MakeAnyLenString(&query,
"SELECT name,value FROM server_globals"), errbuf, &result);
if (result)
{
while ((row = mysql_fetch_row(result)))
{
globhash[row[0]] = row[1];

// DEPRECATED: Export variables as $var in addition to hash
ExportVar(packagename.c_str(), row[0], row[1]);
}
mysql_free_result(result);
}
safe_delete_array(query);

// Put key-value pairs in perl hash
ExportHash(packagename.c_str(), "sglobals", globhash);
}
}
else{
//only export globals if the npcmob has the qglobal flag
if(mob){

map<string, string> globhash;

// Load global variables
database.RunQuery(query, MakeAnyLenString(&query,
"SELECT name,value FROM server_globals"), errbuf, &result);
if (result)
{
while ((row = mysql_fetch_row(result)))
{
globhash[row[0]] = row[1];

// DEPRECATED: Export variables as $var in addition to hash
ExportVar(packagename.c_str(), row[0], row[1]);
}
mysql_free_result(result);
}
safe_delete_array(query);

// Put key-value pairs in perl hash
ExportHash(packagename.c_str(), "sglobals", globhash);
}
}

///////////END ADDED//////////////////////////////////////


before

if(!isPlayerQuest){
//only export globals if the npcmob has the qglobal flag
if(npcmob && npcmob->GetQglobal()){


parser.cpp
added

///////ADDED//////////////////////
//spider661 - load server variables
if (npcmob->GetQglobal())
{
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
char tmpname[65];

if (database.RunQuery(query, MakeAnyLenString(&query, "SELECT name,value FROM server_globals"), errbuf, &result))
{
safe_delete_array(query);
while ((row = mysql_fetch_row(result)))
{
sprintf(tmpname,"%s.g",row[0]);
AddVar(tmpname, row[1]);
}
mysql_free_result(result);
}
else{
LogFile->write(EQEMuLog::Error, "Error in GetServerInt query", query, errbuf);
}
if (query)
{
safe_delete_array(query);
query=0;
}
}
//////////////END ADDED////////////


before

// SCORPIOUS2K - load global variables

if (npcmob->GetQglobal())
{


now if i understood that correctly thats all the code that makes it load the globals. and if so then it should be loading the server globals i added the same way?

spider661
07-05-2008, 05:12 PM
oops that


///////ADDED//////////////////////
//spider661 - load server variables
if (npcmob->GetQglobal())
{
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
char tmpname[65];

database.RunQuery(query, MakeAnyLenString(&query, "SELECT name,value FROM server_globals"), errbuf, &result);
printf("%s\n",query);
printf("%s\n",errbuf);
if (result)
{
printf("Loading global variables for %s\n",npcmob->GetName());
while ((row = mysql_fetch_row(result)))
{
sprintf(tmpname,"%s.g",row[0]);
AddVar(tmpname, row[1]);
}
mysql_free_result(result);
}
else{
LogFile->write(EQEMuLog::Error, "Error in GetServerInt query", query, errbuf);
}
if (query)
{
safe_delete_array(query);
query=0;
}
}
//////////////END ADDED////////////


it should be this in parser.cpp not the above but that still dont fix it

spider661
07-05-2008, 11:03 PM
i figured it out im sorry to have bothered... i will post what i come up with once its done and tested.

AndMetal
07-06-2008, 01:12 AM
On a side note, see my post (http://www.eqemulator.net/forums/showthread.php?t=25610#post152046) in your original thread (http://www.eqemulator.net/forums/showthread.php?t=25610). Fortunately but unfortunately, it should make this code redundant.

spider661
07-06-2008, 04:22 AM
hmm ya i saw that while i was doing code. but i did not understand it all saw that it went to 7 but in the code only went to like 3 did not know you added it up.. question is though is it still tied to the player or npc or is it tied to the server or something like that? becuase what im wanting to do is move from one zone to another with player 1 then the npc in zone 1 should read the variable and tell player 2 the zone is in use come back later and then npc 2 in zone 2 should turn off the same variable so that npc 1 will then again let players in without needing to know what npc its reading from or what player got the variable set? because from the code it seems that it always ties it to a player or npc or zone maybe.

the code i have working now just simply sets a variable to the database name and value and then calls it based on the name.. not set to anything npc,player,zone wise.

if the questglobales already do that great but if not thats what i need to know... wasted about 2 days of my time trying to get this to work if it does but hey lol y reinvent the wheel.

AndMetal
07-06-2008, 04:58 AM
i did not understand it all saw that it went to 7 but in the code only went to like 3 did not know you added it up.. question is though is it still tied to the player or npc or is it tied to the server or something like that? becuase what im wanting to do is move from one zone to another with player 1 then the npc in zone 1 should read the variable and tell player 2 the zone is in use come back later and then npc 2 in zone 2 should turn off the same variable so that npc 1 will then again let players in without needing to know what npc its reading from or what player got the variable set? because from the code it seems that it always ties it to a player or npc or zone maybe.

We're basically working with a bitmask in the options field. The first binary bit is NPCs, the 2nd is Player, and the 3rd is Zone. Since it looks like you would need all 3 to be able to access the global, that would make it 111 in binary. Because binary reads right to left, that would be the same as saying this:

Option: Zone Player NPC
Decimal value: 4 2 1
Binary value: 1 1 1


So, when you add that up, you get 7. Another example would be just the zone & player: 4 + 2 = 6.

the code i have working now just simply sets a variable to the database name and value and then calls it based on the name.. not set to anything npc,player,zone wise.

That's exactly what quest globals do: set a variable in the database (the quest_globals table) that can be called based on the name of the global. By default (when 0 is used for the option), it is specific to that player, npc, & zone that it was set in, but with the options, it opens up those permissions, just like the permissions on a file.

Hope this provides a little more clarity.

spider661
07-06-2008, 05:39 AM
well just tested it your right it already does exactly what i wanted it to do.. good news for everyone that did not know.. a big wast of time for me lol but thanks for the info really nice to know guess i get to just use this as another learning example for the code base :P eventually i will find something i can contribute lol..

thanks again.