tiger_lib/ck3/data/
task_contracts.rs

1use crate::block::Block;
2use crate::context::ScopeContext;
3use crate::db::{Db, DbKind};
4use crate::desc::validate_desc;
5use crate::everything::Everything;
6use crate::game::GameFlags;
7use crate::item::{Item, ItemLoader};
8use crate::scopes::Scopes;
9use crate::token::Token;
10use crate::tooltipped::Tooltipped;
11use crate::validator::Validator;
12
13#[derive(Clone, Debug)]
14pub struct TaskContractType {}
15
16inventory::submit! {
17    ItemLoader::Normal(GameFlags::Ck3, Item::TaskContractType, TaskContractType::add)
18}
19
20impl TaskContractType {
21    pub fn add(db: &mut Db, key: Token, block: Block) {
22        db.add(Item::TaskContractType, key, block, Box::new(Self {}));
23    }
24}
25
26impl DbKind for TaskContractType {
27    fn add_subitems(&self, _key: &Token, block: &Block, db: &mut Db) {
28        if let Some(group) = block.get_field_value("group") {
29            db.add_flag(Item::TaskContractGroup, group.clone());
30        }
31        if let Some(block) = block.get_field_block("task_contract_reward") {
32            for (key, _) in block.iter_definitions() {
33                db.add_flag(Item::TaskContractReward, key.clone());
34            }
35        }
36    }
37
38    fn validate(&self, key: &Token, block: &Block, data: &Everything) {
39        fn sc_weight(key: &Token) -> ScopeContext {
40            let mut sc = ScopeContext::new(Scopes::Character, key);
41            sc.define_name("employer", Scopes::Character, key);
42            sc
43        }
44
45        let mut vd = Validator::new(block, data);
46        let mut sc = ScopeContext::new(Scopes::TaskContractType, key);
47
48        let loca = format!("{key}_contract");
49        data.verify_exists_implied(Item::Localization, &loca, key);
50
51        vd.field_value("group");
52        vd.field_item("icon", Item::File);
53
54        if block.has_key("desc") {
55            vd.field_validated_sc("desc", &mut sc, validate_desc);
56        } else {
57            let loca = format!("{key}_desc");
58            data.verify_exists_implied(Item::Localization, &loca, key);
59            let loca = format!("{key}_desc_title");
60            data.verify_exists_implied(Item::Localization, &loca, key);
61        }
62
63        if block.has_key("task_contract_request") {
64            vd.field_validated_sc("task_contract_request", &mut sc, validate_desc);
65        } else {
66            let loca = format!("{key}_request");
67            data.verify_exists_implied(Item::Localization, &loca, key);
68        }
69
70        vd.field_bool("travel");
71        vd.field_bool("is_criminal");
72        vd.field_bool("use_diplomatic_range");
73
74        vd.field_trigger_builder("valid_to_create", Tooltipped::No, |key| {
75            let mut sc = ScopeContext::new(Scopes::Character, key);
76            sc.define_name("employer", Scopes::Character, key);
77            sc
78        });
79        vd.field_trigger_builder("valid_to_accept", Tooltipped::No, |key| {
80            let mut sc = ScopeContext::new(Scopes::Character, key);
81            sc.define_name("employer", Scopes::Character, key);
82            sc
83        });
84        vd.field_trigger_rooted("valid_to_continue", Tooltipped::No, Scopes::TaskContract);
85        vd.field_trigger_rooted("valid_to_keep", Tooltipped::No, Scopes::TaskContract);
86
87        vd.field_effect_builder("on_create", Tooltipped::No, |key| {
88            let mut sc = ScopeContext::new(Scopes::Character, key);
89            sc.define_name("contract", Scopes::TaskContract, key);
90            sc
91        });
92
93        for field in &["on_accepted", "on_completed", "on_invalidated"] {
94            vd.field_effect_rooted(field, Tooltipped::No, Scopes::TaskContract);
95        }
96
97        vd.field_bool("should_show_toast_on_complete");
98
99        vd.field_validated_block("task_contract_reward", |block, data| {
100            let mut vd = Validator::new(block, data);
101            vd.unknown_block_fields(|_, block| {
102                let mut vd = Validator::new(block, data);
103                vd.field_effect_rooted("effect", Tooltipped::Yes, Scopes::TaskContract);
104                vd.field_bool("should_print_on_complete");
105                vd.field_bool("visible");
106                vd.field_bool("positive");
107            });
108        });
109
110        vd.field_script_value_no_breakdown_builder("weight", sc_weight);
111    }
112}