Skip to main content

manabrew_engine/ability/effects/
store_s_var_effect.rs

1//! StoreSVar effect — store a value in an SVar for later use.
2//!
3//! Ported from Java's `StoreSVarEffect.java`.
4//! Stores a calculated value into a named SVar on the source card.
5
6use super::EffectContext;
7
8/// Struct form of this effect so it can participate in the
9/// `SpellAbilityEffect` trait hierarchy — mirrors Java's
10/// `StoreSVarEffect` class extending `SpellAbilityEffect`.
11#[manabrew_engine_macros::spell_effect(StoreSVarEffect)]
12fn resolve(ctx: &mut EffectContext, sa: &crate::spellability::SpellAbility) {
13    let Some(source_id) = sa.source else { return };
14
15    let svar_name = sa.ir.svar_name_text.clone().unwrap_or_default();
16    let svar_type = sa.ir.svar_type_text.clone().unwrap_or_default();
17    let expression = sa.ir.svar_expression_text.clone().unwrap_or_default();
18
19    if svar_name.is_empty() || svar_type.is_empty() || expression.is_empty() {
20        return;
21    }
22
23    let resolved_number = match svar_type.as_str() {
24        "Number" => expression
25            .parse::<i32>()
26            .unwrap_or_else(|_| crate::svar::evaluate_svar(&expression, sa)),
27        "Count" => crate::svar::resolve_count_svar_for_sa(
28            &expression,
29            ctx.game,
30            source_id,
31            sa.activating_player,
32            sa,
33        ),
34        "CountSVar" => {
35            let mut expression = expression.clone();
36            if expression.contains('/') {
37                let expr_math_var = expression
38                    .split('/')
39                    .nth(1)
40                    .and_then(|rest| rest.split('.').nth(1))
41                    .map(str::to_string);
42                if let Some(expr_math_var) = expr_math_var {
43                    let expr_math =
44                        crate::svar::resolve_numeric_value(ctx.game, sa, &expr_math_var, 0);
45                    expression = expression.replace(&expr_math_var, &expr_math.to_string());
46                }
47            }
48            crate::svar::resolve_svar_expression(
49                &format!("SVar${expression}"),
50                ctx.game,
51                source_id,
52                sa.activating_player,
53                sa,
54            )
55        }
56        "Calculate" => {
57            if let Some(svar_expr) = ctx.game.card(source_id).get_s_var(&expression) {
58                crate::svar::resolve_count_svar_for_sa(
59                    svar_expr,
60                    ctx.game,
61                    source_id,
62                    sa.activating_player,
63                    sa,
64                )
65            } else {
66                expression
67                    .parse::<i32>()
68                    .unwrap_or_else(|_| crate::svar::evaluate_svar(&expression, sa))
69            }
70        }
71        _ => expression
72            .parse::<i32>()
73            .unwrap_or_else(|_| crate::svar::evaluate_svar(&expression, sa)),
74    };
75    let resolved_value = format!("Number${}", resolved_number);
76
77    ctx.game
78        .card_mut(source_id)
79        .set_s_var(svar_name, resolved_value);
80}