PDA

View Full Version : Trying to understand.


superpally1
09-30-2018, 09:34 PM
I can not figure out why this first script works as it should, and the second one does not.

sub EVENT_SAY {

if ($text=~/armorset/i) {
# head armor ids 147587 = leather, 147580 = plate, 147573 = chain, 147566 = cloth
# chest armor ids 147588 = leather, 147581 = plate, 147574 = chain, 147567 = cloth
# leg armor ids 147591 = leather, 147584 = plate, 147577 = chain, 147570 = cloth

my $headid = $client->GetItemIDAt(2);
my $chestid = $client->GetItemIDAt(17);
my $legid = $client->GetItemIDAt(18);

if($headid == 147587 && $chestid == 147588 && $legid == 147591){ #leather
$client->Message(15,"3 pieces of armor equipped, $headid, $chestid, $legid.");
}
elsif($headid == 147587 && $legid == 147591){ #leather
$client->Message(15,"2 pieces of armor equipped, $headid, $legid.");
}
if($headid == 147580 && $chestid == 147581 && $legid == 147584){ #plate
$client->Message(15,"3 pieces of armor equipped, $headid, $chestid, $legid.");
}
elsif($headid == 147580 && $legid == 147584){ #plate
$client->Message(15,"2 pieces of armor equipped, $headid, $legid.");
}
if($headid == 147573 && $chestid == 147574 && $legid == 147577){ #chain
$client->Message(15,"3 pieces of armor equipped, $headid, $chestid, $legid.");
}
elsif($headid == 147573 && $legid == 147577){ #chain
$client->Message(15,"2 pieces of armor equipped, $headid, $legid.");
}
if($headid == 147566 && $chestid == 147567 && $legid == 147570){ #cloth
$client->Message(15,"3 pieces of armor equipped, $headid, $chestid, $legid.");
}
elsif($headid == 147566 && $legid == 147570){ #cloth
$client->Message(15,"2 pieces of armor equipped, $headid, $legid.");
}
}
}



sub EVENT_SAY {
if ($text=~/armorset/i) {
# head armor ids 147587 = leather, 147580 = plate, 147573 = chain, 147566 = cloth
# chest armor ids 147588 = leather, 147581 = plate, 147574 = chain, 147567 = cloth
# leg armor ids 147591 = leather, 147584 = plate, 147577 = chain, 147570 = cloth

my $headid = $client->GetItemIDAt(2);
my $chestid = $client->GetItemIDAt(17);
my $legid = $client->GetItemIDAt(18);

if ($headid == 147587||147580||147573||147566 && $chestid == 147588||147581||147574||147567 && $legid == 147591||147584||147577||147570){
$client->Message(15,"3 pieces of armor equipped, $headid, $chestid, $legid.");
}
elsif ($headid == 147587||147580||147573||147566 && $legid == 147591||147584||147577||147570){
$client->Message(15,"2 pieces of armor equipped, $headid, $legid.");
}
}
}

The second script will always output the 3 piece message regardless if you have all 3 pieces of gear on, 2 pieces, 1 piece, or no pieces.
If the item is not equipped the client->Message will just list -1 for the itemid for that slot.

The elsif statement is never reached.

Any help would be greatly appreciated.

Almusious
10-01-2018, 12:07 AM
sub EVENT_SAY {
if ($text=~/armorset/i) {
# head armor ids 147587 = leather, 147580 = plate, 147573 = chain, 147566 = cloth
# chest armor ids 147588 = leather, 147581 = plate, 147574 = chain, 147567 = cloth
# leg armor ids 147591 = leather, 147584 = plate, 147577 = chain, 147570 = cloth
my $headid = $client->GetItemIDAt(2);
my $chestid = $client->GetItemIDAt(17);
my $legid = $client->GetItemIDAt(18);
if ($headid ~~ [147587,147580,147573,147566] and $chestid ~~ [147588,147581,147574,147567 and $legid ~~ [147591,147584,147577,147570])
{
$client->Message(15,"3 pieces of armor equipped, $headid, $chestid, $legid.");
}
elsif ($headid ~~ [147587,147580,147573,147566] and $legid ~~ [147591,147584,147577,147570])
{
$client->Message(15,"2 pieces of armor equipped, $headid, $legid.");
}
}
}


Use smart matching against an array, much easier to do and look at. Would also consider a hash if you go with any more items fwiw.

Kingly_Krab
10-01-2018, 07:34 AM
“and” is not a valid bareword in Perl. Use && instead. Also, smart-matching is better if you predefine the arrays so it's much easier to understand what the random numbers are.

Almusious
10-02-2018, 02:12 AM
Indeed, "and" is instead a valid logical operator. You had me scratchin' my head trying to figure out what you meant, but I assume perl -c barfed on it because I placed the scalar values meant to be an array within brackets rather than parentheses. Serves me right for not bouncing it against Perl.


($headid ~~ (147587,147580,147573,147566) and ...


I left the comments in so the numbers didn't appear so random. Though, they may still appear random even if:


my @headpieces = (147587,147580,147573,147566);
if ($headid ~~ @headpieces) {


As aforementioned, I would consider doing a Hash of Hashes.

Maybe something along the lines of:


%HoH = (
'leather' => {
'head' => 147587,
'chest' => 147588,
'legs' => 147591,
},
'plate' => {
'head' => 147580,
'chest' => 147581,
'legs' => 147584,
},
'chain' => {
'head' => 147573,
'chest' => 147547,
'legs' => 147577,
},
'cloth' => {
'head' => 147566,
'chest' => 147567,
'legs' => 147570,
},
);


Though the nice thing about Perl and Eqemu in general, there are so many ways one can approach a problem to reach a solution. Sure, there are "better" ways, or perhaps even correct. For instance, placing the


my %elementshash = map { $_ => 1 } @headpieces;
if(exists($elementhash{$headid})) {


I am looking forward to see what you have cooking up superpally1. Assuming it's going to be a public server. :)

superpally1
10-02-2018, 01:45 PM
Thank you very much for the help! I understand now. I will post what im making soon as i finish it later today. And my server is always public if you want to stop by. Omen I :)

Almusious
10-03-2018, 08:35 PM
I wrote this late at night, pretty sure it will work out, though my comments -may- be off a little, maybe someone can correct me on any wrong points. We're all here to learn.


%HoH = (
'leather' => {
'head' => 147587,
'chest' => 147588,
'legs' => 147591,
},
'plate' => {
'head' => 147580,
'chest' => 147581,
'legs' => 147584,
},
'chain' => {
'head' => 147573,
'chest' => 147547,
'legs' => 147577,
},
'cloth' => {
'head' => 147566,
'chest' => 147567,
'legs' => 147570,
},
);

sub EVENT_SAY
{
if ($text=~/hasharmorset/i)
{
# doing the following assuming the player is wearing a plate head (ID 147580)
foreach $firstlevelkey (keys %HoH)
{
# iterate the parent keys of hash %HoH one by one and put the current key being read into $parentkey
# we will assume 'plate' was read first
$childhashref = $HoH{$firstlevelkey};
# make reference of first level hash based on current parent key (i.e. $parentkey)
# $childhashref now equals $HoH{plate}
foreach $secondlevelkey (keys %$childhashref)
{
# iterate the second level (child) keys of the dereferenced hash and put that key into $secondlevelkey
# could also be written %{$childhashref} - lets assume it pulls out the key 'head' from $HoH{plate}
if ($client->GetItemIDAt(2) == $HoH{$firstlevelkey}->{$secondlevelkey})
{
# $HoH{plate}->{head} is equal to its key value which is 147580 - a match, we know they have plate this iteration
quest::say("You are wearing a ".$firstlevelkey." ".$secondlevelkey." found within my Hash of Hashes");
}
}
}
}
}