View Single Post
  #1  
Old 12-27-2003, 03:28 PM
Lurker_005
Demi-God
 
Join Date: Jan 2002
Location: Tourist town USA
Posts: 1,671
Default Guide to the Perl Quest system *updated 16/02/2004*

UPDATED LIST OF FUNCTIONS AVALIABLE HERE:
http://www.arnold11.karoo.net/Perl.htm
Updated 16th Feb 2004 by Monrezz
WARNING: This guide may or may not be obsolete in some areas. -Cisyouc


This is for EQEMu 0.5.3+ With Perl Enabled
If you do not see the following in zone.exe when you boot it up you do NOT have Perl Enabled ones.
[Status] Loading embedded perl
[Status] Loading perlemb plugins.

Also, make sure you have installed Perl. [See Below]


Saving Quests
Save your quests as a .pl This can be done by going into Notepad --> Save As --> All File Types --> "npcid.pl"

Quests should be saved in $EQEmuDir$/quests/zonesn/NPCID.pl
Server-wide default quest in: $EQEmuDir$/quests/default.pl
Zone-wide default quests in: $EQEmuDir$/quests/zonesn/default.pl
The NPCID can be found in the database using a tool such as FQAdmin, Quest Editor or Mysql-Front,
Default quests are attached to all NPCs that do not already have a quest file associated with it.

Commands

- Comments -
Anything after an # is a comment, and is ignored by the parser. This is useful for leaving notes if you have more than one person working on a quest. Example of a comment:
# Monrezz: Next few lines are for the Hail response.


- Events -
sub EVENT_SAY - Triggered when a mob is targeted and the player types something.
sub EVENT_ITEM - Triggered when an item is turned into the mob via trade.
sub EVENT_DEATH - Triggered when the NPC dies.
sub EVENT_ATTACK - Triggered when the NPC is attacked.
sub EVENT_SPAWN - Triggered when the NPC spawns.
sub EVENT_TIMER - Triggered by a "quest::starttimer()"
sub EVENT_SLAY - Triggered whenever an NPC kills someone.
sub EVENT_WAYPOINT - Triggers when the mob reaches a waypoint.


- Variables -
All speaking responses are included in a $text variable:
if ($text=~/Hail/i)
Note the /i. This means it is case insensitive. It is always better to include this.

$text =~/Hello/ - Would match "Hello", but not "hello".
$text =~/hello/ - Would match "hello", but not "Hello".
$text =~/hello/i - Would match "Hello" and "hello".
$text =~/me/ - Would match the "me" in name.
$text =~/\bme\b/ - Would not match the "me" in name. The "\b" means there must not be text next to the match so "me" must be by itself.
$text =~/^me$/i - Would only match if me is the only text said. The "^" tells it it must be the first thing said and the "$" tells it it must be the last thing.

This uses Perl Regular Expression Matching. See one of the following sites for more info:
http://aspn.activestate.com/ASPN/doc...rlrequick.html
http://aspn.activestate.com/ASPN/doc...perlretut.html
http://www.erudil.com/preqr.pdf


- Identifiers -
$name - Returns the name of the user that triggered the Event.
$race - Returns the race of the user that triggered the Event.
$class - Returns the class of the user that triggered the event.
$userid - Returns the ID of the user that triggered the Event.
$ulevel - Returns the level of the user that triggered the Event.
$uguildid - Returns the ID of the guild of the user that triggered the Event.
$uguildrank - Returns the guild rank of the user that triggered the Event.
$mname - Returns the Mob's name.
$mobid - Returns the NPCTypeID of the mob that the user triggered the Event on.
$mlevel - Returns the level of the mob that the user triggered the Event on.
$faction - Returns the faction level number of the user with the mob.
1: Ally
2: Kindly
3: Warmly
4: Amiably
5: Indifferent
6: Apprehensive
$zonesn - Returns the zone short name that the Event occured in.
$zoneln - Returns the zone long name that the Event occured in.
$status - Returns the account status of the user that triggered the Event.
$item1 - The item# in the first slot.
$item2 - The item# in the second slot.
$item3 - The item# in the third slot.
$item4 - The item# in the fourth slot.
$itemcount{itemid} - $itemcount{1001} would return 2 if the user turned in 2 1001 items.
$copper - returns the number of copper coins given tothe mob.
$silver - returns the number of silver coins given tothe mob.
$gold - returns the number of gold coins given tothe mob.
$platinum - returns the number of platinum coins given to the mob.


- Commands -
Commands require a semicolon ";" at the end of each one.
UPDATED VERSION AVALIABLE HERE:
http://www.arnold11.karoo.net/Perl.htm

quest::say("Text"); - Mob will say "Text".
quest::emote("Text"); - Mob will emote "Text".
quest::shout("Text"); - Mob will shout "Text".
quest::spawn(npc_type,grid,guildwarset,x,y,z); - Spawn "npc_type" on "grid" with "guildwarset" at "x","y","z".
quest::echo("Text"); - Echoes specified text to console.
quest::summonitem(itemid); or quest::summonitem(itemid,charges); - Summons "itemid" to user that triggered Event. Charges is the number of charges, or number of items in the stack depending on the item type, it is also optional.
quest::castspell(id,spellid); - Casts "spell" on entity with "id".
quest::selfcast(spellid); - Forces client to cast spell on themself (useful for self only and group effect spells).
quest::depop(); - Mob will de-spawn.
quest::cumflag(); - Flag 50 for mob will increase by 1.
quest::flagnpc(flag,flag_value); - Sets "flag" to "flag_value" for mob.
quest::flagclient(flag,flag_value); - Sets "flag" to "flag_value" for client.
quest::exp(amount); - Adds "amount" of exp to user's exp amount.
quest::level(newlevel); - Sets user level.
quest::safemove(); - Moves user to zone's safe x,y,z.
quest::rain(1/0); or quest::snow(1/0); - Makes it rain or snow in zone.
quest::givecash (cop.,silv.,gold,plat); - Gives client coin.
quest::pvp("on/off"); - Sets pvp on/off for user.
quest::doanim(anim_num); - Mob will do animation for "anim_num".
quest::addskill(skill,value); - Increases "skill" by "value" for user.
quest::me("text"); - Does a name-less emote, me("The ground below you begins to shake").
quest::faction(faction_id,value); - Give player faction "value" with "faction_id".
quest::setguild(guild_id,rank); - Add player to "guild_id" with a "rank".
quest::rebind(zone id,x,y,z) - Binds the user that triggered the Event to the provided zone and loc.
quest::flagcheck - Checks the value of a quest flag.
quest::write
quest::settime(hour,minute) - Sets zone time of day. Sky/lighting changes acordingly.
quest::setsky(0-255) - changes the sky.
quest::settimer(timerID,seconds) - Starts timer for use with EVENT_TIMER You can have multiple "timerID"'s that trigger every "seconds".
quest::stoptimer(timerID) - stops the timer "timerID".
quest::settarget(type,ID) - Quest mob targets "ID" by "type" = npctype or entity.
quest::follow(ID) - Mob starts to follow "ID".
quest::sfollow() - turns off follow.
quest::movepc(zoneid,x,y,z) - Moves the user that triggered the Event to the provided zone and loc.
quest::gmmove(x,y,z) - Moves the user that triggered the Event to the provided loc.
quest::movegrp(zoneid,x,y,z) - Moves the user's Group that triggered the Event to the provided zone and loc.
quest::setallskill(0-252) - Sets all skills to value.
quest::attack("name") - Attacks "name".
quest::save() - Saves player data? see note
quest::setglobal(varname,value,options,duration) - Sets a variable for the current quest mob. See Tark's post
quest::targlobal(varname,value,duration,npcid,char id,zoneid) - Set a variable for any mob. See Tark's post
quest::delglobal(varname) - delete a variable for the quest mob. See Tark's post


- If Statements -
Syntax:
if($variable1 [operator] $variable2){
quest::commands;
}


Operators:
$1 == $2 : If variable $1 is the same as variable $2, carry on.
$1 != $2 : If variable $1 is NOT the same as variable $2, carry on.
$1 > $2 : If variable $1 is greater than variable $2, carry on.
$1 < $2 : If variable $1 is less than variable $2, carry on.
$1 >= $2 : If variable $1 is greater than or equal to variable $2, carry on.
$1 <= $2 : If variable $1 is less than or equal to variable $2, carry on.

In this example, if the user is a smaller level than the mob the mob says "I'm a higher level than you!"
Code:
if($ulevel < $mlevel){
quest::say("I'm a higher level than you!");
}
$1 && $2 : If $variable1 and $variable2 are true, carry on.
$1 || $2 : If $variable1 or $variable2 are true, carry on.

In this example, if the user is a smaller level than the mob the mob and the mob is at least level 10, the mob says "I'm higher than you.". Note: You must put all calculations in brackets "(",")", otherwise they wil be calculated in the wrong order.
Code:
if(($ulevel < $mlevel) && ($mlevel >=10)){
quest::say("I'm higher than you!");
}
It is also easier if you break the quest up into lines, for easier reading. Here are a few useful examples of commonly used code:

Hail script:
Code:
 
sub EVENT_SAY
{
 if ($text=~ /Hail/i){quest::say("Why hello there mister!");}
}
Multiple responses:
Code:
sub EVENT_SAY
{
 if ($text=~ /Hail/i){quest::say("Hey, have you seen a [rock] around here?");}
 if ($text=~ /rock/i){quest::say("Ya it was big and shiny");}
}
Item Turn-in:
Code:
sub EVENT_ITEM
{
 if ($item1 == 1001){quest::say("Wow thanks for this.. cloth?!");}
}
NPC Shouting and Emoting:
Code:
sub EVENT_SAY
{
 if ($text=~ /Hail/i) { quest::me("Theres a sound of [wind] blowing as you come close to bob-the-npc");}
 if ($text=~ /wind/i) { quest::shout("This guy is bugging me");}
}
NPC Death:
Code:
sub EVENT_DEATH
{
 quest::say("I'll get you back $name!");
 quest::shout("I've just died!");
}
Bone Chips:
Code:
sub EVENT_SAY
{
 if ($text=~ /Hail/i){quest::say("Hail $name. We of Tunare are charged with protecting the Great Mother from the forces of Innoruk. Even now the evil minions of this foul deity are despoiling our great forest. Will you help us [protect the mother]?");}
 if ($text=~ /perform a task/i){quest::say("Just outside the gates of Felwithe the forces of Innoruk gather in the guise of decaying skeletons. Bring me four sets of bone chips as proof of your vigilance. I assure you that your faith shall not go unrewarded.");}
}
sub EVENT_ITEM
{
 if ($itemcount{13331} == 4){quest::say("Praise Tunare - I knew that you would be victorious. I reward you with this spell, and pray that it will help you in your fight against the unholy forces of Innoruk.");
 quest::exp(125);
 quest::faction(32,5);
 quest::faction(57,-1);
 quest::summonitem(15374);} 
}
Priest of Discord:
Code:
sub EVENT_SAY {
if($text=~/Hail/i){quest::say("Greetings $name. Are you a child of Order? If you have come seeking the path of Discord I require only that you give me your [Tome of Order and Discord] and I shall show you the way. Only then will you be freed from Order's confining restraints.");}
if($text=~/tome of order and discord/i){quest::say("The Tome of Order and Discord was penned by the seventh member of the Tribunal and has become the key to a life of Discord  in spite of the author's pitiful warnings.  Do you not have one  child of Order?  Would you [like to read] it?");}
 if($text=~/read it/i)
 {
 quest::say("Very well.  Here you go.  Simply return it to me to be released from the chains of Order.");
 quest::summonitem(18700);
 }
}
sub EVENT_ITEM
{
if($itemcount{18700} && $itemcount{18700} == 1)
  {
  quest::say("I see you wish to join us in Discord!  Welcome!  By turning your back on the protection of Order you are now open to many more opportunities for glory and power.  Remember that you can now be harmed by others who have also heard the call of Discord.");
  quest::exp(125);
  quest::pvp("On");
  }
}
Soulbinder:
Code:
sub EVENT_SAY
{
if($text=~/Hail/i){quest::say("Greetings $name. When a hero of our world is slain  their soul returns to the place it was last bound and the body is reincarnated. As a member of the Order of Eternity  it is my duty to [bind your soul] to this location if that is your wish.");}
if($text=~/bind my soul/i)
  {
  quest::say("Binding your soul.  You will return here when you die.");
  quest::castspell($userid,2049);
  }
}
- Advanced -


Test script for testing $variables:
Code:
sub EVENT_SAY { 
   if ($text=~/name/i){quest::say("name = $name");}
   if ($text=~/race/i){quest::say("race = $race");}
   if ($text=~/class/i){quest::say("class = $class");}
   if ($text=~/userid/i){quest::say("userid = $userid");}
   if ($text=~/ulevel/i){quest::say("ulevel = $ulevel");}
   if ($text=~/uguildid/i){quest::say("uguildid = $uguildid");}
   if ($text=~/uguildrank/i){quest::say("uguildrank = $uguildrank");} 
   if ($text=~/mobid/i){quest::say("mobid = $mobid");} 
   if ($text=~/mname/i){quest::say("mname = $mname");}
   if ($text=~/mlevel/i){quest::say("mlevel = $mlevel");} 
   if ($text=~/faction/i){quest::say("faction = $faction");}
   if ($text=~/zonesn/i){quest::say("zonesn = $zonesn");}
   if ($text=~/zoneln/i){quest::say("zoneln = $zoneln");}
   if ($text=~/status/i){quest::say("status = $status");} 
   if ($text=~/emote/i){quest::emote("emotes before you.");} 
   if ($text=~/shout/i){quest::shout("Is this shouting?");}
   if ($text=~/spawn1/i){quest::spawn(42,0,0,1,0,1);}
   if ($text=~/echo/i){quest::echo("this is an echo echo echo echo echo");}
   if ($text=~/summonitem1/i){quest::summonitem(17969);}
   if ($text=~/summonitem2/i){quest::summonitem(13087, 2);} 
   if ($text=~/castspell/i){quest::castspell($userid, 278);}
   if ($text=~/depop/i){quest::depop();}
   if ($text=~/exp/i){quest::exp(100);}
   if ($text=~/level/i){quest::level($ulevel + 1);} 
   if ($text=~/safemove/i){quest::safemove();}
   if ($text=~/rain1/i){quest::rain(1);}
   if ($text=~/snow1/i){quest::snow(1);}
   if ($text=~/rain2/i){quest::rain(0);}
   if ($text=~/snow2/i){quest::snow(0);}
   if ($text=~/givecash/i){quest::givecash(0,0,0,50);} 
   if ($text=~/pvp1/i){quest::pvp("on");} 
   if ($text=~/pvp2/i){quest::pvp("off");}
   if ($text=~/doanim/i){quest::doanim(3);} 
   if ($text=~/me/i){quest::me("The heavens applaud you.");}
   if ($text=~/givefaction/i){quest::faction(1,1);}
   if ($text=~/takefaction/i){quest::faction(101,-5);}
   if ($text=~/setcumflag/i){quest::cumflag();}
   if ($text=~/setflagnpc1/i){quest::flagnpc(1);} 
   if ($text=~/setflagnpc2/i){quest::flagnpc(2);}
   if ($text=~/addskill/i){quest::addskill(1,5);} 
   if ($text=~/setguild/i){quest::setguild(1,1);}
   if ($text=~/rebind/i){quest::rebind(9,1,0,3);}
   if ($text=~/flagcheck/i){quest::flagcheck(50,2);quest::say("flag 50 = ");}
   if ($text=~/write/i){quest::write();}
   if ($text=~/settime/i){quest::settime(4,39);}
   if ($text=~/setsky/i){quest::setsky(1);}
   if ($text=~/settimer/i){quest::settimer(7,15);}
   if ($text=~/stoptimer/i){quest::stoptimer(7);}
   if ($text=~/settarget/i){quest::settarget(entity,$userid);}
   if ($text=~/sfollow1/i){quest::sfollow();}
   if ($text=~/follow2/i){quest::follow($userid);}
   if ($text=~/movepc/i){quest::movepc(9,1,0,3);}
   if ($text=~/gmmove/i){quest::gmmove(-1,0,3);}
   if ($text=~/movegrp/i){quest::movegrp(9,0,1,3);}
   if ($text=~/setallskill/i){quest::setallskill(55);}
   if ($text=~/attack/i){quest::attack("$name");}
   if ($text=~/save/i){quest::save();}
}
Money conversion (converts all coins into the lowest number of coins):
Code:
sub EVENT_SAY
{
	if($text =~ /Hail/i){
	quest::say("Greetings $name. Would you like me to [convert] some money?");}

	if($text =~ /convert/i){
	quest::say("Give me some loose change and I will change it into the highest coinage I can. I will always round down - I have to make a living somehow!");}
}
sub EVENT_ITEM
{
	$myplatinum = (($copper/1000) + ($silver/100) + ($gold/10) + $platinum);
	$mygold = (($copper/100) + ($silver/10) + $gold + (10*$platinum));
	$mysilver = (($copper/10) + $silver + (10*$gold) + (100*$platinum));
	$mycopper = ($copper + (10*$silver) + (100*$gold) + (1000*$platinum));

if($mycopper < 10){
	quest::say("Sorry, but I need at least 10 copper to upgrade you into silver. Here, have your money back.");
	quest::givecash($copper,0,0,0);}

if((($mycopper >= 10) && ($mycopper < 100)) || (($mysilver >= 1) && ($mysilver < 10))){
	quest::say("You gave me coins worth a total value of $mysilver silver. Here you go:");
	quest::givecash(0,$mysilver,0,0);}

if((($mycopper >= 100) && ($mycopper < 1000)) || (($mysilver >= 10) && ($mysilver < 100)) || (($mygold >= 1) && ($mygold < 10))){
	quest::say("You gave me coins worth a total value of $mygold gold. Here you go:");
	quest::givecash(0,0,$mygold,0);}

if(($mycopper >= 1000) || ($mysilver >= 100) || ($mygold >= 10) || ($myplatinum >= 1)){
	quest::say("You gave me coins worth a total value of $myplatinum platinum. Here you go:");
	quest::givecash(0,0,0,$myplatinum);}
}


Installing Perl

Download Perl 5.8, Then install using the default settings for everything. Now reboot so path changes take affect. Congratulations, Perl is installed.

Installing IO::Scalar
If you don't already have it, download nmake.exe (save with .exe extension). Copy it into your perl\bin directory. Then type the following in a DOS window:
Code:
perl -MCPAN -e shell
When asked if you want to configure it manually, say "no". Once everything is done there type in:
Code:
install IO::Scalar
Once complete it should say -- install OK.

Problems
If perl isn't installed properly the zone windows will disapear after starting up. If you followed all the above steps correctly, make sure you have a copy of "Perl58.dll" in your "C:\Perl\bin" directory. If there is a copy there, search your computer for all other copies of it and delete them. Also note it is Perl58, not 56.

To test if IO::Scalars is installed type the following in a DOS window:
Code:
perl -MIO::Scalar -e "print 'Installed'"
If you get an error it isn't working. Make sure you installed it correctly, if you didn't delete the following files in "C:\Perl\site\lib\IO" and then rerun "install IO::Scalar":
Scalar.pm
Scalar.pm.html
ScalarArray.pm



Last Edited by Monrezz on 16th February 2004.


Note: This is NOT a support thread. Please post help questions in the forum.
Reply With Quote