Abilities and Triggers
Types of abilities
The most familiar type of ability for mafia players is the "activated" ability,
where the player decides when to "activate" the ability. This is represented in
the engine by the Ability type.
Some examples: voting, night kills, protection, role blocking, double-voting.
"Automatic" or "passive" abilities are Triggers,
which perform actions in response to external events.
Though the player may percieve these to be different (e. g. having multiple lives
seems different than being a Paranoid Gun Owner), the implementation is similar:
both handle particular Event types and create Actions in response.
Note that both are derived from ATBase.
This class automatically applies Constraints
to objects' event handlers.
Abilities
An Ability is probably the easiest case to implement.
It handles EActivate events,
which signal that we want to activate a particular ability, and responds with
a corresponding Action, given the sent parameters.
To create a custom Ability, you can either Ability and override
the activate() (and possibly __init__()) method(s):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | |
Alternatively, you can generate one from a function or pre-existing Action:
1 2 3 | |
This does the same as the above, but auto-generates the MyAbility class
(note that "name" in the generator is the class name, while "name" in the
__init__ function is the display name of the ability.)
Triggers
Abilities that are triggered in other ways (e. g. passive abilities) should
subclass Trigger directly. You can add any event handlers you want, and the
trigger will automatically apply the correct Constraints.
Constraints
Generally, abilites can only be used under particular conditions. The most typical ones are:
- The source (
Actor, parent ofability) must be alive. - The target must be alive (if an
Actor). - You can use the ability only during the (day) or (night).
- Only one player from your
Factionmay use this ability, and once per night.
These conditions are represented by Constraint objects.
If a Constraint is violated, the Ability or Trigger doesn't actually return
the action(s) back to the action queue that called it, which means the ability or
trigger don't actually run. It will currently just send a warning to the logging
module... this is not super elegant, but it works well enough for now. 😅