Once more unto the breach

It has been a few post since my last full Moose and AD&D post so I though I would get at least one more rule into my 'Creator' Class now that I have may Character Classes and races all sorted out.

This time we are going to look at Hit Points or HP for short.

A touchy subject, for many, as I am sure the black Knight has taken quite a few beyond normal and still fights on.

HitPoints.jpg

As well as being the source of endless debate there are also quite a few rules on HPs that are a little tricky to play with. Here are the basics

  1. Each 'Character Class' has is own hit dice for HPs
  2. Constitution can effect HPs
  3. Some 'Character Classes' get extra hit dice when starting out.
  4. Characters can loose HPs temporarily
  5. Characters can gain HPs temporarily
  6. Characters can loose HPs permanently
  7. Characters can gain HPs permanently
  8. Character can never have less that '1' permanent HP
  9. Characters collapse at '0' HPs
  10. Characters Die at '-10' HPs
  11. Characters gain HPs permanently when they move up levels

So some of these only apply at character creation, some only apply during game play and some both. So the one's that I need in the Creator are 1,2,3,6 and only 3 applies just to character creation.

Well I need I need some place to put this value and as usual I want to keep the dice roll or rolls around so I can try this

has hit_dice_rolls (
    is=>'ro',
    isa=>'ArrayRef[Int]',
    default=>sub{[]},
    init_arg => undef,
);
So I have an Array-Ref of Ints, read only, and I do not want this able to be set at instantiation. Now for my hit points again I want this to be much the same like this

 has hit_points  (
    is=>'ro',
    isa=>'Int',
    default=>0
    init_arg => undef,
     alias => [ qw(HP hp) ],
     
);
As well I would really like to use both HP and hp for the same values and I can accomplish that with 'MooseX::Alisases' by using it and adding in a list of aliases. Now this gets me thinking as there are many many things that have HPs So why not move this off into its own role? Something like this that I can use else where.

package  RPG::ADD::Attribute::HitPoints;
use Moose::Role;
use MooseX::Aliases;
requires ( qw (_build_hps constitution hit_die hit_dice ));

has hit_points  (
    is=>'ro',
    isa=>'Int',
    default=>0
    init_arg => undef,
    alias => [ qw(HP hp) ],
    builder=>'_build_hps',

);

has hit_dice_rolls (
    is=>'rw',
    isa=>'ArrayRef[Int]',
    default=>sub{[]},
);

has current_hit_points (
    is=>'rw',
    isa=>'Int',
    default=>0,
    init_arg => undef,
);
Notice how I have added a 'builder' to the 'hit_points'' attribute and made it part of the requires so now any class or role that wants to use must have a builder for it.

So in my character class I just want the sum of all my rolls like this;


sub _build_hps {
     my $self = shift;
     return $self->current_hps()
          if ($self->current_hps());
     my $hps = 0;
     foreach my $roll ($self->hit_dice_rolls()){
         $self->current_hps( $self->current_hps+$roll);
     }
     return $self->current_hps;
}
In my Creator class the call is a little different as this time I have to roll some dice like this

sub _build_hps {
     use RPG::ADD::Dice;

     my $self = shift;
     $count = 1
          unless($count);
     return $self->current_hps()
          if ($self->current_hps());

     my $throw = RPG::ADD::Dice->new("1D".$self->die.$self->hp_bonus);
     
     foreach my $count (0..$self->hit_dice()){
          $self->hit_dice_rolls()->[$count-1] = $throw->roll()
          $self->current_hit_points($self->current_hit_points()+$hps);
        
     }
    $self->current_hit_points(1)
          if ($self->current_hit_points() <1 );
     return $self->current_hit_points();
     
}

Or say for my 'Monster' Class where I need to roll more dice


sub _build_hps {
     use RPG::ADD::Dice;
     my $self = shift;
     return $self->current_hps()
          if ($self->current_hps());
     my $hps = RPG::ADD::Dice->new("D".$self->die().$self->hit_dice.$self->hp_bonus);
     
     $self->current_hps($hps->roll());

     return self->current_hps();
     
}

I also added in a RW 'current_hps' attribute that can be used in game-play.

So again moose give me a great deal of flexibility now I can now reuse this role in at lest three places and with the bonus that I if I try to use it in say a class without one of the requirements it will die.

This little tidbit is going to come in handy.

HP.jpeg

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