PDA

View Full Version : regular expression/comments issues


c0ncrete
11-12-2012, 02:23 PM
i just ran into a really weird problem that i can't seem to sort out and i was wondering if someone could take a look at it and tell me if i'm doing something obviously wrong.

the following script works as expected. all of the patterns that i have stored as scalars are matching correctly.


use strict;
use warnings;

my $kobolds = '^#(broken|over|pox|s(elan|l(a|i)ve|pider)|the)|(a _)?glooming';
my $spiders = '^#venom|a_gloom(_|f)';
my $rats = '^#r(at|uf)|a_(cave|diseased)_r';

my @kobold_list = (
'#Brokenclaw',
'#Overlord Gnikan',
'#Pox',
'#Selandoor',
'#Slavemaster Ruga',
'#Sliver',
'#Spider_Tamer_Gugan',
'#The_Gloomingdeep_Locksmith',
'a_garroted_kobold',
'a_Gloomingdeep_captain',
'a_Gloomingdeep_grunt',
'a_Gloomingdeep_plaguebearer',
'a_Gloomingdeep_slave_warden',
'a_Gloomingdeep_spiritweaver',
'a_Gloomingdeep_warrior',
'Gloomingdeep_Spiritweaver',
'Gloomingdeep_Taskmaster',
'a_kobold_barrel'
);

foreach my $npc (@kobold_list) {
if ( $npc =~ m/$kobolds/i ) {
print "MATCHED: $npc\n";
}
else {
print "NOT MATCHED: $npc\n";
}
}

print "\n";

my @spider_list = (
'#Queen_Gloomfang',
'#Venomfang',
'a_gloom_spider',
'a_gloom_spiderling',
'a_gloomfang_luker',
'a_small_spider'
);

foreach my $npc (@spider_list) {
if ( $npc =~ m/$spiders/i ) {
print "MATCHED: $npc\n";
}
else {
print "NOT MATCHED: $npc\n";
}
}

print "\n";

my @rat_list = (
'#Ratasaurus',
'#Rufus',
'a_cave_rat',
'a_diseased_rat',
'a_small_rat'
);

print "\n";

foreach my $npc (@rat_list) {
if ( $npc =~ m/$rats/i ) {
print "MATCHED: $npc\n";
}
else {
print "NOT MATCHED: $npc\n";
}
}
running it results in the following output:
(for some reason an extra newline is printed after the final $npc in @spider_list)
C:\EQEmu\sandbox>perl test_matches.pl
MATCHED: #Brokenclaw
MATCHED: #Overlord Gnikan
MATCHED: #Pox
MATCHED: #Selandoor
MATCHED: #Slavemaster Ruga
MATCHED: #Sliver
MATCHED: #Spider_Tamer_Gugan
MATCHED: #The_Gloomingdeep_Locksmith
NOT MATCHED: a_garroted_kobold
MATCHED: a_Gloomingdeep_captain
MATCHED: a_Gloomingdeep_grunt
MATCHED: a_Gloomingdeep_plaguebearer
MATCHED: a_Gloomingdeep_slave_warden
MATCHED: a_Gloomingdeep_spiritweaver
MATCHED: a_Gloomingdeep_warrior
MATCHED: Gloomingdeep_Spiritweaver
MATCHED: Gloomingdeep_Taskmaster
NOT MATCHED: a_kobold_barrel

NOT MATCHED: #Queen_Gloomfang
MATCHED: #Venomfang
MATCHED: a_gloom_spider
MATCHED: a_gloom_spiderling
MATCHED: a_gloomfang_luker
NOT MATCHED: a_small_spider


MATCHED: #Ratasaurus
MATCHED: #Rufus
MATCHED: a_cave_rat
MATCHED: a_diseased_rat
NOT MATCHED: a_small_ratthe moment i add a comment anywhere in the script, nothing beneath that line will execute. i've tried escaping the # symbols in the patterns and everything else i could possibly think of, all to no avail.

i'm at a loss here... any ideas?

c0ncrete
11-12-2012, 02:49 PM
found the newline issue... duh.
the problem with the comments still exists, however.

c0ncrete
11-12-2012, 03:32 PM
it's got to be an issue with the definition of the arrays or iterating over the elements, but i don't completely follow why it would be problematic. the following script gets to the end of the file and prints PASSED (even with the original regexp patterns):


use strict;
no strict 'vars';
use warnings;

# matches named and generic gloomingdeep kobolds
my $kobolds = '(?=^(#([bopt]|s(e|l[ai]|p))|(a_)?gloomi))';
# matches named and generic gloom/fang spiders (not queen)
my $spiders = '(?=^(#v|a_gloom[_f]))';
# matches named and generic rats
my $rats = '(?=^(#r[au]|a_(cave|diseased)_r))';

sub EVENT_SAY
{
if ( !$npc || $npc->GetOwnerID() || $npc->GetSwarmOwner() ) {
return;
}
if ( $text =~ /hail/i ) {
quest::say("Shh! I think I hear the kobolds...");
}
}

sub EVENT_ITEM
{
if ( !$npc || $npc->GetOwnerID() || $npc->GetSwarmOwner() ) {
plugin::GivePetItems();
return;
}
plugin::return_items(\%itemcount);
}

sub EVENT_COMBAT
{
if ( $combat_state ) {
if ( $mname =~ /$kobolds/i ) {
quest::emote("brandishes razor sharp claws and circles inward.");
}
elsif ( $mname =~ /$spiders/i ) {
quest::emote("scuttles forward to attack.");
}
elsif ( $mname =~ /#queen/i ) {
quest::emote("brandishes razor sharp fangs and attacks!");
}
elsif ( $mname =~ /$rats/i ) {
quest::emote("races forward to attack.");
}
}
}

sub EVENT_DEATH
{
if ( $mname =~ /$kobolds/i ) {
quest::emote("unleashes a lupine yelp as it collapses on the floor.");
}
elsif ( $mname =~ /$spiders/i ) {
quest::emote("collapses in a heap of broken legs.");
}
elsif ( $mname =~ /#queen/i ) {
quest::emote("'s corpse unleashes a chittering keen as it falls backward.");
}
elsif ( $mname =~ /$rats/i ) {
quest::emote("'s corpse stops moving.");
}
}

print "PASSED\n";
i'll be testing in-game to make sure it works as expected.

c0ncrete
11-17-2012, 01:45 PM
ok, i've sorted out that declaring any variables outside of a subroutine in a zone's default.pl causes problems. the thing is, i don't understand why. is it a bug? is it an unintended limitation due the way the namespaces are dynamically created by npcs that use the default script? is it working as intended?

the way i found out this is what was causing me issues is that i added the following line to the beginning of the script

quest::shout(__PACKAGE__);without any declarations in what i assume would usually be called 'main', i get a handful of messages in the zone like this:

a cave rat shouts 'qst189410'
a cave rat shouts 'qst189408'
a cave rat shouts 'qst189409'

when this occurs, npcs without an explicitly defined quest script respond as they should, using the default script.

as soon as i try to declare a variable outside of any subroutine, i only see a single shout and nothing works properly.

i'm guessing that there is some relatively simple concept i'm just not grasping about the quest interface, but i don't know what it might be. any information would be much appreciated.

c0ncrete
11-17-2012, 02:05 PM
using a work-around of declaring global variables using keyword 'our' instead of 'my' from within EVENT_SPAWN seems to work, but i'm still confused as to why declaring outside of a subroutine would break the script.

Noport
11-17-2012, 03:52 PM
sub EVENT_ITEM {
if (plugin::check_handin(\%itemcount,xxxxx=>1))<-------- needs to be added
if ( !$npc || $npc->GetOwnerID() || $npc->GetSwarmOwner() ) {
plugin::GivePetItems();
return;
}
plugin::return_items(\%itemcount);
}

c0ncrete
11-17-2012, 04:11 PM
sub EVENT_ITEM {
if (plugin::check_handin(\%itemcount,xxxxx=>1))<-------- needs to be added
if ( !$npc || $npc->GetOwnerID() || $npc->GetSwarmOwner() ) {
plugin::GivePetItems();
return;
}
plugin::return_items(\%itemcount);
}


oh really?

please explain why i'd need to use plugin::check_handin() if i'd want every npc that uses default.pl to return the every item they were given, unless they were a pet. when you're done with that exercise in futility, you can try to explain what your suggestion has to do with anything in this thread.