tiger_lib/ck3/data/
stories.rs

1use crate::block::{BV, Block};
2use crate::context::ScopeContext;
3use crate::db::{Db, DbKind};
4use crate::everything::Everything;
5use crate::game::GameFlags;
6use crate::item::{Item, ItemLoader};
7use crate::scopes::Scopes;
8use crate::token::Token;
9use crate::tooltipped::Tooltipped;
10use crate::validator::Validator;
11
12#[derive(Clone, Debug)]
13pub struct Story {}
14
15inventory::submit! {
16    ItemLoader::Normal(GameFlags::Ck3, Item::Story, Story::add)
17}
18
19impl Story {
20    pub fn add(db: &mut Db, key: Token, block: Block) {
21        db.add(Item::Story, key, block, Box::new(Self {}));
22    }
23}
24
25impl DbKind for Story {
26    fn validate(&self, _key: &Token, block: &Block, data: &Everything) {
27        let mut vd = Validator::new(block, data);
28
29        let sc_builder = |key: &Token| {
30            let mut sc = ScopeContext::new(Scopes::StoryCycle, key);
31            sc.define_name("story", Scopes::StoryCycle, key);
32            sc
33        };
34
35        vd.field_effect_builder("on_setup", Tooltipped::No, sc_builder);
36        vd.field_effect_builder("on_end", Tooltipped::No, sc_builder);
37        vd.field_effect_builder("on_owner_death", Tooltipped::No, sc_builder);
38
39        vd.multi_field_validated_key_block("effect_group", |key, block, data| {
40            let mut sc = ScopeContext::new(Scopes::StoryCycle, key);
41            sc.define_name("story", Scopes::StoryCycle, key);
42            let mut vd = Validator::new(block, data);
43
44            // TODO: handle case of multiple of these fields being specified
45            for field in &["days", "weeks", "months", "years"] {
46                vd.field_validated(field, |bv, data| match bv {
47                    BV::Value(token) => {
48                        token.expect_integer();
49                    }
50                    BV::Block(block) => {
51                        let mut vd = Validator::new(block, data);
52                        vd.req_tokens_integers_exactly(2);
53                    }
54                });
55            }
56            vd.field_numeric_range("chance", 0.0..=100.0);
57
58            vd.field_trigger("trigger", Tooltipped::No, &mut sc);
59
60            validate_complex_effect(&mut vd, &mut sc);
61        });
62    }
63}
64
65fn validate_complex_effect(vd: &mut Validator, sc: &mut ScopeContext) {
66    vd.multi_field_validated_block("first_valid", |block, data| {
67        let mut vd = Validator::new(block, data);
68        validate_complex_effect(&mut vd, sc);
69    });
70    vd.multi_field_validated_block("random_valid", |block, data| {
71        let mut vd = Validator::new(block, data);
72        validate_complex_effect(&mut vd, sc);
73    });
74    vd.multi_field_validated_block("triggered_effect", |block, data| {
75        let mut vd = Validator::new(block, data);
76        vd.field_trigger("trigger", Tooltipped::No, sc);
77        vd.field_effect("effect", Tooltipped::No, sc);
78    });
79    vd.field_effect("fallback", Tooltipped::No, sc);
80}