\s*(.*?)\s*<\/em><\/p>/;
$num++;
$spellname= $1;
$spellname=~s//'/g;
$spellname=~s/ / /g;
$spellname=~s/Mord's/Mordenkein's/;
$self->newspell($spellname);
} elsif (not $spellname) {
next; # ignore text before a spell is there
} elsif (/<\/body/) {
last;
} elsif ((/^( )?([\w\s,\/]+):/) && isastat($2)) {
# the stat may go over line - continue until )?([\w\s,\/]+):\s+(.*?)\s*( )(\w+)\s*(.*)( )(\w+)\s*(.*) )?As ([^,]+),/ and not
$self->getstat($spellname,"Description")) {
my $basespell= $2;
$basespell=~s//'/g;
$self->setstat($spellname,"Base Spell",$basespell);
}
# description is previous description plus this line
my $descrip= $self->getstat($spellname,"Description") . $_;
$self->setstat($spellname,"Description",$descrip);
}
}
close($fh);
return $num;
}
######################################################################
=item readlistfile
This takes in a filename and parses it for class spell lists in
the original SRD format.
=cut
sub readlistfile {
my $self= shift;
my $file= shift;
# temporary variables to keep track of what class, level, domain,
# and info we are currently in.
my $class= undef;
my $level= undef;
my $domain= undef;
my $rowtext= undef;
my $num;
my $fh= new FileHandle;
open($fh,$file) or croak "Couldn't open file '$file'";
while (<$fh>) {
if (//) { # underline tags denote title lines
# append the next line if neccessary
if (not m/<\/u>/) { chomp($_); $_=$_." ".<$fh>; }
# make sure it is appropriate (catch "SORCEROR AND WIZARD")
if (m/(\d)\w*-LEVEL\s+([A-Z]+)[A-Z ]*\s+SPELLS.*<\/u>/i) {
$level= $1;
$class= isaclass($2) or croak
"Unknown class '$2' in file '$file' line $.";
$domain= undef;
} elsif (m/\s*(\w+)\s+Domain\s*<\/u>/) {
$level= undef;
$class= isaclass("cleric");
$domain= $1;
} else {
croak "non-title tag in file '$file' line $.";
}
} elsif (not ($class or $level or $domain)) {
next;
} elsif (/<\/body>/) {
last;
}
if ((/
or
|<\/p>)/) {
chomp($_); $_=$_." ".<$fh>;
}
m/^(
|<\/p>)/ or croak
"Bad stat line in '$file' line $., under '$spellname'\n$_";
my ($stat,$value)= (isastat($2),$3);
$value=~s//'/g;
$value=~s/ / /g;
if (defined($self->getstat($spellname,"Description")) and not
($stat=~/Focus|XP Cost|Components/) and $debug) {
warn "Possible parsing error in '$file' line $.\n" .
" -> '$spellname' stat '$stat' comes after desc start\n";
}
if ($stat eq "Level") {
my $bad=undef;
my @parts= split(',',$value);
for (@parts) {
m/^\s*([\w\/]+) (\d)\s*$/ or $bad="Bad pattern '$_'";
isaclass($1) or isadomain($1) or
$bad="Unknown class/domain '$1'";
}
warn $bad if (defined($bad));
}
if ($stat eq "Components") {
my $p= "V|S|M|F|DF|XP";
# must match "(V), M, F/DF (see text)"
$value=~m/^(\s*\(?($p)\)?[,\/])*\s*($p)\s*(\(see text\))?/
or warn "Unknown component '$value'";
}
$self->setstat($spellname,$stat,$value);
} elsif ((/^(
)?/) && isaschool($2)) {
while (not m/(
|<\/p>)/) { # may go over line
chomp($_); $_=$_." ".<$fh>;
}
m/^(
/ or die;
$self->setstat($spellname,"School",$2);
$self->setstat($spellname,"Other",$3);
} elsif (/\w/) {
### The phrase "As ]*>//g; # remove ]*>\s*([^<]*?)\s*addspelltolist($prefix.$_,$class,$level);
$self->setstat($prefix.$_,"Blurb",$blurb);
}
} else {
$spellname=~s/\s*\(\w+\/?\w*\)\s*$//;
$self->addspelltolist($spellname,$class,$level);
$self->setstat($spellname,"Blurb",$blurb);
}
} elsif (defined($rowtext)) {
$rowtext.=$_;
}
} # end of while (<$fh>)
close($fh);
return $num;
}
######################################################################
=item usebasespell
This runs through all known spells and for those with a recognized
"Base Spell", it tries to fill in unknown stats by taking the value
from the base spell stat.
=cut
sub usebasespell {
my $self= shift;
my @statlist= $self->getstats();
my @spelllist= $self->getspells();
foreach my $spell (@spelllist) {
my $basespell= $self->getstat($spell,"Base Spell");
next unless defined($basespell);
warn "'$spell' has unknown base spell '$basespell'\n" if
($debug and not $self->isaspell($basespell));
next unless $self->isaspell($basespell);
foreach my $stat (@statlist) {
next if defined($self->getstat($spell,$stat));
my $value= $self->getstat($basespell,$stat);
next unless defined($value);
$self->setstat($spell,$stat,$value);
}
}
}
######################################################################
1; # required end of module line
__END__
=head1 NOTE
This is tailored for reading the d20SRD document. However, it does
not reproduce any of the material therein.
=head1 Requirements
I'd recommend using at least perl 5.003 -- if you don't have
it, this is the time to upgrade! Get 5.005_02 or better.
=head1 AUTHORS
John H. Kim