PDA

View Full Version : Howto: Perl Quests


Eglin
11-29-2003, 06:45 AM
Wasn't sure if this was the best forum to put this in or not, but...

Thanks to Rogean graciously allowing me to fiddle with his server this morning, I was able to get the Perl quest stuff working under Linux. The Linux version doesn

Rogean
11-29-2003, 06:48 AM
Eglin > All. Works Great! =)

Trumpcard
11-29-2003, 09:41 AM
Ah, so that was why i was getting the panic !

Good show! Going to sticky this post. Could you go into a little more detail in this thread regarding subdirectories, extensions, etc..

Eglin
11-29-2003, 01:18 PM
Could you go into a little more detail in this thread regarding subdirectories, extensions, etc..
Of course. Please feel free to ask specific questions, too.

Perl quests work almost exactly like native quests. I modeled them after the description here (http://www.everquestserver.com/forums/viewtopic.php?t=5719), and made changes where I happened to notice that Wes did (ala $itemcount or timer). At any rate, the same directory structure is used, but filenames should end in ".pl". So, if you download the quests linked above, then you should unzip them such that your dir structure looks like ($eqemu_base)/quests/($zonename)/[npcid].qst (all lowercase!!!), then paste the convert script above into ($eqemu_base)/quests/convert.pl, then run ./convert.pl. You should then have a .pl file for each .qst file. I don't think the quest converter works perfectly yet, but I don't think it should be hard to fix it (works for me, but I had differently formatted input quests & I don't remember where I downloaded them). Offering a quest package already in pl format would be cool, espescially since installing perl quests requires a level of trust in the author (security reasons), but I didn't feel comfortable doing so since I do not know who to credit for the original package (which all modern quest distributions obviously derive from). Nonetheless, I am considering making/maintaining a quest/plugin package/repository at some point.

Plugins may either be stuffed into ($eqemu_base)/plugin.pl or placed in any file with a .pl extention in ($eqemu_base)/plugins/ When zone starts up, it will compile all the code in plugin.pl and each file in the plugins dir whose filename ends in .pl (IIRC). Any code outside of a subroutine will be discarded (IIRC). All code is compiled into package plugin by default. For some plugin examples, see this thread (http://www.everquestserver.com/forums/viewtopic.php?t=11056#58123). Plugins and the #peval command are really really really cool and useful. If you use perl, you should learn them. The key to using them effectively is to learn how embperl stuffs things into packages (plugins are in package plugin, quests are in qst[qst id] (ie qst1234) or qstdefault). Don't worry if you don't understand that last bit - you can still benefit from using perl.

hrm... what else should I share? Oh... the vars $1, $1-, etc aren't be used in Perl quests. Instead, look for $text to hold the entire string. So, if ($1- =~= "Hail") becomes if($text=~/Hail/). I _think_ that the convert script will handle this for you, but you should still probably know what's up.

Since I can't think of anything else to share without trying to teach Perl, I'll stop. Feel free to ask specific questions, though (in this thread or others). I want to see some cool quests/features, so if you do something neat, need help doing something neat, or just have a tight setup, please post somewhere and tell us about it!

Eglin
11-29-2003, 01:38 PM
Oh, yeah.... $(eqemu_basedir)/quests/default.pl gets compiled and applied to any npc who does not have a .pl file of their own.

I used something like the following when I was testing implementing the Perl stuff.

sub EVENT_SAY() {
quest::say("Greetings. $name... I can tell you about [variables] and [commands] or you can give me items.") if ($text=~/hail/i);
quest::say("Want to test a variable? Try [name]. [race]. [class]. [userid]. [ulevel]. [uguildid]. [mobid]. [mlevel]. [faction]. [zonesn]. [zoneln]. or [status]") if ($text=~/variabl/i);
quest::say("name = $name") if($text=~/name/i);
quest::say("race = $race") if($text=~/race/i);
quest::say("class = $class") if($text=~/class/i);
quest::say("userid = $userid") if($text=~/userid/i);
quest::say("ulevel = $ulevel") if($text=~/ulevel/i);
quest::say("uguildid = $uguildid") if($text=~/uguildid/i);
quest::say("mobid = $mobid") if($text=~/mobid/i);
quest::say("mlevel = $mlevel") if($text=~/mlevel/i);
quest::say("faction = $faction") if($text=~/faction/i);
quest::say("zonesn = $zonesn") if($text=~/zonesn/i);
quest::say("zoneln = $zoneln") if($text=~/zoneln/i);
quest::say("status = $status") if($text=~/status/i);
quest::say("Want to test a command? Try [emote]. [shout]. [spawn]. [echo]. [summonitem]. [castspell]. [depop]. [cumflag]. [flagnpc]. [flagclient].[exp]. [level]. [safemove]. [rain]. [snow]. [givecash]. [pvp]. [doanim]. [addskill]. or [me]") if($text=~/command/i);
quest::emote("emotes before you.") if ($text=~/emote/i);
quest::shout("Is this shouting?") if ($text=~/shout/i);
quest::say("I don't feel like spawning anything right now") if($text=~/spawn/i);
quest::echo("this is an echo echo echo echo echo") if ($text=~/echo/i);
quest::summonitem(17969) if ($text=~/summonitem/i);
quest::castspell(278, $id) if ($text=~/castspell/i);
quest::say("awww... I don't wanna!") if ($text=~/depop/i);
quest::exp(100) if ($text=~/exp/i);
quest::level($ulevel + 1) if ($text=~/level/i);
quest::safemove() if ($text=~/safemove/i);
quest::rain(1) if ($text=~/rain/i);
quest::snow(1) if ($text=~/snow/i);
quest::givecash(0,0,0,50) if ($text=~/givecash/i);
quest::pvp("on") if ($text=~/pvp/i);
quest::doanim(3) if ($text=~/doanim/i);
quest::me("The heavens applaud you.") if ($text=~/me/i);
}

Obviously, this means that I haven't tested the spawn commands and depop commands and a few others. rain and snow seem to be pretty unstable ATM... I'm probably passing the arguments to the underlying C++ subsystem incorrectly (haven't taken the time to look into this yet - hey, it is a first revision!). Also, some commands aren't mutually exclusive (so telling the npc "emote" will result in both emote and me), but no biggie. You probably shouldn't be using this as a default anyway.

Trumpcard
11-29-2003, 11:49 PM
Works great so far, I see ALOT of these scrolling though..

[Status] Error exporting var: Perl runtime error: Can't modify concatenation (.) or string in scalar assignment at (eval 8728) line 1, at EOF

Looks like it's just catching and throwing... Maybe ought to wrap that one a little better so we can identify the root of the problem, at least identify the source file (no idea how tough that will be since im guessing its just wrapping up the err text from perl....

Eglin
11-30-2003, 03:53 PM
Works great so far, I see ALOT of these scrolling though..

[Status] Error exporting var: Perl runtime error: Can't modify concatenation (.) or string in scalar assignment at (eval 8728) line 1, at EOF

Looks like it's just catching and throwing... Maybe ought to wrap that one a little better so we can identify the root of the problem, at least identify the source file (no idea how tough that will be since im guessing its just wrapping up the err text from perl....
Not a very descriptive message, but an error that should never really happen, since the function is internal to the parser. There is no sourcefile to identify because, again, this is internal to the parser. This is the bit that makes all the vars like $name avaliable to scripts. I'm actually surprised it works at all for you if you're getting these messages. Try replacing perl->eval(std::string("$").append(pkgprefix).append("::").append(varname).append("=qq(").append(value).append(");").c_str()); with perl->eval(std::string("$").append(pkgprefix).append("::").append(varname).append("=q(").append(value).append(");").c_str()); That should do it.

lol... looking at that and wondering why the hell I didn't just use strstream... that's fugly! cheers

Scorpious2k
12-03-2003, 09:08 AM
Running WinXP here, made the change recommended and still getting the message....

Trumpcard
12-03-2003, 09:11 AM
I've found that once you identify the script with the problem (parse error message on zone bootup usually will tell you which .pl file), and move it out of the way, this spam will stop..

Scorpious2k
12-03-2003, 09:21 AM
Thanks, it was getting on my last nerve and I was close to finding a newbie and pulling a mattmeck on him....

Rogean
12-03-2003, 10:47 AM
ROFL

mattmeck
12-04-2003, 04:10 AM
!!! :shock: HEY!!!


See even when i am not around at all for over a week people still take my name in vain :twisted: :twisted:

Eglin
12-04-2003, 07:38 AM
Any chance your scripts use waypointing stuff?

std::string temp = "wp."; -> std::string temp = "wp";

oops :)

Liem
12-13-2003, 03:53 PM
[quote=Eglin]2) If you can compile but get a panic: top_env error upon execution, then check to make sure you have IO::Scalar installed. This is the confusing bit. For some reason (and I

Eglin
12-13-2003, 05:08 PM
This panic happens too on Win32 with ActivePerl-5.8.1.807-MSWin32-x86 but install IO::Scalar doesn't work
I've tested under Windows XP with both 5.6 and 5.8 dists, including the package you listed. I don't really know why Perl is dieing like that, or why it is bringing down the whole process, since it is pretty much always wrapped inside @eval blocks. At any rate, if you are positive that you are setup correctly, then step through the embperl constructor and see where it is puking on you.

Since I don't really understand why it is dying in this fashion (and there is scarce documentation avaliable on top_env: panic), I can't say for certain that the error is in the constructor. Nor can I say that it is related to IO::Scalar or any other module. Still, it seems like the best place to start. If you have trouble debugging, you might note that embperl is not dependent upon eqemu - you can write a simple standalone app to test it by including embperl.h and linking against embperl.o and perl58.lib

Thank you for posting your perl version. That tells me a lot about your situation right off the bat. If you post another response, though, please be much more specific about your error.... Was it a panic: top_env like the others? At what point did the error occur? What do you get when you type:perl -MIO::Scalar -e "print 'AOK'" from a command prompt? What OS are you on? etc...

Liem
12-13-2003, 07:03 PM
This is a post from me in the Win32 support forum about this same matter.
http://www.everquestserver.com/forums/viewtopic.php?t=11720&postdays=0&postorder=asc&start=0

Lurker_005
12-22-2003, 10:43 PM
A small but usefull tip for those that DON'T know perl.

The i near the end of the if ($text=~/hail/i); example means it is case insensitive.

Not knowing ANY perl, it actually took me a while to find out what it was for. Although I already suspected...[/i]

And of course the best place to start to learn perl is the documentation that came with perl :)