Go Back   EQEmulator Home > EQEmulator Forums > Quests > Quests::Q&A

Quests::Q&A This is the quest support section

Reply
 
Thread Tools Display Modes
  #16  
Old 04-17-2015, 12:19 AM
markusdabrave's Avatar
markusdabrave
Sarnak
 
Join Date: Jan 2012
Location: Plano, TX
Posts: 69
Default

Ok, working, quasi-finished product:

Code:
sub castdelay{
	$delayOver = (time + @_[0]);
	while (time < $delayOver){}
	1;
}

sub EVENT_SPAWN {
	quest::settimer("portershout",90);
}

sub EVENT_TIMER {
	if($timer eq "portershout") {
	quest::shout("Porting to all druid locations! Hail me near tunnel to Qeynos Hills!");
	$random_number = int(rand(100))+30; ## Randomizes porter shout after initial 90 second delay but no less than 30 seconds between shouts
	quest::settimer("portershout", $random_number);
	}
}

sub EVENT_SAY{
	if ($text=~/Hail/i) {
		plugin::Whisper("Hail! Where would you like to go? [Surefall] Glade, [Butcherblock] Mountains, The [Feerrott], North [Karana], [Lavastorm] Mountains, [Misty] Thicket, [South Ro], [Steamfont] Mountains, West [Commonlands] or [Toxxulia] Forest?");
	}
	elsif ($text=~/Commonlands/i) {
	quest::say("Off to West Commonlands!");
	$npc->DoAnim(43); #Cast animation
	$client->SpellEffect(43,10); #Cast spell effect
	castdelay(5); #invoke delay subroutine
	quest::selfcast(34); #selfcast superior camo
	quest::movepc(21, 1427, 479, -51, 0); #move PC to (zoneid, x, y, z, heading)
	}
	elsif ($text=~/Surefall/i) {
	quest::say("Off to Surefall Glade!");
	$npc->DoAnim(43);
	$client->SpellEffect(43,10);
	castdelay(5);
	quest::selfcast(34);
	quest::movepc(3, -391, -209, 4.75, 0);
	}
	elsif ($text=~/butcherblock/i) {
	quest::say("Off to Butcherblock Mountains!");
	$npc->DoAnim(43);
	$client->SpellEffect(43,10);
	castdelay(5);
	quest::selfcast(34);
	quest::movepc(68, 1984, -2135, 0);
	}
	elsif ($text=~/feerrott/i) {
	quest::say("Off to The Feerrott!");
	$npc->DoAnim(43);
	$client->SpellEffect(43,10);
	castdelay(5);
	quest::selfcast(34);
	quest::movepc(47, -1885, 367, 13.57, 0);
	}
	elsif ($text=~/karana/i) {
	quest::say("Off to North Karana!");
	$npc->DoAnim(43);
	$client->SpellEffect(43,10);
	castdelay(5);
	quest::selfcast(34);
	quest::movepc(13, -1494, -2706, -7.5, 0);
	}
	elsif ($text=~/lavastorm/i) {
	quest::say("Off to Lavastorm Mountains!");
	$npc->DoAnim(43);
	$client->SpellEffect(43,10);
	castdelay(5);
	quest::selfcast(34);
	quest::movepc(27, 460, 460, -84.88, 0);
	}
	elsif ($text=~/misty/i) {
	quest::say("Off to Misty Thicket!");
	$npc->DoAnim(43);
	$client->SpellEffect(43,10);
	castdelay(5);
	quest::selfcast(34);
	quest::movepc(33, -1896, -490, 120.34, 0);
	}
	elsif ($text=~/south ro/i) {
	quest::say("Off to South Ro!");
	$npc->DoAnim(43);
	$client->SpellEffect(43,10);
	castdelay(5);
	quest::selfcast(34);
	quest::movepc(35, 317, -2034, -22.64, 0);
	}
	elsif ($text=~/steamfont/i) {
	quest::say("Off to Steamfont Mountains!");
	$npc->DoAnim(43);
	$client->SpellEffect(43,10);
	castdelay(5);
	quest::selfcast(34);
	quest::movepc(56, 1668, -1779, -108.07, 0);
	}
	elsif ($text=~/toxxulia/i) {
	quest::say("Off to Toxxulia Forest!");
	$npc->DoAnim(43);
	$client->SpellEffect(43,10);
	castdelay(5);
	quest::selfcast(34);
	quest::movepc(56, -357, 1099, -57.93, 0);
	}
}
Any optimization tips are more than welcome. Functionality-wise I think I'm there.
Reply With Quote
  #17  
Old 04-17-2015, 12:24 AM
ghanja's Avatar
ghanja
Dragon
 
Join Date: Aug 2012
Location: Hershey, PA
Posts: 499
Default

Code:
sub EVENT_SPAWN {
	quest::settimer("portershout",90);
}

sub EVENT_TIMER {
	if($timer eq "portershout") {
		quest::stoptimer("portershout");
		quest::shout("Porting to all druid locations! Hail me near tunnel to Qeynos Hills!");
		quest::settimer("portershout", int(rand(100))+30);
	}
}

sub EVENT_SAY {
my %porthash = (
				"butcher" => "Butcherblock Mountains",
				"feerrott" => "The Feerrott",
				"northkarana" => "North Karana",
				"lavastorm" => "Lavastorm Mountains",
				"misty" => "Misty Thicket",
				"sro" => "South Ro",
				"steamfont" => "Steamfont Mountains",
				"commons" => "West Commonlands",
				"toxxulia" => "Toxxulia Forest"
				);
	if ($text=~/Hail/i) {
		plugin::Whisper("Hail! Where would you like to go? ");
		foreach my $key (keys %porthash) {
			$client->Message(315, "[".quest::saylink($key, 1, $porthash{$key})."]");
		}
	}
	elsif (defined $porthash{$text}) {
		plugin::Whisper("Off to ".$porthash{$text}." you go!");
		quest::doanim(43);
		$client->SpellEffect(43,10);
		castdelay(5);
		quest::selfcast(34);
		quest::zone($text);
	}
}

sub castdelay{
	$delayOver = (time + $_[0]);
	while (time < $delayOver){}
	1;
}
Reply With Quote
  #18  
Old 04-17-2015, 12:37 AM
ghanja's Avatar
ghanja
Dragon
 
Join Date: Aug 2012
Location: Hershey, PA
Posts: 499
Default

I cannot immediately locate the sound file for ports, however, to give it a little flavor, you could put this before line 34 of the above code snippet (thus making it the new line 34):

Code:
$client->PlayMP3("twinkle001_loop.wav");
If you add the above make this line:

Code:
castdelay(5);
to

Code:
castdelay(9);
To correspond with the length of the wave file.
Reply With Quote
  #19  
Old 04-17-2015, 05:35 PM
Asylum
Sarnak
 
Join Date: Jun 2013
Posts: 81
Default

Congratulation on solving your puzzle. Now to tackle simplifying the code. As many have advised over the years, using an array or hash to handle multiple inputs and outputs is the best method to simplify code.

Basically you have a player /say "location" as input to the npc's EVENT_SAY subroutine, which triggers the wonderful spell animations and invis prior to porting to the various destinations as output. The inputs can be stored as a variable $playersaidthis and the outputs as a variable $portplayerhere in an associated array.

Your code will have a single if statement instead of an if/elsif for every destination and be about 90% shorter. Let us know how it works and once again, congratulations on solving your perl puzzle and learning more about scripting.

EDIT: haha, I forgot to hit send this morning and after I realized it this afternoon, ghanja had already posted the script I described.
Reply With Quote
  #20  
Old 04-17-2015, 06:44 PM
Kingly_Krab
Administrator
 
Join Date: May 2013
Location: United States
Posts: 1,589
Default

Here's my work around. This requires my plugin to be useful.

NPC Script:
Code:
@zones = ("butcher", "feerrott", "northkarana", "lavastorm", "misty", "sro", "steamfont", "commons", "toxxulia");
sub EVENT_SAY {
    if ($text=~/Hail/i) {
        plugin::Whisper("Hail! Where would you like to go?");
        plugin::Whisper(quest::saylink($_, 1, plugin::Zone("LN", $_))) for @zones;
    } elsif ($text!~/Hail/i && $text ~~ @zones) {
        plugin::Whisper("Give me just a moment to prepare.");
        $npc->SetEntityVariable("Client", $client->GetID());
        quest::settimer($text, 5);
    }
}

sub EVENT_TIMER {
    if($timer ~~ @zones) {
        quest::stoptimer($timer);
        $npc->SignalNPC(plugin::Zone("ID", $timer));
    }
}

sub EVENT_SIGNAL {
    if (plugin::Zone("SN", $signal) ~~ @zones) {
        $entity_list->GetClientByID($npc->GetEntityVariable("Client"))->Message(315, $npc->GetCleanName() . " whispers, 'Off to " . plugin::Zone("LN", $signal) . " you go!'");
        $entity_list->GetClientByID($npc->GetEntityVariable("Client"))->SignalClient($entity_list->GetClientByID($npc->GetEntityVariable("Client")), $signal);
    }
}
Player.pl (required):
Code:
sub EVENT_SIGNAL {
    if ($signal > 0 && $signal < 1000) {
        quest::zone(plugin::Zone("SN", $signal));
    }
}

Last edited by Kingly_Krab; 08-31-2021 at 09:33 PM..
Reply With Quote
  #21  
Old 04-17-2015, 07:04 PM
markusdabrave's Avatar
markusdabrave
Sarnak
 
Join Date: Jan 2012
Location: Plano, TX
Posts: 69
Default

LOL I feel like I won a prize

I'm about to give the array thing a try. I'm familiar with them, it's just understanding how Perl handles them. My next question was going to be can you do a case statement but I think you guys have pretty much answered that. I'll let you know how it works out

Kingly - Your plugin looks tremendously helpful. Stupid question: How do I use it? Do I need to copy it into the script or can it reside elsewhere as its own script waiting to be called upon?
Reply With Quote
  #22  
Old 04-17-2015, 07:06 PM
Kingly_Krab
Administrator
 
Join Date: May 2013
Location: United States
Posts: 1,589
Default

You need to create a Perl file in your plugins folder in your server folder. Name it whatever you want. Also, Perl has switches, but it's not necessary in this situation, nor have I ever found it necessary.
Reply With Quote
  #23  
Old 04-17-2015, 09:53 PM
markusdabrave's Avatar
markusdabrave
Sarnak
 
Join Date: Jan 2012
Location: Plano, TX
Posts: 69
Default

Code:
sub EVENT_SAY {
my %porthash = (
				"butcher" => "Butcherblock Mountains",
				"feerrott" => "The Feerrott",
				"northkarana" => "North Karana",
				"lavastorm" => "Lavastorm Mountains",
				"misty" => "Misty Thicket",
				"sro" => "South Ro",
				"steamfont" => "Steamfont Mountains",
				"commons" => "West Commonlands",
				"toxxulia" => "Toxxulia Forest"
				);
	if ($text=~/Hail/i) {
		plugin::Whisper("Hail! Where would you like to go? ");
		foreach my $key (keys %porthash) {
			$client->Message(315, "[".quest::saylink($key, 1, $porthash{$key})."]");
		}
	}
	elsif (defined $porthash{$text}) {
		plugin::Whisper("Off to ".$porthash{$text}." you go!");
		quest::doanim(43);
		$client->SpellEffect(43,10);
		castdelay(5);
		quest::selfcast(34);
		quest::zone($text);
	}
}
Ok this will take me a month to figure out own my own what all's going on here. It works though. So instead of typing a location, you've opted for clickable links. Very clever. It's a little over my head right now but I'll keep staring at it until it sinks in. It sort of does. Is there a way to make the zone list "<zone>, <zone>, <zone>" instead of a list?

About to try KKs. This one's definitely over my head. I've read about globals and entitys but haven't messed with them yet.

Also, side question brought up by the plugin thing:

Could I turn this into a plugin by saving it in the plugins folder?

Code:
sub castdelay{
	$delayOver = (time + $_[0]);
	while (time < $delayOver){}
	1;
}
Reply With Quote
  #24  
Old 04-17-2015, 11:57 PM
markusdabrave's Avatar
markusdabrave
Sarnak
 
Join Date: Jan 2012
Location: Plano, TX
Posts: 69
Default

KK, I'm getting a "<LINKER ERROR>" when I talk to the NPC where he would be listing the port locations. Does the players.pl need to be in plugins or part of the script? I've done something wrong apparently.
Reply With Quote
  #25  
Old 04-18-2015, 12:05 AM
Uleat's Avatar
Uleat
Developer
 
Join Date: Apr 2012
Location: North Carolina
Posts: 2,815
Default

That 'linker' error may be part of my bailiwick..though, quests are not.

Pretty sure that kicks in when there is missing information in the text link constructor.


I did test scripts to ensure that they worked when I pushed them. (EDIT: pushed the client translation version of the code)

Try having the npc 'say' the information so that you can verify that wrong/null parameters are not being passed.
__________________
Uleat of Bertoxxulous

Compilin' Dirty
Reply With Quote
  #26  
Old 04-18-2015, 12:35 AM
markusdabrave's Avatar
markusdabrave
Sarnak
 
Join Date: Jan 2012
Location: Plano, TX
Posts: 69
Default

Code:
 quest::say("Hail! Where would you like to go?");
        quest::say(quest::saylink($_, 1, plugin::Zone("LN", $_))) for @zones;
Also resulted in the linker error message for each location. Hopefully I did that right.

Side note:
Code:
 quest::saylink($_, 1, plugin::Zone("LN", $_)) for @zones;
Displays nothing.
Reply With Quote
  #27  
Old 04-18-2015, 12:51 AM
markusdabrave's Avatar
markusdabrave
Sarnak
 
Join Date: Jan 2012
Location: Plano, TX
Posts: 69
Default

So the ghanja's code works, but it sends me to the zone safe spots rather than the druid ring. Would it make sense to add the x,y,z,h values into the $porthash array and call them in a quest::movenpc rather than a quest::zone command? Something like this:

Code:
sub EVENT_SAY {
my %porthash = (
				"surefall" => ["Surefall Glade", 3, -391, -209, 4.75, 0],
				"butcher" => ["Butcherblock Mountains",68, 1984, -2135, 0],
				"feerrott" => ["The Feerrott",47, -1885, 367, 13.57, 0],
				"northkarana" => ["North Karana",13, -1494, -2706, -7.5, 0],
				"lavastorm" => ["Lavastorm Mountains",27, 460, 460, -84.88, 0],
				"misty" => ["Misty Thicket",33, -1896, -490, 120.34, 0],
				"sro" => ["South Ro",35, 317, -2034, -22.64, 0],
				"steamfont" => ["Steamfont Mountains",56, 1668, -1779, -108.07, 0]
				"commons" => ["West Commonlands", 21, 1427, 479, -51, 0],
				"toxxulia" => ["Toxxulia Forest", 56, -357, 1099, -57.93, 0],
				);
	if ($text=~/Hail/i) {
		plugin::Whisper("Hail! Where would you like to go? ");
		foreach my $key (keys %porthash) {
			$client->Message(315, "[".quest::saylink($key, 1, $porthash{$key})."]");
		}
	}
	elsif (defined $porthash{$text}) {
		plugin::Whisper("Off to ".$porthash{$text}." you go!");
		quest::doanim(43);
		$client->SpellEffect(43,10);
		castdelay(5);
		quest::selfcast(34);
		#quest::zone($text);
		quest::movenpc($porthash{$key}[1],[2],[3],[4],[5]);
	}
}
... which is broke, probably a syntax thing on my part. This is more a 'am I on a path that makes sense' question. I'm still figuring out hash arrays. I've at least found some references but you know how it is. Reading, doing and understanding are 3 completely different things
Reply With Quote
  #28  
Old 04-18-2015, 12:53 AM
Uleat's Avatar
Uleat
Developer
 
Join Date: Apr 2012
Location: North Carolina
Posts: 2,815
Default

Here is where that text comes from: https://github.com/EQEmu/Server/blob...ient.cpp#L8394

Let me take your script home tonight to verify that it's not code-related..and hopefully someone will come up with a solution before
I get back tomorrow.


EDIT: Just read your last post..I'll still look it over and see where you are when I get back.
__________________
Uleat of Bertoxxulous

Compilin' Dirty
Reply With Quote
  #29  
Old 04-18-2015, 01:26 AM
markusdabrave's Avatar
markusdabrave
Sarnak
 
Join Date: Jan 2012
Location: Plano, TX
Posts: 69
Default

LOL I don't think I'll make any more progress tonight. As I was reading, there are many ways to do things in Perl. I'm interested in seeing either way This is a learning experience for me.
Reply With Quote
  #30  
Old 04-18-2015, 01:47 AM
Kingly_Krab
Administrator
 
Join Date: May 2013
Location: United States
Posts: 1,589
Default

Did you actually create a plugin file in your plugins folder in your base server folder? Mine is C:/EQ/EQEmuServer/plugins, you may have it in something like C:/EQ/EQEmuServer/quests/plugins or C:/EQ/EQEmuServer/quests/global.

Correct folder (C:/EQ/EQEmuServer/plugins):


Incorrect folder (C:/EQ/EQEmuServer/quests/plugins or C:/EQ/EQEmuServer/quests/global):
Reply With Quote
Reply


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 08: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