tiger_lib/ck3/data/
courtier_guest_mgmt.rs

1use crate::block::Block;
2use crate::context::ScopeContext;
3use crate::db::{Db, DbKind};
4use crate::desc::validate_desc;
5use crate::effect::validate_effect;
6use crate::everything::Everything;
7use crate::game::GameFlags;
8use crate::item::{Item, ItemLoader};
9use crate::report::{ErrorKey, err};
10use crate::scopes::Scopes;
11use crate::token::Token;
12use crate::tooltipped::Tooltipped;
13use crate::validate::validate_modifiers_with_base;
14use crate::validator::Validator;
15
16#[derive(Clone, Debug)]
17pub struct CourtierGuestManagement {}
18
19inventory::submit! {
20    ItemLoader::Normal(GameFlags::Ck3, Item::CourtierGuestManagement, CourtierGuestManagement::add)
21}
22
23impl CourtierGuestManagement {
24    pub fn add(db: &mut Db, key: Token, block: Block) {
25        db.add(Item::CourtierGuestManagement, key, block, Box::new(Self {}));
26    }
27}
28
29impl DbKind for CourtierGuestManagement {
30    fn validate(&self, key: &Token, block: &Block, data: &Everything) {
31        let mut vd = Validator::new(block, data);
32
33        if key.is("courtier_management") {
34            let sc_builder = |key: &Token| {
35                let mut sc = ScopeContext::new(Scopes::Character, key);
36                sc.define_name("courtier", Scopes::Character, key);
37                sc.define_name("liege", Scopes::Character, key);
38                sc
39            };
40
41            vd.field_trigger_builder("can_leave", Tooltipped::No, sc_builder);
42            vd.field_validated_key_block("monthly_leave_chance_x10", |key, block, data| {
43                validate_modifiers_with_base(block, data, &mut sc_builder(key));
44            });
45        } else if key.is("guest_management") {
46            let sc_builder = |key: &Token| {
47                let mut sc = ScopeContext::new(Scopes::Character, key);
48                sc.define_name("guest", Scopes::Character, key);
49                sc.define_name("host", Scopes::Character, key);
50                sc
51            };
52            vd.field_trigger_builder("guest_can_arrive", Tooltipped::No, sc_builder);
53            vd.field_validated_key_block("guest_score", |key, block, data| {
54                validate_modifiers_with_base(block, data, &mut sc_builder(key));
55            });
56            vd.field_trigger_builder("can_leave", Tooltipped::No, sc_builder);
57            vd.field_validated_key_block("monthly_leave_chance_x10", |key, block, data| {
58                validate_modifiers_with_base(block, data, &mut sc_builder(key));
59            });
60            vd.field_validated_block("guest_description", |block, data| {
61                let mut vd = Validator::new(block, data);
62                vd.multi_field_validated_block("description", |block, data| {
63                    let mut vd = Validator::new(block, data);
64                    vd.req_field("desc");
65                    vd.field_trigger_builder("limit", Tooltipped::No, sc_builder);
66                    vd.field_validated_key_block("weight", |key, block, data| {
67                        validate_modifiers_with_base(block, data, &mut sc_builder(key));
68                    });
69                    vd.field_validated_key("desc", |key, bv, data| {
70                        validate_desc(bv, data, &mut sc_builder(key));
71                    });
72                });
73            });
74        } else {
75            let msg = "expected either `courtier_management` or `guest_management`";
76            err(ErrorKey::Validation).msg(msg).loc(key).push();
77        }
78    }
79}
80
81#[derive(Clone, Debug)]
82pub struct GuestSystem {}
83
84inventory::submit! {
85    ItemLoader::Normal(GameFlags::Ck3, Item::GuestSystem, GuestSystem::add)
86}
87
88impl GuestSystem {
89    pub fn add(db: &mut Db, key: Token, block: Block) {
90        db.add(Item::GuestSystem, key, block, Box::new(Self {}));
91    }
92}
93
94impl DbKind for GuestSystem {
95    fn validate(&self, key: &Token, block: &Block, data: &Everything) {
96        // TODO: the root scope is not documented here
97        let mut sc = ScopeContext::new(Scopes::None, key);
98        sc.define_name("mover", Scopes::Character, key);
99
100        if key.is("destination_for_guest_entering_pool")
101            || key.is("destination_for_courtier_entering_pool")
102        {
103            validate_effect(block, data, &mut sc, Tooltipped::No);
104        } else {
105            let msg = "expected either `destination_for_guest_entering_pool` or `destination_for_courtier_entering_pool`";
106            err(ErrorKey::Validation).msg(msg).loc(key).push();
107        }
108    }
109}