tiger_lib/ck3/data/
gamerules.rs1use crate::block::Block;
2use crate::db::{Db, DbKind};
3use crate::everything::Everything;
4use crate::game::GameFlags;
5use crate::item::{Item, ItemLoader};
6use crate::report::{ErrorKey, err};
7use crate::token::Token;
8use crate::validator::Validator;
9
10#[derive(Clone, Debug)]
11pub struct GameRule {}
12
13inventory::submit! {
14 ItemLoader::Normal(GameFlags::Ck3, Item::GameRule, GameRule::add)
15}
16
17impl GameRule {
18 pub fn add(db: &mut Db, key: Token, block: Block) {
19 db.add(Item::GameRule, key, block, Box::new(Self {}));
20 }
21}
22
23impl DbKind for GameRule {
24 fn add_subitems(&self, _key: &Token, block: &Block, db: &mut Db) {
25 for (key, _) in block.iter_definitions() {
26 if !key.is("categories") {
27 db.add_flag(Item::GameRuleSetting, key.clone());
28 }
29 }
30 }
31
32 fn validate(&self, key: &Token, block: &Block, data: &Everything) {
33 let mut vd = Validator::new(block, data);
34
35 let loca = format!("rule_{key}");
36 data.verify_exists_implied(Item::Localization, &loca, key);
37
38 vd.field_validated_block("categories", |block, data| {
39 let mut vd = Validator::new(block, data);
40 for token in vd.values() {
41 let loca = format!("game_rule_category_{token}");
42 data.verify_exists_implied(Item::Localization, &loca, token);
43 }
44 });
45
46 if let Some(token) = vd.field_value("default") {
47 if token.is("categories") || block.get_field_block(token.as_str()).is_none() {
48 let msg = "this rule does not have that setting";
49 err(ErrorKey::MissingItem).msg(msg).loc(token).push();
50 }
51 }
52
53 vd.unknown_block_fields(|setting, block| {
54 let mut vd = Validator::new(block, data);
55 let loca = format!("setting_{setting}");
56 data.verify_exists_implied(Item::Localization, &loca, setting);
57 let loca = format!("setting_{setting}_desc");
58 data.verify_exists_implied(Item::Localization, &loca, setting);
59 if let Some(token) = vd.field_value("apply_modifier") {
60 if let Some((category, modifier)) = token.split_once(':') {
61 if !category.is("player") && !category.is("ai") && !category.is("all") {
62 let msg = "expected player: ai: or all:";
63 err(ErrorKey::Validation).msg(msg).loc(category).push();
64 }
65 data.verify_exists(Item::Modifier, &modifier);
66 } else {
67 let msg = "expected format category:modifier";
68 err(ErrorKey::Validation).msg(msg).loc(token).push();
69 }
70 }
71
72 vd.field_validated_block("defines", |block, data| {
73 let mut vd = Validator::new(block, data);
74 vd.unknown_block_fields(|group, block| {
75 let mut vd = Validator::new(block, data);
76 vd.unknown_fields(|key, _| {
77 let define_key = format!("{group}|{key}");
78 data.verify_exists_implied(Item::Define, &define_key, key);
79 });
80 });
81 });
82
83 vd.multi_field_value("flag");
86 });
87 }
88}