===== About Mods =====
Pretty much everything in DnD::library is a Mod (Module Modifier). Classes are Mods, races are Mods, feats and even magical items -- they are all Mods.
Base class for all Mods is DnD::Mod. Each mod has to be descendant of DnD::Mod.
Mods can be either specific (as DnD::Armor::Leather or DnD::Race::Elf) or generic. Most often used generic Mods are DnD::Scalar and DnD::Bonus.
===== DnD::Mod =====
Usually, we don't create this Mod directly. Instead, we use it as a base class for other Mods. It implements following public methods:
$self->next( $attribute ); # Returns value of attribute computed by next Mod in a computing chain.
$self->addImport( $module, @params ); # Adds module to import list. Items from import list are added to character right after the import of the Mod itself.
$self->addScalar( $attribute, $value ); # Shortcut for $self->addImport('DnD::Scalar', $attribute, $value).
$self->addBonus( $attribute, $value ); # Shortcut for $self->addImport('DnD::Bonus', $attribute, $value).
$self->addRemove( @module_id ); # Adds modules to remove list. Items from remove list are deactivated right after the import of the Mod itself.
$self->ability_mod( $ability_score ); # Returns ability modifier computed from ability score.
There are several other functions. They are called only in Core code (because of higher speed and effeciency) and should not be needed in normal Mods.
It's required, that every Mod (with the exception of some Core Mods) recieves it's parameters as a hash //(not reference)//. Character always adds key ''character'' to the parameters hash.
It's forbidden to call function ''next'' in the constructor. While constructor is still running, the module was not imported yet and therefore no Mod from import and remove arrays could be imported / removed. This could produce inconsistent results. If you really need to import something that depends on character's attriubutes, you can pass reference to function (arbitrarily complicated) to DnD::Bonus.
===== DnD::Scalar =====
This Mod represents a constant value. It takes two parameters -- attribute and value. Example of use:
my $scalar1 = DnD::Scalar->new('Ability/Str', 10);
my $scalar2 = DnD::Scalar->new('Feats', []);
In other mods, we usually use more convenient syntax for adding some constant:
$self->addScalar('Ability/Str', 10);
$self->addScalar('Feats', []);
''$value'' can be either scalar, refernce to array or reference to hash.
===== DnD::Bonus =====
This Mod represents a bonus to attribute. It takes two parameters -- attribute and value. Example of use:
my $bonus1 = DnD::Bonus->new('Ability/Str', 2);
my $bonus2 = DnD::Bonus->new('Feats', [ 'Improved Initiative' ]);
my $bonus3 = DnD::Bonus->new('Combat/AC/Parts', { dodge => 2 });
In other mods, we usually use more convenient syntax for adding a bonus:
$self->addBonus('Ability/Str', 2);
$self->addBonus('Feats', [ 'Improved Initiative' ]);
$self->addBonus('Combat/AC/Parts', { dodge => 2 });
''$value'' can be either scalar, refernce to array, reference to hash or reference to function. The way how the bonus is handled depends on type of bonus and type of value of attribute.
* **scalar attribute** & **scalar bonus** -- returns attribute + bonus
* **arrayref attribute** & **scalar bonus** -- appends bonus to end of attribute array
* **arrayref attribute** & **arrayref bonus** -- appends bonus array to end of attribute array
* **hashref attribute** & **hashref bonus** -- returns merged bonuses (using ''merge_bonus'' function)
* **subref bonus** -- returns return value of bonus function
Although it's theoretically possible to change attribute's type in bonus function, we strongly advise against it. It will probably cause serious system malfunction.