i don't know why you're having issues at this point. i made some minor changes to the script (shown in red below) and tossed it on an npc in tutorialb and it worked exactly as i expected it would. half of them spawned as erudites (necros) and the other half as high elves (enchanters), and both showed the correct responses when hailed.
quests\tutorialb\a_cave_rat.pl
Code:
use 5.012;
no strict 'vars';
use warnings;
# array of playable class long names
use constant CLASS_L => qw(
Unknown Warrior Cleric Paladin Ranger Shadowknight Druid Monk Bard Rogue
Shaman Necromancer Wizard Magician Enchanter Beastlord Berserker
);
# hashref containing buffs offered depening on the class of the npc
my $data = {
Enchanter => {
greet => "I have the %s for your mind.",
buffs => [
[ "Bind Affinity", 35, 10 ],
[ "Breeze", 697, 25 ],
[ "Clarity", 174, 50 ],
[ "Clarity II", 1693, 200 ],
[ "Alacrity", 170, 10 ],
[ "Augment", 1729, 30 ],
[ "Aanya's Quickening", 1708, 100 ],
[ "Rune I", 481, 5 ],
],
},
Necromancer => {
greet => "Souls and %s.",
buffs => [
[ "Bind Affinity", 35, 10 ],
[ "Dead Men Floating", 1391, 10 ],
],
},
};
sub EVENT_SPAWN {
if ( 49 > (int rand 99) + 1 ) {
$npc->SetEntityVariable( "Class", 14 );
$npc->SetRace(5);
}
else {
$npc->SetEntityVariable( "Class", 11 );
$npc->SetRace(3);
}
}
sub EVENT_SAY {
my $npcClass = (CLASS_L)[ $npc->GetEntityVariable("Class") ];
my $greeting = $data->{$npcClass}->{greet} || "Got %s?";
my $buffList = $data->{$npcClass}->{buffs};
# saylink
my $buffs = quest::saylink( "buffs", 1 );
my $CanCast = sub {
foreach my $spell ( @{ +shift } ) {
my ( $spellName, $spellID, $spellCost ) = @{$spell};
my $buffLink = quest::saylink( $spellName, 1 );
$client->Message( 315,
"I can cast $buffLink on you for ${spellCost}pp." );
}
};
# matches hail
if ( $text =~ /hail/i ) { quest::say( sprintf $greeting, $buffs); }
# doesn't match hail, but does match something in buff list
elsif ( my @match = grep { ${$_}[0] =~ /$text/i } @{$buffList} ) {
# single, exact match in buff list.
if ( @match == 1 && $text eq $match[0][0] ) {
my ( $spellName, $spellID, $spellCost ) = @{ $match[0] };
$client->Message( 315,
"That will be ${spellCost}pp for $spellName." );
quest::setglobal( "buff", $text, 0, "M5" );
}
# more than one match in buff list. list them.
else { $CanCast->( \@match ); }
}
# defaut to listing all buffs this npc can cast.
else { $CanCast->($buffList); }
}
sub EVENT_ITEM {
my $npcClass = (CLASS_L)[ $npc->GetEntityVariable("Class") ];
my $buffList = $data->{$npcClass}->{buffs};
my $correctMoney = 0;
# if client has selected a buff
if ( defined $qglobals{buff} ) {
# find the buff selected
foreach my $spell ( @{$buffList} ) {
my ( $spellName, $spellID, $spellCost ) = @{$spell};
# if client gave the correct amount of money, cast the spell
next if $qglobals{buff} ne $spellName || $platinum != $spellCost;
$client->Message( 315,
"Thank you for the ${spellCost}pp. Prepare for $spellName!" );
$npc->CastSpell( $spellID, $client->GetID() );
$correctMoney = 1;
quest::delglobal("buff");
last;
}
}
# incorrect amount of money given or no qglobal for buff found for client
if ( !$correctMoney && ( $copper || $silver || $gold || $platinum ) ) {
$client->Message( 315,
"I don't need these coins. You may have them back." );
quest::givecash( $copper||0, $silver||0, $gold||0, $platinum||0 );
}
}