Code:
# ============
# aliasing via typeglobs
# https://perldoc.perl.org/perldata.html#Typeglobs-and-Filehandles
*randRange = \*plugin::RandomRange;
# ============
# hash of stuff we want to possibly randomize, and by how much.
# this setup allows you to tweak chances of and ranges of scaling each stat
# it also allows you to keep the logic below a little cleaner.
my $target = {
# strength
str => {
# chance at randomization defined here (25%)
randomize => do { rand 100 > 75 },
# 'normal' scaling is a range of 110-130% at a 75% chance
# 'critical' scaling is a range of 130-200% at a 25% chance
modifier => do { rand 100 > 75 ? randRange(10, 25) : randRange(25, 75) },
# workaround since each stat has its own method of retrieval
accessor => do { $npc->GetSTR() },
# arbitrary here, but it's a good idea to have the ones below
cleanup => do { $npc->Emote("snarls menacingly...") },
},
# intelligence
_int => {
randomize => do { rand 100 > 75 },
modifier => do { rand 100 > 75 ? randRange(10, 30) : randRange(30, 100) },
accessor => do { $npc->GetINT() },
cleanup => do { $npc->SetMana($npc->GetMaxMana()) },
},
# wisdom
wis => {
randomize => do { rand 100 > 75 },
modifier => do { rand 100 > 75 ? randRange(10, 30) : randRange(30, 100) },
accessor => do { $npc->GetWIS() },
cleanup => do { $npc->SetMana($npc->GetMaxMana()) },
},
# stamina
sta => {
randomize => do { rand 100 > 75 },
modifier => do { rand 100 > 75 ? randRange(10, 30) : randRange(30, 100) },
accessor => do { $npc->GetSTA() },
cleanup => do { $npc->Heal() },
},
};
# for each stat listed in the table of targets...
foreach my $stat (keys %$target)
{
# skip stat if we don't roll a chance to randomize it
# TODO: further modify chances based on race/class
next unless $target->{$stat}->{randomize};
# get the current value of the stat we are looking at
my $current = $target->{$stat}->{accessor};
# roll for and retrieve the modifier to use to scale the stat
my $scale = $target->{$stat}->{modifier};
# stat scaling calculation happens here
my $modified = $current + int($current*(rand $scale/100));
# change applied
$npc->ModifyNPCStat($stat, $modified);
# do any cleanup defined for the current stat
$target->{$stat}->{cleanup} if defined $target->{$stat}->{cleanup};
};