A Race to the Finish

Well in my last post I made use of the visitor pattern so sort out 'Grot' characters at an early stage. My next challenge is to set the race of my 'Character' from one of the ones below.

RPG_Races_proportions_by_Artigas.jpg

Well not all of these just the original 7 A D&D races. I could try my visitor pattern again but part of what I want to build into this system is the ability to eventually expand into the odd miss-mash of races above. So I could go back and attempt to do this with parametrized roles like I tried to do with Grot character as in this post but what I really want is to load in my 'Ability' rolls and then have it tell me what 'Race' I could be rather then attempting to load all those roles.

I guess I could use a simple given when in sub on my 'Creator' class but then I would have to recode things if I added a new 'Race' into the mix.

So why not just leverage OO programming a little create a 'Class' for each race and simply iterate through a folder full of them instantiate each in turn and if the ability set passes a test then I can load that race into an array that then can be used later for choosing a class.

Well I can start with just a generic empty 'Race' class like this


package RPG::ADD::Creator::Race;
use Moose;

has 'ability_mins' =>(
is =>'ro',
isa =>'HashRef',
init_arg => undef,
default =>sub{{}},
);

sub can_be{
my $self = shift;
my ($attr) = @_;
foreach my $ability (keys($self->ability_mins())){
return 0
if ($attr->{$ability} < $self->ability_mins()->{$ability});
}
return 1;
}


Note in my 'ability_mins' I set the inti_arg to 'undef' which essentially turns it into a constant as there is no way to set or get this value.

The next step is just as simple. I create an 'Elf' class like this


package RPG::ADD::Creator::Race::Elf;
use Moose;
extends 'RPG::ADD::Creator::Race';

has '+ability_mins' =>(
default =>sub{{intelligence=>8,dexterity=>7,constitution=>6,charisma=>8}},
);


that is extending my original race class. Now I have nicely encapsulated any rules in this class. So if numb-nuts the 'Project Manager' really really wants a Half-Ogre PC all I need do is add in a new class like this in my 'Race' folder.

package RPG::ADD::Creator::Race::HalfOgre;
use Moose;
extends 'RPG::ADD::Creator::Race';

has '+ability_mins' =>(
default =>sub{{strength=>14,constitution=>14}},
);


and it should just work. However I do not even want to try and figure out the race of this bunch

darkon-stuffies.jpg

Now of course I have to play with my 'Creator' class a bit but with mods like 'Module::PluginFinder' about this is quite easy


my $finder = Module::PluginFinder->new(
                 search_path => 'RPG::ADD::Creator::Race',
                 filter => sub {
                    my ( $module, $searchkey ) = @_;
                    $module->can( $searchkey );
                 },
              );
    foreach my $race ($finder->modules()){
	my $check_race = $race->new();
        push($self->available_race,$check_race)
             if ($check_race->can_be($attr));
    }
The may be a Mooser way to do this, as there are some MooseXes out there that may do the trick for me but I am a happy little programmer right now. Will have improve on this as we go along as I could see a use for a name attribute in Race class along with building in the rules for available class choices. Which is my next post me thinks

Leave a comment

About byterock

user-pic Long time Perl guy, a few CPAN mods allot of work on DBD::Oracle and a few YAPC presentations