tiger_lib/ck3/data/
perks.rs1use crate::block::Block;
2use crate::ck3::modif::ModifKinds;
3use crate::context::ScopeContext;
4use crate::db::{Db, DbKind};
5use crate::desc::validate_desc;
6use crate::everything::Everything;
7use crate::game::GameFlags;
8use crate::item::{Item, ItemLoader};
9use crate::modif::validate_modifs;
10use crate::scopes::Scopes;
11use crate::token::Token;
12use crate::tooltipped::Tooltipped;
13use crate::validator::Validator;
14
15#[derive(Clone, Debug)]
16pub struct Perk {}
17
18inventory::submit! {
19 ItemLoader::Normal(GameFlags::Ck3, Item::Perk, Perk::add)
20}
21
22impl Perk {
23 pub fn add(db: &mut Db, key: Token, block: Block) {
24 db.add(Item::Perk, key, block, Box::new(Self {}));
25 }
26}
27
28impl DbKind for Perk {
29 fn add_subitems(&self, _key: &Token, block: &Block, db: &mut Db) {
30 if let Some(tree) = block.get_field_value("tree") {
31 db.add_flag(Item::PerkTree, tree.clone());
32 }
33 }
34
35 fn validate(&self, key: &Token, block: &Block, data: &Everything) {
36 let mut vd = Validator::new(block, data);
37 let mut sc = ScopeContext::new(Scopes::Character, key);
38
39 if !vd.field_validated_sc("name", &mut sc, validate_desc) {
40 let loca = format!("{key}_name");
41 data.verify_exists_implied(Item::Localization, &loca, key);
42 }
43
44 if let Some(token) = vd.field_value("tree") {
45 let loca = format!("{token}_name");
46 data.verify_exists_implied(Item::Localization, &loca, token);
47 data.verify_icon("NGameIcons|LIFESTYPE_TREE_BACKGROUND_PATH", token, ".dds");
48 }
49 vd.field_validated_block("position", |block, data| {
50 let mut vd = Validator::new(block, data);
51 vd.req_tokens_numbers_exactly(2);
52 });
53
54 let icon = vd.field_value("icon").unwrap_or(key);
55 data.verify_icon("NGameIcons|PERK_ICON_PATH", icon, ".dds");
56
57 vd.field_item("lifestyle", Item::Lifestyle);
58 for parent in vd.multi_field_value("parent") {
60 data.verify_exists(Item::Perk, parent);
61 }
62
63 vd.field_trigger_rooted("can_be_picked", Tooltipped::Yes, Scopes::Character);
64 vd.field_trigger_rooted("can_be_auto_selected", Tooltipped::No, Scopes::Character);
65 vd.multi_field_item("trait", Item::Trait);
66 vd.field_effect_rooted("effect", Tooltipped::Yes, Scopes::Character);
67
68 vd.multi_field_validated_block("character_modifier", |block, data| {
69 let vd = Validator::new(block, data);
70 validate_modifs(block, data, ModifKinds::Character, vd);
71 });
72 vd.multi_field_validated_block("doctrine_character_modifier", |block, data| {
73 let mut vd = Validator::new(block, data);
74 vd.field_item("doctrine", Item::Doctrine);
75 validate_modifs(block, data, ModifKinds::Character, vd);
76 });
77 vd.multi_field_validated_block("culture_character_modifier", |block, data| {
78 let mut vd = Validator::new(block, data);
79 vd.field_item("parameter", Item::CultureParameter);
80 validate_modifs(block, data, ModifKinds::Character, vd);
81 });
82 vd.multi_field_validated_block("government_character_modifier", |block, data| {
83 let mut vd = Validator::new(block, data);
84 vd.field_item("flag", Item::GovernmentFlag);
85 vd.field_bool("invert_check");
86 validate_modifs(block, data, ModifKinds::Character, vd);
87 });
88
89 vd.field_script_value("auto_selection_weight", &mut sc);
90 }
91}