To Extend, or Not to Extend: That is the Question:

With apologies to The Bard and The Scottish Play for the bad miss-quote above. I am continuing on with my D&D Moose Quest. The last post I left of with what to do now that I am going to try to use a number of Mixins and how they perhaps can work with other classes.

I have chosen the 'OpenDoorsOnA' character ability as it is one that is not only effected by 'Strength' it can also be effected by The 'Fighter Class' as they get an extra roll of % dice to extend there strength from 01 to 100 (00 in D&D speak) but still staying below 19. To account for this I could just fix my 'OpenDoorsOnA' role a little to look for the exceptional strength attribute like this

      requires (qw(strength exceptional));

and then change my 'open_door_on_a' sub accordingly to check for 18 strength then exception_strength but now I have the problem that any class that wants to use this role will also require the 'exceptional_strength' attribute as well.

When you sit down and work out it the chance of exceptional strength, an 18 with 3xd6s is 0.463 and for 00 with 2x d20s is something like .025. so I always wondered why each time I had a new player come into the game, who looked like this;


they always had a Fighter character with Strength 18(00). Why did I even let them join in??

So obviously adding this into my role is not a good Idea but how do I account for it? In the 'Fighters' class perhaps? Obviously, most of the time a fighter will just use the regular 'open_door_on_a', so do I need a 'open_door_with_exceptional' sub just for the fighter?

If I do that now in my game program will have to check for fighter then exceptional strength each time I try to open a door?? Makes for a good deal of 'if/elsif/else' or 'given when' commands in my game code (too bad I do not get paid by the line)??

What I would really like is just to have one 'open_door_on_a' and let the class figure out what to return.

I could of course just overwrite the 'open_door_on_a' sub in my Fighter class and shove in the exceptional stuff but there are times when a character can be both a Fighter and a MU user so which one do I use?

I will be venturing into Diamond land. Fortunately I think Moose has the answer.

Lest start for now with just a base 'Fighter' class that extends the 'Character' class.

package Fighter;
use Moose;
extends 'Character';

As this is a fighter and they get a possible 'exceptional' attribute so I add that in;

has 'exceptional' =>(
	is		=>'ro',
	isa		=>'Int',

Now the fun bit;

with  'OpenDoorsOnA', => { 
     -alias       =>{open_door_on_a=>'normal_open_door_on_a'},
     -excludes =>'open_door_on_a' 

So what did I do in the above??

Well in order to avoid 'diamond problem' clashes Moose allows me to both 'alias' and or exclude any methods or attributes in the role I am consuming. So I have renamed 'OpenDoorsOnA->open_door_on_a' to 'OpenDoorsOnA->normal_open_door_on_a' and then excluded it so I can't accidentally access it directly somehow.

Now all I have to do is add this sub

sub open_door_on_a {
	my $self = shift;
	return $self->normal_open_door_on_a()
		if ($self->strength() < 18);
	given ($self->exceptional){
		when (0){
			return 5;
		when ([1..50]){
			 return 3;
		when ([51..99]){
			return 4;

and when I do this;

use Fighter;
my $me = Fighter->new({name=>'Sir Cumferace',strength=>18,exceptional=>99});

print $me->name()."\n";
print "opens a door on a ". $me->open_door_on_a()."\n";

I get;

Sir Cumferace
opens a door on a 4

Bonus! I am really beginning to enjoy Moose.

Reading a little deeper into the D&D rules I see that 'exceptional' exceptional strength also allows you to bash in locked, barred or even magic doors. Taking into account that even in the 'Fighter' class exceptional strength would be rare, why have even have an attribute for it in that class? It is just going to take up extra space 99.9% of the time!

Perhaps 'Exceptional' strength should be a role on its own and only used when a Fighter has 18 Strength????

Oh well something for another post 1


"[...] If much you note him You shall offend him, and extend his Passion, Feed, and regard him not. [...]"

—Macbeth, 2.iv

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