boseiju/ability_tree/ability/
triggered.rs

1mod trigger_cond;
2
3pub use trigger_cond::TriggerCondition;
4
5use crate::ability_tree::AbilityTreeNode;
6use crate::ability_tree::MAX_CHILDREN_PER_NODE;
7
8/// A triggered ability is an ability that waits for an event to happen
9/// to put an effect on the stack.
10///
11/// From the Comprehensive Rules:
12/// A kind of ability. Triggered abilities begin with the word “when,” “whenever,” or “at.”
13/// They’re written as “\[Trigger condition\], \[effect\].”
14/// See rule 113, “Abilities,” and rule 603, “Handling Triggered Abilities.”
15///
16/// See also: <https://mtg.fandom.com/wiki/Triggered_ability>
17#[derive(serde::Serialize, serde::Deserialize)]
18#[derive(Debug, Clone, PartialEq, Eq)]
19pub struct TriggeredAbility {
20    pub condition: TriggerCondition,
21    pub effect: crate::ability_tree::ability::spell::SpellAbility,
22    #[cfg(feature = "spanned_tree")]
23    pub span: crate::ability_tree::span::TreeSpan,
24}
25
26impl AbilityTreeNode for TriggeredAbility {
27    fn node_id(&self) -> usize {
28        use idris::Idris;
29        crate::ability_tree::NodeKind::TriggeredAbility.id()
30    }
31
32    fn children(&self) -> arrayvec::ArrayVec<&dyn AbilityTreeNode, MAX_CHILDREN_PER_NODE> {
33        let mut children = arrayvec::ArrayVec::new_const();
34        children.push(&self.effect as &dyn AbilityTreeNode);
35        children.push(&self.condition as &dyn AbilityTreeNode);
36        children
37    }
38
39    fn display(&self, out: &mut crate::utils::TreeFormatter<'_>) -> std::io::Result<()> {
40        use std::io::Write;
41        write!(out, "triggered ability:")?;
42        out.push_inter_branch()?;
43        write!(out, "condition:")?;
44        out.push_final_branch()?;
45        self.condition.display(out)?;
46        out.pop_branch();
47        out.next_final_branch()?;
48        write!(out, "effect:")?;
49        out.push_final_branch()?;
50        self.effect.display(out)?;
51        out.pop_branch();
52        out.pop_branch();
53        Ok(())
54    }
55
56    fn node_tag(&self) -> &'static str {
57        "triggered ability"
58    }
59
60    #[cfg(feature = "spanned_tree")]
61    fn node_span(&self) -> crate::ability_tree::span::TreeSpan {
62        self.span
63    }
64}