Go Back   EQEmulator Home > EQEmulator Forums > Quests > Quests::Custom

Quests::Custom Custom Quests here

Reply
 
Thread Tools Display Modes
  #1  
Old 10-23-2009, 01:15 PM
Valdaun
Fire Beetle
 
Join Date: Oct 2009
Posts: 28
Default Very simple scalable array + hash based quest template

I've been working on this quest for a few days now and I thought I would share the completed product. I really wanted to make a quest template with the following attributes:
  • Very easy to modify
  • Very easy to scale up to dozens+ of items
  • Heavy use of variables to eliminate redundancy, especially of item IDs
  • Say links + item links + direct whispering, because those rock!

I knew from previous programming experience that multi dimensional arrays (or I guess perl calls them hashes) holding all the relevant bits of information would be the way to go, but it took some playing to get the syntax and loops just right since I am really only fluent in PHP.

Anyway, below is my completed quest using this method. As this particular quest was intended to give my family and friends a way to start off with some decent equipment, I took some inspiration from current events ... hopefully no one finds the slight US political nod offensive; it's all in good fun!

Lastly, please note that a previous version of this was causing Plane of Knowledge to crash on startup simply by existing in the poknowledge quest folder. I would have to remove it, let the zone start, then put it back and run #reloadqst to get things working. I have not yet reset my server since my final revision, but if anyone has any thoughts on why a quest .pl file would crash a zone bootup I would love to hear them! I am actually suspecting it might be more due to the NPC itself, so deleting him and starting over is on my list of things to try.

The Quest:
Code:
#
# Simple & Scalable
# Array + hash based quest template
#
# Valdaun  10/23/2009
#
################################################
# All turnins follow simple method:
#
# Quest Item + Component Cost = Reward
#
# Extremely scalable from a handful of sets
# to dozens, without any code bloat.
#
# All item IDs are typed only one time,
# reducing errors and simplifying changes
#
# Heavy use on say and item links + npc whispers
# for minimal say spam and ease of npc interaction
#
################################################
#
#######    BEGIN ARRAY MODS    #################
# 
################################################
#
# QUEST TURNINS AND REWARDS
#
################################################
#
# Component costs for quest turnins
#
my $rare_cost = 22503;	# blue diamond (dropped)
my $mid_cost = 10031;	# fire opal (bought)

################################################
#
# Arrays containing the item to turnin as the array index,
# which points to a cost & reward hash which will be looped
# through later in the say and handin sections.
#
my %fabled_turnins = (
	5401 => { "cost" => $rare_cost, "reward" => 68259 },	#Mithril 2 hander & fabled
	5403 => { "cost" => $rare_cost, "reward" => 68260 },	#Ghoulbane & fabled
	5500 => { "cost" => $rare_cost, "reward" => 68263 },	#SS of Ykesha & fabled
	5412 => { "cost" => $rare_cost, "reward" => 68262 }	#Razing Sword of Skarlon & fabled
);

my %defiant_turnins = (
	8003 => { "cost" => $mid_cost, "reward" => 50550 },	#Longbow & Rough Defiant Bow
	9004 => { "cost" => $mid_cost, "reward" => 50551 },	#Kite Shield & Rough Def. Chitin Shield (tank)
	5006 => { "cost" => $mid_cost, "reward" => 50549 },	#Halberd & R.D. Halberd
	6006 => { "cost" => $mid_cost, "reward" => 50540 },	#Warhammer & R.D. Hammer
	8007 => { "cost" => $mid_cost, "reward" => 50546 },	#Shuriken & R.D. Knuckle Dusters
	5002 => { "cost" => $mid_cost, "reward" => 50543 },	#Long Sword & R.D. Longsword
	9002 => { "cost" => $mid_cost, "reward" => 50552 },	#Round Shield & R.D. Round Shield (priest)
	7002 => { "cost" => $mid_cost, "reward" => 50544 },	#Rapier & R.D. Stone Dagger (rog)
	7001 => { "cost" => $mid_cost, "reward" => 50545 },	#Dagger & R.D. Serrated Dagger (caster)
	5001 => { "cost" => $mid_cost, "reward" => 50542 },	#Short Sword & R.D. Short Sword
	6003 => { "cost" => $mid_cost, "reward" => 50541 },	#Mace & R.D. Scepter (priest)
	6012 => { "cost" => $mid_cost, "reward" => 50547 },	#Worn Great Staff & R.D. Spiked Staff (2hb)
	7003 => { "cost" => $mid_cost, "reward" => 50548 }	#Spear & R.D. Trident (2hp)
);

################################################
#
#  Whisper Color
#
my $whisper_color = 315;	# tan

################################################
#
#  Experience rewards
#
my $exp_big = 5000000;	# 1 yellow bar of AA
my $exp_mid = 50000;	# 1-4 worth of exp, slows down fast 6+

################################################
#
#######    END VARIABLE MODS     ###############
# 
################################################

sub EVENT_SAY {

################################################
#
#  Conversation navigation links for say section
#
my $fabled = quest::saylink("fabled");
my $defiant = quest::saylink("defiant");
my $looking_for = quest::saylink("looking for");
my $trade_for = quest::saylink("trade for");

	if($text=~/hail/i)
	{
		quest::say("My friend $name, come talk to me for a minute.  My name is
			   	Barack O'Pally, and I represent a change you can believe in!  
				Now listen to this, for too long have the rich and powerful in 
				this world held onto all of the [$fabled] and [$defiant] weapons 
				of yore.  I think this is a travesty and I intend to do something 
				about it.  Say it with me ... YES WE CAN!");
	}

	if($text=~/fabled/i)
	{
		$client->Message($whisper_color, "So this is what we are going to do.  You are going 
				to go out and collect some level 40-50 weapons and, and then I will 
				turn around and give you the fabled version just out of the kindness 
				of my heart, and my desire to change this world!  Would you like to 
				see what I am [$looking_for]?");
	}

	if($text=~/looking for/i)
	{
		$client->Message($whisper_color, "At this time, I am able to transmute the following 
				weapons into their fabled counterparts:");

		# loop through item => reward array and send a list of items to client 
		foreach $id (sort keys %fabled_turnins)
		{
			my $item_link = quest::varlink($id);
			my $cost_link = quest::varlink($fabled_turnins{$id}{"cost"});
			my $reward_link = quest::varlink($fabled_turnins{$id}{"reward"});

			$client->Message($whisper_color, "$item_link + $cost_link turn into $reward_link")
		}
	}

	if($text=~/defiant/i)
	{
		$client->Message($whisper_color, "To help get your start in this world with a little 
				leg up from The Man, I can get you some Rough Defiant quality weapons 
				for a minimal cost.  Would you like to see what I can [$trade_for]?");
	}

	if($text=~/trade for/i)
	{
		$client->Message($whisper_color, "At this time, I am able to make the following trades.  
				Most of these basic weapons are found on city merchants.");
		
		# loop through item => reward array and send a list of items to client 
		foreach $id (sort keys %defiant_turnins)
		{
			my $item_link = quest::varlink($id);
			my $cost_link = quest::varlink($defiant_turnins{$id}{"cost"});
			my $reward_link = quest::varlink($defiant_turnins{$id}{"reward"});

			$client->Message($whisper_color, "$item_link + $cost_link for $reward_link")
		}
	}
}

sub EVENT_ITEM {

	# used to determine if anything needs handed back
	my $gaveitem = 0;

	# loop through item => reward array looking for a match
	foreach $item_id (sort keys %fabled_turnins)
	{
		$cost = $fabled_turnins{$item_id}{"cost"};
		$reward = $fabled_turnins{$item_id}{"reward"};

		# hand out the goods on a match of item + cost
		if (plugin::check_handin(\%itemcount, $item_id => 1, $cost => 1))
		{
			$gaveitem = 1;

			quest::emote(" uses the power of the people to grant you whats yours!");
			quest::summonitem($reward);
			quest::ding;

			# this lets us grant a meaningful exp reward 
			# without giving a dozen+ levels worth at level 1
			if ($ulevel > 39)
			{
				quest::exp($exp_big);
			}

			else
			{
				quest::exp($exp_mid);
			}
		}
	}

	# loop through 2nd item => reward array looking for a match
	foreach $item_id (sort keys %defiant_turnins)
	{
		$cost = $defiant_turnins{$item_id}{"cost"};
		$reward = $defiant_turnins{$item_id}{"reward"};

		# hand out the goods on a match of item + cost
		if (plugin::check_handin(\%itemcount, $item_id => 1, $cost => 1))
		{
			$gaveitem = 1;

			quest::emote(" uses the power of the people to grant you whats yours!");
			quest::summonitem($reward);
			quest::exp(50000);
			quest::ding;
		}
	}

	# if there were no matches, give back what was turned in
	if ($gaveitem == 0)
	{
		plugin::return_items(\%itemcount);
	}
}

Last edited by trevius; 10-23-2009 at 05:54 PM..
Reply With Quote
  #2  
Old 10-23-2009, 04:59 PM
trevius's Avatar
trevius
Developer
 
Join Date: Aug 2006
Location: USA
Posts: 5,946
Default

Very nice and clean format. Thanks for sharing it

BTW, using quest::saylink outside of EVENT_SAY will almost always cause a zone crash, which may be why you were seeing your crashes. I am not really sure what causes the crash, but as long as you keep them inside EVENT_SAY, it isn't an issue.
__________________
Trevazar/Trevius Owner of: Storm Haven
Everquest Emulator FAQ (Frequently Asked Questions) - Read It!
Reply With Quote
  #3  
Old 10-23-2009, 05:04 PM
Valdaun
Fire Beetle
 
Join Date: Oct 2009
Posts: 28
Default

Thank you! By the way, you are right about it being the quest::saylink variables outside of EVENT_SAY. I moved them in, no more crash. whew!
Reply With Quote
  #4  
Old 10-23-2009, 05:56 PM
trevius's Avatar
trevius
Developer
 
Join Date: Aug 2006
Location: USA
Posts: 5,946
Default

I hope you don't mind, but I took the liberty to edit your post to adjust the saylink location in the script. Should be ready for anyone else to use it as-is now
__________________
Trevazar/Trevius Owner of: Storm Haven
Everquest Emulator FAQ (Frequently Asked Questions) - Read It!
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

   

All times are GMT -4. The time now is 07:18 PM.


 

Everquest is a registered trademark of Daybreak Game Company LLC.
EQEmulator is not associated or affiliated in any way with Daybreak Game Company LLC.
Except where otherwise noted, this site is licensed under a Creative Commons License.
       
Powered by vBulletin®, Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Template by Bluepearl Design and vBulletin Templates - Ver3.3