PDA

View Full Version : Check_handin


Disorder
02-17-2013, 04:38 AM
Greetings!

I'm having trouble with this quest. I cannot get check_handin to function as I see it in other peoples quests. First, here is my quest code...

##################################
# Ragged Jep NPCID: 1000
# Qeynos
# Blue Fish Meat Quest
# Ragged Jep's Rusty Fishing Hook Quest
# Ragged Jep's Bobber Quest
# Created 02/16/2013 by Disorder
##################################

$help = quest::saylink("help");
$fish = quest::saylink("Ol' Chomper");
$bobber = quest::saylink("Prized Fishing Bobber");
$food = quest::saylink("fish meat");
$more = quest::saylink("more");

sub EVENT_SPAWN
{
quest::set_proximity($x - 35, $x + 35, $y - 35, $y + 35);
}

sub EVENT_ENTER
{
if ($ulevel <=2)
{
$client->Message (315, "Ragged Jep whispers to you, 'Woah, good thing I decided to go fishing today! Come over and talk with me when you gather your bearings.'");
}
}

sub EVENT_SAY
{
if ($text=~/Hail/i)
{
plugin::Whisper("Hello, $name! I'm Jep, just a poor fisherman. I really thought I was going to be rich! I thought I caught $fish! Nope, thats not my luck today.
What were you doing floating out there anyway? Well, I'm the hero of the day. Hey, since you're already wet, how about giving me some $help?");
}

if($text=~/help/i)
{
plugin::Whisper("Oh thank you! I lost my $bobber to one of those darn fish. Do you think you could retrieve it for me? While you're looking for it, could you get me some $food?
Since I lost my Prized Fishing Bobber, I have not been able to catch fish like normal. I'm so hungry!");
}

elsif($text=~/Prized Fishing Bobber/i)
{
plugin::Whisper("Oh yes! I won it in a bet with Dolorn McHorn, the Harbor Manager. He's not been so busy since ships haven't been able to come to town. He's taken up drinking instead.
Lucky for me, he made a drunk bet, and lost. Now I can feed myself quite well... until I lost the bobber. Bring it back to me when you find it!");
}

elsif($text=~/fish meat/i)
{
plugin::Whisper("Yes, I'm so hungry! I really could go for some Blue Fin fish meat. Four pieces ought to do the trick for today.");
}

elsif($text=~/Ol' Chomper/i)
{
plugin::Whisper("WHERE?!?! Oh.. whew. Yeah. right. Sorry, I get a little jumpy. He's the reason I fish from the shore and not on my old rickety boat here. Some say Ol' Chomper is just
a story made up to scare kids. I've seen him! Everyone thinks I'm crazy. One time in my old boat, I was fishing in the deeper waters when out of nowhere
Ol' Chomper surfaced. About ate me and the boat whole! I was able to lodge my boat ore in his jaws, just in time to escape. Bah, who cares. No one believes me anyway.");
}
elsif($text=~/more/i)
{
plugin::Whisper("Oh, I'm glad you asked. I'm emberrased to say. One evening while I was on the docks south of here, Dolorn McHorn managed to sneak up behind me while I was gutting my fish.
The bastard pushed me into the water! I'm not a strong swimmer and my knife that I use to gut fish fell to the ocean floor. I can't swim that deep to get it.
Would you retrieve it for me?");
}

}

sub EVENT_ITEM
{
if ((plugin::check_handin(\%itemcount, 1373 => 4)))
{
plugin::Whisper("Thanks, $name! Perhaps you would be interested in helping me some $more?");
quest::exp("20000");
quest::ding();
}

elsif ((plugin::check_handin(\%itemcount, 1378 => 1)))
{
plugin::Whisper("Oh thank you so much, $name! I can't wait to show Dolorn McHorn's drunk arse that I got my bobber back. He was quite delighted to know I had lost it.");
quest::exp("45000");
quest::ding();
}

elsif ((plugin::check_handin(\%itemcount, 1377 =>1)))
{
if (($ulevel <= 5 && !defined $qglobals{jep_knife}))
{
quest::setglobal("jep_knife","1","4","M30");
quest::exp("20000");
quest::ding();
}

else
{
plugin::return_items(\%itemcount);
plugin::Whisper("Oh, $name, you already brought my knife back. Thank you though! You can have this one back.");
}

}

else
{
plugin::return_items(\%itemcount);
quest::Whisper("I don't want that. Here, take it back, $name.");
}

}

## END OF QUEST ##

Notice for example this:

elsif ((plugin::check_handin(\%itemcount, 1378 => 1)))

If i do not wrap this in so many parenthesis my quest stops functioning completely. Quests from the DB read like this:

elsif (plugin::check_handin(\%itemcount, 25832 => 3, 24934 => 1))

Not a huge deal, but I think I may be making a mistake some where else.

Also, I can not get this section of the code to work properly...

elsif ((plugin::check_handin(\%itemcount, 1377 =>1)))
{
if (($ulevel <= 5 && !defined $qglobals{jep_knife}))
{
quest::setglobal("jep_knife","1","4","M30");
quest::exp("20000");
quest::ding();
}

else
{
plugin::return_items(\%itemcount);
plugin::Whisper("Oh, $name, you already brought my knife back. Thank you though! You can have this one back.");
}

}

The npc will say the text nested in the else statement, but he will not return the item. He returns all other items from the following else statement in the parent if statement.

Any help would be appreciated. Don't mind my horrible quest writing creativity. Got to start somewhere :)

Have fun!

c0ncrete
02-17-2013, 05:44 AM
the call to return_items should be outside of any conditional and located at the bottom of EVENT_ITEMS so as to return any unused items.

if you make a call to check_handin before you check other requirements, you'll have to summon the item if you want to return it, because check_handin will always consume the items sent as parameters, deleting them from %itemcount. either that or add the item to %itemcount and allow return_items to handle it at the bottom of the event.

ghanja
02-17-2013, 05:50 AM
Was just about to crash for the night.


elsif (($ulevel <= 5) && (!defined $qglobals{jep_knife})) ## If this quest line done why go any farther?
{
if ((plugin::check_handin(\%itemcount, 1377 =>1 )))
{
quest::setglobal("jep_knife","1","4","M30");
quest::exp("20000");
quest::ding();
}
}
else
{
plugin::return_items(\%itemcount);
plugin::Whisper("I don't want that. Here, take it back, $name.");
}
}


You're looking for an item match a quest line that the person may not be eligible for due to the defined qglobal, rather than checking if they can do it first.

That will cause the hiccup as well as not returning the item.. because you're telling it item 1377 in a quantity of 1 is a valid item, with the check_handin, so it is removing that item from the hash, thus, won't return it even with the return_items call.

Hope the above fixes the issue, if not it should at least get you started, am to "wake up" in two hours due to a forgotten appointment. Got to run. Good luck.

ghanja
02-17-2013, 05:51 AM
Bleh had I known c0ncrete was on I would have crashed instead of bothering.. frickin Perl ninja he is. :p

c0ncrete
02-17-2013, 06:43 AM
i'd do something like this, but i'm extremely picky... :)

elsif ( # consume knife only if
$ulevel < 6 # client is under level 6
&& !defined $qglobals{jep_knife} # and has not turned it in yet
&& plugin::check_handin( \%itemcount, 1377 => 1 )
)
{
# FYI: this will allow another turn-in after 30 minutes...
quest::setglobal( "jep_knife", "1", "4", "M30" );
quest::exp("20000");
quest::ding();
}

# if the knife has already been turned in
# and the client is attempting to turn it in again
my $knife_back = 0;
if ( defined $qglobals{jep_knife} && defined $itemcount{1377} ) {
plugin::Whisper( "Oh, $name, you already brought my knife back. "
. "Thank you though! You can have this one back." );
my $knife_back = 1;
}

# determine how many items are left in %itemcount to return
# NOTE: we're counting the knife if it has not been addressed above
# because ( $ulevel > 5 && !defined $qglobals{jep_knife} ) is possible
my $return_count = ( scalar keys %itemcount ) - $knife_back;

# if we're returning at least one item that we have not addressed,
# then we'll use some additional item return flavor text
# NOTE: %itemcount will always have at least one key (0)
if ( $return_count > 1 ) {

# this is the text template we'll use in the call to sprintf
my $return_template = "I don't want %s. Here, take %s back, $name.";

# if we have more than 1 item going back that is not addressed,
# use plural nouns... otherwise, use singular nouns
my @return_noun =
$return_count > 2
? ( "these", "them" )
: ( "this", "it" );

# put the template and the nouns together here
plugin::Whisper( sprintf $return_template, @return_noun );
}

# give stuff back
plugin::return_items( \%itemcount );
}


i commented everything so you can get an idea of what's going on.

Disorder
02-17-2013, 01:19 PM
Thanks for all the responses. c0ncrete, I'm not sure I understand your code. I know you even took the time to add notes, but this one is beyond me. I'll tinker around with it. I think you just use functions I am not familiar with.

Have fun!

c0ncrete
02-17-2013, 03:00 PM
if it helps any, it is intended to replace the bottom part of your EVENT_ITEM subroutine, starting at (and including) your check for the hand in of the knife. if you have any specific questions, i'd be more than happy to answer them.

Disorder
02-19-2013, 10:56 AM
[QUOTE=c0ncrete;218378]i'd do something like this, but i'm extremely picky... :)

elsif ( # consume knife only if
$ulevel < 6 # client is under level 6
&& !defined $qglobals{jep_knife} # and has not turned it in yet
&& plugin::check_handin( \%itemcount, 1377 => 1 )
)
{
# FYI: this will allow another turn-in after 30 minutes...
quest::setglobal( "jep_knife", "1", "4", "M30" );
quest::exp("20000");
quest::ding();
}

# if the knife has already been turned in
# and the client is attempting to turn it in again
my $knife_back = 0;
if ( defined $qglobals{jep_knife} && defined $itemcount{1377} ) {
plugin::Whisper( "Oh, $name, you already brought my knife back. "
. "Thank you though! You can have this one back." );
my $knife_back = 1;
}

# determine how many items are left in %itemcount to return
# NOTE: we're counting the knife if it has not been addressed above
# because ( $ulevel > 5 && !defined $qglobals{jep_knife} ) is possible
my $return_count = ( scalar keys %itemcount ) - $knife_back;

# if we're returning at least one item that we have not addressed,
# then we'll use some additional item return flavor text
# NOTE: %itemcount will always have at least one key (0)
if ( $return_count > 1 ) {

# this is the text template we'll use in the call to sprintf
my $return_template = "I don't want %s. Here, take %s back, $name.";

# if we have more than 1 item going back that is not addressed,
# use plural nouns... otherwise, use singular nouns
my @return_noun =
$return_count > 2
? ( "these", "them" )
: ( "this", "it" );

# put the template and the nouns together here
plugin::Whisper( sprintf $return_template, @return_noun );
}

# give stuff back
plugin::return_items( \%itemcount );
}


I used this code and when the knife is returned after q globals is set, he says the return statement for the knife specifically and the return statement for all other items. Any idea why? Also, can you explain how %return_count and sprintf work?

c0ncrete
02-19-2013, 11:08 AM
he says the return text for the knife as well as for any additional item(s) that are returned? if so, it's because that's what it is supposed to do.

sprintf info found here:
http://perldoc.perl.org/functions/sprintf.html

%itemcount is a hash that is populated by the server when you hand in items. the keys are item numbers, and the values are the count of that item that was turned in. things may end up changing when the inventory system is reworked.

ghanja
02-19-2013, 11:13 AM
$return_count is the (explicit) size of the hash %itemcount less the value of $knife_back, which is 0 unless the qglobal and the itemcount hash contains item 1377 (which itself is the list, more less, of what you handed the npc) in which case it equals 1

ghanja
02-19-2013, 11:14 AM
... alright then, need to start using two instances of FF constantly refreshing on one while writing replies on the other. :p

c0ncrete
02-19-2013, 11:21 AM
oops. i misread the question. he was asking about $return_count, not %itemcount. what he said.

Disorder
02-19-2013, 11:37 AM
c0ncrete,

When JUST the knife is returned he says the text

my $knife_back = 0;
if ( defined $qglobals{jep_knife} && defined $itemcount{1377} ) {
plugin::Whisper( "Oh, $name, you already brought my knife back. "
. "Thank you though! You can have this one back." );
my $knife_back = 1;
}

AND

if ( $return_count > 1 ) {

# this is the text template we'll use in the call to sprintf
my $return_template = "I don't want %s. Here, take %s back, $name.";

Disorder
02-19-2013, 11:38 AM
Sorry for double post. Is he supposed to say he doesn't want the item twice?

c0ncrete
02-19-2013, 11:42 AM
no, that wasn't intended. lemme wake up a bit more before i try to fix it or i'll probably just make it worse. :)

c0ncrete
02-19-2013, 12:12 PM
oops. i double posted as well. sheesh....

c0ncrete
02-19-2013, 12:13 PM
this should fix it.

my $return_count = ( ( scalar keys %itemcount ) - $knife_back );

joligario
02-19-2013, 02:08 PM
Just a comment: glancing at the work above, it seems it is getting way more complicated than it should be.

c0ncrete
02-19-2013, 02:27 PM
sure, he could very easily have chosen to use generic text (or none at all) when handing the unused items back, but that's pretty boring.

Disorder
02-20-2013, 04:40 PM
Sorry for delayed response. Been so busy. I'll take a look at this and let ya know.

Disorder
02-21-2013, 01:10 PM
Finally got to test it. I still get this response:

[Thu Feb 21 11:09:25 2013] Ragged Jep whispers, 'Oh, Disorder, you already brought my knife back. Thank you though! You can have this one back.'
[Thu Feb 21 11:09:25 2013] Ragged Jep whispers, 'I don't want this. Here, take it back, Disorder.'


Any suggestions, mate? :)

c0ncrete
02-21-2013, 02:21 PM
it's the superfluous 'my' before setting $knife_back to 1. that causes $knife_back to have a value of 1 only inside of that block (it's a completely separate instance of the variable, actually). total newbie mistake on my part.