tiger_lib/ck3/data/
election.rs1use 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::report::{ErrorKey, warn};
8use crate::scopes::Scopes;
9use crate::token::Token;
10use crate::tooltipped::Tooltipped;
11use crate::validate::validate_modifiers_with_base;
12use crate::validator::Validator;
13
14#[derive(Clone, Debug)]
15pub struct Election {}
16
17inventory::submit! {
18 ItemLoader::Normal(GameFlags::Ck3, Item::SuccessionElection, Election::add)
19}
20
21impl Election {
22 pub fn add(db: &mut Db, key: Token, block: Block) {
23 db.add(Item::SuccessionElection, key, block, Box::new(Self {}));
24 }
25}
26
27impl DbKind for Election {
28 fn validate(&self, key: &Token, block: &Block, data: &Everything) {
29 let loca = format!("{key}_candidates");
30 data.verify_exists_implied(Item::Localization, &loca, key);
31 let loca = format!("{key}_candidates_tooltip");
32 data.verify_exists_implied(Item::Localization, &loca, key);
33 let loca = format!("{key}_electors");
34 data.verify_exists_implied(Item::Localization, &loca, key);
35 let loca = format!("{key}_electors_tooltip");
36 data.verify_exists_implied(Item::Localization, &loca, key);
37
38 let mut vd = Validator::new(block, data);
39 let mut sc = ScopeContext::new(Scopes::Character, key);
40 sc.define_name("title", Scopes::LandedTitle, key);
41 sc.define_name("holder", Scopes::Character, key);
42
43 vd.field_validated_block("candidates", |block, data| {
44 let mut vd = Validator::new(block, data);
45 validate_candidates(&mut vd, &mut sc);
46 });
47
48 vd.field_validated_block("electors", |block, data| {
49 let mut vd = Validator::new(block, data);
50 vd.field_integer("max");
51 vd.field_validated_block_sc("priority", &mut sc, validate_modifiers_with_base);
52 validate_candidates(&mut vd, &mut sc);
53 });
54
55 vd.field_validated_block_sc("elector_vote_strength", &mut sc, validate_modifiers_with_base);
56
57 sc.define_name("candidate", Scopes::Character, key);
58 sc.define_name("holder_candidate", Scopes::Character, key);
59 vd.field_validated_block_sc("candidate_score", &mut sc, validate_modifiers_with_base);
60 }
61}
62
63fn validate_candidates(vd: &mut Validator, sc: &mut ScopeContext) {
64 vd.multi_field_validated("add", |bv, data| match bv {
65 BV::Value(token) => {
66 if !CANDIDATE_TYPES.contains(&token.as_str()) {
67 let msg = "unknown candidate category";
68 warn(ErrorKey::Choice).msg(msg).loc(token).push();
69 }
70 }
71 BV::Block(block) => {
72 let mut vd = Validator::new(block, data);
73 vd.field_choice("type", CANDIDATE_TYPES);
74 vd.field_trigger("limit", Tooltipped::No, sc);
75 }
76 });
77 vd.field_trigger("limit", Tooltipped::No, sc);
78}
79
80const CANDIDATE_TYPES: &[&str] = &[
81 "title_claimants",
82 "title_dejure_vassals",
83 "holder",
84 "holder_direct_vassals",
85 "holder_spouses",
86 "holder_close_family",
87 "holder_close_or_extended_family",
88 "holder_dynasty",
89 "holder_council_members",
90 "holder_tributaries",
91];