EQEmulator Forums

EQEmulator Forums (https://www.eqemulator.org/forums/index.php)
-   Quests::Q&A (https://www.eqemulator.org/forums/forumdisplay.php?f=599)
-   -   Hash Array in Perl Question (https://www.eqemulator.org/forums/showthread.php?t=40693)

Shin Noir 06-14-2016 04:28 AM

Hash Array in Perl Question
 
I got this little plugin i'm mucking around, this is just a snippet, but the idea is still there:

The problem: quest::say always just says "Requires " once, and never iterates/echos anything of note.

pastebin probably easier to read.

http://pastebin.com/NGwDt2Rj
Code:

sub DoArmorHandin {
 
    my $armor_list;
    $tmp_zone = 113;
    $tmp_class = 9;
    $armor_list[$tmp_zone][$tmp_class][6] = {slot => 19, item => 24938, reward => 31014}; #boots
 
    foreach my $entry ($armor_list[$zoneid][$class]) {
        quest::say("Requires ".$entry);
        if (plugin::check_handin(\%itemcount,$entry{item}) => 1 &&
            $cash >= (plugin::DoPricingBySlot($entry{slot})*1000)) {
            quest::summonitem($entry{reward});
            return 1;
        }
    }
    return 0;
}


Kingly_Krab 06-14-2016 04:47 AM

Change this:
Code:

foreach my $entry ($armor_list[$zoneid][$class]) {
To this:
Code:

foreach my $entry (@{$armor_list[$zoneid][$class]}) {

Kingly_Krab 06-14-2016 04:48 AM

That change uses Perl's dynamic type casting and allows the foreach to recognize it as an array rather than a singular variable.

Shin Noir 06-14-2016 05:57 AM

I was still having some peculiar issues, that aside though.. my next issue is..

I'm trying to check_handin and it seems to always be empty with itemcount, so, i'm trying to pass itemcount, similar to how check_handin does it.

Code:

plugin::velious_armor_handin($zoneid, $cash, $client->GetClass(), \%itemcount)
I call it itemref. the Got Item! line never triggers, even if I use proper item id.
Code:

sub velious_armor_handin {
        my $zoneid = shift;
        my $cash = shift;
        my $classid = shift;
        my $itemref = shift; #I don't know if perl does a pointer reference or what, emulating check_handin's code to pass along
        my $armor_list = plugin::velious_armor_list();
               
        for $x (0...6) {
                $slot = $armor_list[$zoneid][$classid][$x]{slot};
                $item = $armor_list[$zoneid][$classid][$x]{item};
                $reward = $armor_list[$zoneid][$classid][$x]{reward};
                quest::say("Looking for $slot in $item for reward $reward");               
                if (plugin::check_handin(\%itemref, $item => 1)) { #i'm passing itemref here, to check_handin.
                        quest::say("Got item!"); #this line never echos.
                        if ($cash >= (plugin::pricing_by_slot($slot)*1000)) {
                                quest::summonitem($reward);
                                return 1;
                        } else { #fail!
                                return 0;
                        }
                }
        }
        return 0;
}


ghanja 06-14-2016 09:43 AM

Would be curious to see the hash itself as it looks like a hash of arrays of arrays, however, at a very quick glance as I'm just perusing with limited time atm:

Code:

for $x (0...6) {
You have an extra period in the range operator.

I assume this hash that you're concocting contains quest hand-in/reward?

Shin Noir 06-14-2016 03:47 PM

Didn't even see that, but oddly, perl is OK with three dots. I'll change it up to ensure no other side effects.
http://codepad.org/7A83V6CT

The challenge/solution I originally posted I ended up re-approaching and iterating the $armor_list as an array, and then grabbing the hash data as seen on the bottom example.

My only snag now is that I'm trying to transfer the %itemcount hash to plugin::check_handin() via another function, plugin::velious_armor_handin() and for some reason, passing the variable from function to function is not doing pointer refs. May end up picking up a programming book about perl, but figured perl experts can peek and be like "Do X instead of Y", and save me a ton of time of fiddling and google research that inevitably is probably a 2 line fix.

c0ncrete 06-14-2016 04:08 PM

from http://perldoc.perl.org/perlref.html

"References are easy to use in Perl. There is just one overriding principle: in general, Perl does no implicit referencing or dereferencing. When a scalar is holding a reference, it always behaves as a simple scalar. It doesn't magically start being an array or hash or subroutine; you have to tell it explicitly to do so, by dereferencing it."

Shin Noir 06-14-2016 05:17 PM

Thanks c0ncrete. So the answer to my question is: \%{$itemref}

Code:

sub velious_armor_handin {
        my $zoneid = shift;
        my $cash = shift;
        my $classid = shift;
        my $itemref = shift; #I don't know if perl does a pointer reference or what, emulating check_handin's code to pass along
        my $armor_list = plugin::velious_armor_list();
               
        for $x (0...6) {
                $slot = $armor_list[$zoneid][$classid][$x]{slot};
                $item = $armor_list[$zoneid][$classid][$x]{item};
                $reward = $armor_list[$zoneid][$classid][$x]{reward};
                quest::say("Looking for $slot in $item for reward $reward");               
                if (plugin::check_handin(\%{$itemref}, $item => 1)) { #i'm passing itemref here, to check_handin.
                        quest::say("Got item!"); #this line never echos.
                        if ($cash >= (plugin::pricing_by_slot($slot)*1000)) {
                                quest::summonitem($reward);
                                return 1;
                        } else { #fail!
                                return 0;
                        }
                }
        }
        return 0;
}


ghanja sent me a PM that informed shift is destructive and pulls data out of the argument list @_ so, I will keep that in mind while I finish fixing other issues.

This is all complete, and I posted the solutions to my question on each part, for anyone else who may have similar questions.

Thanks for your help guys.

c0ncrete 06-14-2016 05:23 PM

it's been a very long time since i've been eyeball deep in perl, but that looks syntactically correct at least. i don't have my old work to reference at the moment (at the office currently), but i'll be digging up some old stuff where i was using references all over the place when i get back to the house in a few hours.

Shin Noir 06-14-2016 05:28 PM

my tl;dr to answer my own question:

perl == c++

/$var == &var
{$var} == *var


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

Powered by vBulletin®, Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.