Log in

View Full Version : check_hasitem issue or just bad Perl Code


Gaflack
11-26-2012, 08:52 AM
The below quest works but has issues.

Quest purpose: give info on updated a item and then take items and update.

The quest works fine taking turn-ins and giving the updated item. The issue is checking to see which item the person has so the NPC responds with proper instuctions.

It works fine if the person has the 1st-3rd updated item, if they have the 4th udated item or higher it bugs the client so bad you have to kill it (mouse functions die etc).

So to many calls to "check_hasitem"?


###############################################
# NPC: Ivy
# Zone: POK
# Quest: Charm Upgrade
###############################################

sub EVENT_SAY {

if($text=~/hail/i && plugin::check_hasitem($client, 132535)) {
quest::say("Hail, $name! Bring me your old charm and a Aviak Charm and I will upgrade your Charm");
}
elsif($text=~/hail/i && plugin::check_hasitem($client, 132538)) {
quest::say("Hail, $name! Bring me your old charm and a Shadow Boot from the Evil Tower and I will upgrade your Charm");
}
elsif($text=~/hail/i && plugin::check_hasitem($client, 132539)) {
quest::say("Hail, $name! Bring me your old charm and a Growler Canine and I will upgrade your Charm");
}
elsif($text=~/hail/i && plugin::check_hasitem($client, 132540)) {
quest::say("Hail, $name! Bring me your old charm and a Knights Eye from Sebilis and I will upgrade your Charm");
}
elsif($text=~/hail/i && plugin::check_hasitem($client, 132541)) {
quest::say("Hail, $name! Bring me your old charm and a Spiders Eye from the Velks Icy World and I will upgrade your Charm");
}
elsif($text=~/hail/i && plugin::check_hasitem($client, 132542)) {
quest::say("Hail, $name! Bring me your old charm and a Gem of the Void from 4 Arms and I will upgrade your Charm");
}
elsif($text=~/hail/i && plugin::check_hasitem($client, 132543)) {
quest::say("Hail, $name! Bring me your old charm and a Bugs Eye from Soldiers in the Grove and I will upgrade your Charm");
}
elsif($text=~/hail/i && plugin::check_hasitem($client, 132544)) {
quest::say("Hail, $name! Bring me your old charm and a Western Waste Wyrm Eye and I will upgrade your Charm");
}
elsif($text=~/hail/i && plugin::check_hasitem($client, 132545)) {
quest::say("Hail, $name! Bring me your old charm and a Undead Eye from the Umbral Skeletons and I will upgrade your Charm");
}
elsif($text=~/hail/i && plugin::check_hasitem($client, 132546)) {
quest::say("Hail, $name! Bring me your old charm and a Valor Eye form those Cave Mobs in Valor and I will upgrade your Charm");
}
}

sub EVENT_ITEM {
if(plugin::check_handin(\%itemcount, 132535 => 1, 13737 => 1)) { #Happy's Charm Aviak Char
quest::say("Very good!");
quest::summonitem(132538); #Happy's Silver
}
elsif(plugin::check_handin(\%itemcount, 132538 => 1, 29220 => 1)) { #Happy's Silver Shadow Boots
quest::say("Very Very good!");
quest::summonitem(132539); #Happy's Gold
}
elsif(plugin::check_handin(\%itemcount, 132539 => 1, 12977 => 1)) { #Happy's Gold Growler Tooth
quest::say("Ecellent!");
quest::summonitem(132540); #Happy's Electrum
}
elsif(plugin::check_handin(\%itemcount, 132540 => 1, 132548 => 1)) { #Happy's Electrum Knights Eye
quest::say("Happy Days!");
quest::summonitem(132541); #Happy's Platinum
}
elsif(plugin::check_handin(\%itemcount, 132541 => 1, 132549 => 1)) { #Happy's Platinum Spiders Eye
quest::say("Wonderfull!");
quest::summonitem(132542); #Happy's Velium
}
elsif(plugin::check_handin(\%itemcount, 132542 => 1, 9053 => 1)) { #Happy's Velium Gem of the Void
quest::say("Perfect!");
quest::summonitem(132543); #Happy's Clear
}
elsif(plugin::check_handin(\%itemcount, 132543 => 1, 132550 => 1)) { #Happy's Clear Bug Eye
quest::say("Fantanstic!");
quest::summonitem(132544); #Happy's Jade
}
elsif(plugin::check_handin(\%itemcount, 132544 => 1, 132551 => 1)) { #Happy's Jade Wyrm Eye
quest::say("Too Cool!");
quest::summonitem(132545); #Happy's Opal
}
elsif(plugin::check_handin(\%itemcount, 132545 => 1, 132552 => 1)) { #Happy's Opal Undead Eye
quest::say("Almost Done!");
quest::summonitem(132546); #Happy's Ruby
}
elsif(plugin::check_handin(\%itemcount, 132546 => 1, 132553 => 1)) { #Happy's Ruby Valor Eye
quest::say("Finished!");
quest::summonitem(132547); #Happy's Diamond
}

else {
#Return items if incorrect
plugin::return_items(\%itemcount);
}
}
#END of FILE

Thanks for any input,

Gaf

Drajor
11-26-2012, 10:07 AM
Heya Gaflack,

I don't know much about the check_hasitem method however I thought I would suggest a slightly different approach to what you are trying to achieve. Note that I wrote this quickly and as I am no perl expert there are probably some errors!

%ITEM_RESPONSE = (
132535, "Aviak Charm",
132538, "Shadow Boot from the Evil Tower",
132539, "Growler Canine",
132540, "Knights Eye from Sebilis",
132541, "Spiders Eye from the Velks Icy World",
132542, "Gem of the Void from 4 Arms",
132543, "Bugs Eye from Soldiers in the Grove",
132544, "Western Waste Wyrm Eye",
132545, "Undead Eye from the Umbral Skeletons",
132546, "Valor Eye form those Cave Mobs in Valor"
);

sub EVENT_SAY {
if ( $text=~/hail/i ) {
foreach $i (keys (%ITEM_RESPONSE)) {
if ( plugin::check_hasitem( $client, $i ) ) {
$t = $ITEM_RESPONSE{$i};
quest::say("Hail, $name! Bring me your old charm and a $t and I will upgrade your Charm");
}
}
}
}

Drajor
11-26-2012, 10:21 AM
So I got curious and had a look at the server side methods that are called from check_hasitem. I do not believe there is anything there which could cause the client to lock up so badly.

Also, something I failed to include in my code snippet and should also be included in your original code is a return / break after the check_hasitem has succeeded. Once you have found the item, there is no need to continue searching.

sorvani
11-26-2012, 10:55 AM
he was using elseif so it will automatically stop the entire if block once a match hits.
But yeah, in a loop you need a break to get out early.

Drajor
11-26-2012, 11:01 AM
Sorvani is right! Its late here :p

Gaflack
11-27-2012, 09:04 AM
Thanks for the post Drajor.

I did a little testing last night and it seems that when I try the script it not only kills the client it kills any other client I have running. Very Strange.

Things I am going to test:

Check that multi-client kill issue with different PC's and different Clients. I am thinking it is a zone issue since 2 clients were killed.

Replace items checked with standard Vendor items (maybe one of my items is messed up in the database).



Thanks,
Gaf

sorvani
11-27-2012, 10:54 AM
You should also take the hail check out of every line and simply wrap all the hand in checks in a single is hail like Drajor did in the loop example.

if($text=~/hail/i) {
if(plugin::check_hasitem($client, 132535)) {
quest::say("Hail, $name! Bring me your old charm and a Aviak Charm and I will upgrade your Charm");
} elsif(plugin::check_hasitem($client, 132538)) {
etc
}
} #end hail if block
} #end EVENT_SAY


additionally, you are using the return items poorly. it should be outside of ANY logic block at the end of the sub. There is no need for it to be in a logic check. as all the check_item stuff removes from the hash as it processes.
sub EVENT_ITEM {
if (some logic) {
stuff
} elsif(some other logic) {
other stuff
} else {
other other stuff
}
plugin::return_items
}

Gaflack
11-27-2012, 01:18 PM
Thanks for the post sorvani.

I really appreciate that you took the time to not just say 'your code is lame' but to show where to improve. After 20+ years away from any coding any help is a blessing. There are lots of us trolls out here who learn tons from posts where you show a better way to do something.

I will redo my quest then see if it kills my clients before I make my other tests.

Thanks again,

Gaf

lerxst2112
11-27-2012, 05:07 PM
If all the clients in the zone are disconnected then it sounds like the zone is crashing. Look in the world server logs to see if this is the case, and the appropriate zone server log to see if there is any useful information logged about why it is crashing.

Gaflack
11-28-2012, 11:21 AM
Ran some more checks and zone is crashing, clients in other zones ok. Check Processor during hails of npc with different quest items. Processor load goes from 1%, 10%, 12%, 13%, 100% (5sec), 100% 20sec, 100% till zone dies and clients crash. This was with item on client from 1st in list to 6th in list.

So it seems that the more I call check_hasitem the harder the load on the processor until it dies.

Going to replace created items with standard vendor items and retest.

Edit:
I thought of it after, hailing with no quest items kills client as server processor is maxed. Still I replace all items in script with standard vendor items and it does not change the results.

I replace the check_hasitem with a replacement that c0ncrete sent me, no difference.

BTW, tested on Titanium, SOD and UF.

I just replace the code with a 'Hail with click-able links' but would love to figure out what I am doing wrong.

Thanks,

Gaf

lerxst2112
11-28-2012, 07:06 PM
If the zone process is using 100% cpu for an extended period of time it is likely in an endless loop. You'd need to attach a debugger to it and break to see where.