overlord_event_system/behaviors/
vassals.rs

1//! Vassal behaviors: task/link reward stubs, task loyalty, and link loyalty
2//! decay.
3
4use event_system::script::types::ESCurrencyUnit;
5
6use crate::behaviors::{BehaviorKind, BehaviorMeta, BehaviorRegistry};
7
8/// Inputs for a vassal/suzerain reward fn (`reward_fn` config slots).
9pub struct VassalRewardCtx {
10    /// Whether the vassal task succeeded; `None` at the link-reward sites,
11    /// which have no task outcome.
12    pub good_task: Option<bool>,
13}
14
15/// Signature of a vassal/suzerain reward fn.
16pub type VassalRewardFn = fn(&VassalRewardCtx) -> anyhow::Result<Vec<ESCurrencyUnit>>;
17
18/// Reward slots are stubs: no reward is currently granted. Kept as three
19/// distinct named fns (one per config slot) so a future real reward on any one
20/// slot can replace just that fn.
21pub fn vassal_task_reward_const(_ctx: &VassalRewardCtx) -> anyhow::Result<Vec<ESCurrencyUnit>> {
22    Ok(vec![])
23}
24
25pub fn suzerain_reward_const(_ctx: &VassalRewardCtx) -> anyhow::Result<Vec<ESCurrencyUnit>> {
26    Ok(vec![])
27}
28
29pub fn vassal_reward_const(_ctx: &VassalRewardCtx) -> anyhow::Result<Vec<ESCurrencyUnit>> {
30    Ok(vec![])
31}
32
33/// Test vassal-task reward (template 7b4a7bf5): good → 42, bad → 32.
34pub fn test_vassal_task_reward_42_32(ctx: &VassalRewardCtx) -> anyhow::Result<Vec<ESCurrencyUnit>> {
35    let amount = if ctx.good_task.unwrap_or(true) {
36        42
37    } else {
38        32
39    };
40    crate::behaviors::rewards::fixed_currencies(&[(TEST_CURRENCY, amount)])
41}
42
43/// Test vassal-task reward (template 05e915bf): good → 0, bad → 42.
44pub fn test_vassal_task_reward_0_42(ctx: &VassalRewardCtx) -> anyhow::Result<Vec<ESCurrencyUnit>> {
45    let amount = if ctx.good_task.unwrap_or(true) { 0 } else { 42 };
46    crate::behaviors::rewards::fixed_currencies(&[(TEST_CURRENCY, amount)])
47}
48
49/// Test suzerain/vassal link reward: a flat 42 of the soft currency.
50pub fn test_vassal_link_reward_42(_ctx: &VassalRewardCtx) -> anyhow::Result<Vec<ESCurrencyUnit>> {
51    crate::behaviors::rewards::fixed_currencies(&[(TEST_CURRENCY, 42)])
52}
53
54const TEST_CURRENCY: &str = "b59b33a2-4d19-4e2c-9cea-e03ea15882a0";
55
56/// Inputs for the vassal-task loyalty slot (`loyalty_fn` config field).
57pub struct VassalLoyaltyCtx {
58    pub good_task: bool,
59}
60
61/// Signature of a vassal-task loyalty fn (`i64` loyalty amount).
62pub type VassalLoyaltyFn = fn(&VassalLoyaltyCtx) -> anyhow::Result<i64>;
63
64/// The shipped vassal-task loyalty: a flat 10, regardless of outcome.
65pub fn vassal_task_loyalty_const(_ctx: &VassalLoyaltyCtx) -> anyhow::Result<i64> {
66    Ok(10)
67}
68
69/// Test loyalty fn (template 7b4a7bf5): good → 42, bad → 32.
70pub fn test_vassal_task_loyalty_42_32(ctx: &VassalLoyaltyCtx) -> anyhow::Result<i64> {
71    Ok(if ctx.good_task { 42 } else { 32 })
72}
73
74/// Test loyalty fn (template 05e915bf): good → 0, bad → 42.
75pub fn test_vassal_task_loyalty_0_42(ctx: &VassalLoyaltyCtx) -> anyhow::Result<i64> {
76    Ok(if ctx.good_task { 0 } else { 42 })
77}
78
79/// Inputs for the vassal-link loyalty decay (code-dispatched).
80pub struct LoyaltyDecreaseCtx {
81    pub time_passed_sec: i64,
82}
83
84/// Signature of a loyalty-decay fn (`i64` decrease per tick).
85pub type LoyaltyDecreaseFn = fn(&LoyaltyDecreaseCtx) -> anyhow::Result<i64>;
86
87/// The shipped loyalty decay: a flat 7 per tick, ignoring elapsed time.
88pub fn loyalty_decrease_const_7(_ctx: &LoyaltyDecreaseCtx) -> anyhow::Result<i64> {
89    Ok(7)
90}
91
92/// Register this module's config-dispatched behaviors.
93pub fn register(registry: &mut BehaviorRegistry) {
94    let mut reward = |name: &str, title: &str, desc: &str, f: VassalRewardFn| {
95        registry.register_vassal_reward(
96            BehaviorMeta {
97                name: name.to_string(),
98                category: BehaviorKind::VassalReward,
99                title: title.to_string(),
100                description: desc.to_string(),
101            },
102            f,
103        );
104    };
105    reward(
106        "vassal_task_reward_const",
107        "Награда за вассальное задание (стаб)",
108        "Пустая награда — слот reward_fn вассального задания пока не выдаёт валют.",
109        vassal_task_reward_const,
110    );
111    reward(
112        "suzerain_reward_const",
113        "Награда сюзерена (стаб)",
114        "Пустая награда — слот suzerain_reward_fn пока не выдаёт валют.",
115        suzerain_reward_const,
116    );
117    reward(
118        "vassal_reward_const",
119        "Награда вассала (стаб)",
120        "Пустая награда — слот vassal_reward_fn пока не выдаёт валют.",
121        vassal_reward_const,
122    );
123    reward(
124        "test_vassal_task_reward_42_32",
125        "Тест: награда вассального задания (42 / 32)",
126        "Тестовый reward_fn: успех => 42, провал => 32 мягкой валюты.",
127        test_vassal_task_reward_42_32,
128    );
129    reward(
130        "test_vassal_task_reward_0_42",
131        "Тест: награда вассального задания (0 / 42)",
132        "Тестовый reward_fn: успех => 0, провал => 42 мягкой валюты.",
133        test_vassal_task_reward_0_42,
134    );
135    reward(
136        "test_vassal_link_reward_42",
137        "Тест: награда за вассальную связь (42)",
138        "Тестовый suzerain/vassal reward_fn: 42 мягкой валюты.",
139        test_vassal_link_reward_42,
140    );
141
142    let mut loyalty = |name: &str, title: &str, desc: &str, f: VassalLoyaltyFn| {
143        registry.register_vassal_loyalty(
144            BehaviorMeta {
145                name: name.to_string(),
146                category: BehaviorKind::VassalLoyalty,
147                title: title.to_string(),
148                description: desc.to_string(),
149            },
150            f,
151        );
152    };
153    loyalty(
154        "vassal_task_loyalty_const",
155        "Лояльность за вассальное задание (константа 10)",
156        "Возвращает 10 независимо от исхода задания.",
157        vassal_task_loyalty_const,
158    );
159    loyalty(
160        "test_vassal_task_loyalty_42_32",
161        "Тест: лояльность вассального задания (42/32)",
162        "Тестовый loyalty_fn: успех => 42, провал => 32 (задание 7b4a7bf5).",
163        test_vassal_task_loyalty_42_32,
164    );
165    loyalty(
166        "test_vassal_task_loyalty_0_42",
167        "Тест: лояльность вассального задания (0/42)",
168        "Тестовый loyalty_fn: успех => 0, провал => 42 (задание 05e915bf).",
169        test_vassal_task_loyalty_0_42,
170    );
171}