Log in

View Full Version : Adding Perl Functions in New Quest System


Cisyouc
11-19-2004, 08:57 AM
In this tutorial I will be demonstrating how to add functions using the new perl quest system by FatherNitwit; similar to the tutorial for the old system written by Cofruben.

In this example I will be creating a completely useless function but it should show how all the features work. It will be quest::qcalc();. The function will bascially just add the 2 numeric parameters and display them to the client.

First, start by opening up questmgr.h and go to line ~109 or about here: void clear_proximity();Below this, insert this line: void qcalc(int numberone, int numbertwo);
Now open up questmgr.cpp and head to line ~1007 or: void QuestManager::clear_proximity() {
safe_delete(npc->proximity);
entity_list.RemoveProximity(npc->GetID());
}Below this, add: void QuestManager::qcalc(int numberone, int numbertwo)
{
Client *c = GetInitiator();
int result = numberone+numbertwo;
char* resultmessage;
sprintf(resultmessage, "Quest Calculator 1.0: %i + %i = %i", numberone, numbertwo, result);
c->Message(15, resultmessage);
}
GetInitiator(); gets your client class so any function after that (c->Message(int,char*) in this example) would be the equal as c->CastToClient()->...

Now open up perlparser.cpp and go to line ~193, where you should see the ending of XS(XS_EntityList_new)
{
dXSARGS;
if (items != 1)
Perl_croak(aTHX_ "Usage: EntityList::new()");
{
EntityList * RETVAL;

RETVAL = &entity_list;
ST(0) = sv_newmortal();
if(RETVAL)
sv_setref_pv(ST(0), "EntityList", (void*)RETVAL);
}
XSRETURN(1);
}

#endif After this, add in the qcalc code: XS(XS__qcalc); //Defines the function
XS(XS__qcalc) //Adding the function
{
dXSARGS; //Retrieves quest args
if (items != 2) //Number of args used
Perl_croak(aTHX_ "Usage: quest::qcalc(int, int);"); //Return an error
int x = SvUV(ST(0)); //Load Argument '0'
int y = SvUV(ST(1)); //Load Argument '1'

quest_manager.qcalc(x, y); /*load QuestManager::qcalc(int numberone, int numbertwo); with parameters x and y (see above definitions)*/
} Finally, at around line 1277, add in after XS_VERSION_BOOTCHECK ; Add this: newXS(strcpy(buf, "qcalc"), XS__qcalc, file);

Enjoy your new function...and hopefully you'll come up with better ideas than me...

fathernitwit
11-19-2004, 12:46 PM
some additions:

1. you shouldent need to call GetInitiator()... you can access it directly as 'initiator'... as well as the npc the quest is running on as 'npc'. Be careful as initiator is allowed to be null... on the other hand, npc is garunteed to never be null.

2. if you want your methods to work with the old non-XS based system, you need to do this:

If you want it to work in old mode perl and .qst, edit parser.cpp
Parser::ExCommands (~line 777)
else if (!strcmp(command,"joe")) {
quest_manager.joe(atoi(arglist[0]));
}

And then at then end of embparser.cpp, add:
"sub joe{push(@cmd_queue,{func=>'joe',args=>join(',',@_)});}"


3. when writting the XS callbacks like XS(XS__qcalc)
The SvUV thing can take several forms:
SvUV == string to unsigned value (char->ulong)
SvIV == string to signed value (char->long)
SvNV == string to real value (float,double)
SvPV_nolen == string with no length restriction

Cisyouc
11-19-2004, 02:24 PM
Thanks fnw.. but when i was compiling it on VC++ 6 I did indeed have to use GetInitiator() for some reason, because id get a compiliation error (undefined controller) if I just used initiator-> (which i saw other XS entries use fine)

So, im not sure.