tiger_lib/data/
achievements.rs

1use crate::block::Block;
2use crate::db::{Db, DbKind};
3use crate::everything::Everything;
4use crate::game::{Game, GameFlags};
5use crate::item::{Item, ItemLoader};
6#[cfg(feature = "jomini")]
7use crate::report::{ErrorKey, err};
8use crate::scopes::Scopes;
9use crate::token::Token;
10use crate::tooltipped::Tooltipped;
11use crate::validator::Validator;
12
13#[derive(Clone, Debug)]
14pub struct Achievement {}
15
16inventory::submit! {
17    ItemLoader::Normal(GameFlags::all(), Item::Achievement, Achievement::add)
18}
19
20impl Achievement {
21    pub fn add(db: &mut Db, key: Token, block: Block) {
22        db.add(Item::Achievement, key, block, Box::new(Self {}));
23    }
24}
25
26impl DbKind for Achievement {
27    fn validate(&self, key: &Token, block: &Block, data: &Everything) {
28        let mut vd = Validator::new(block, data);
29
30        if Game::is_jomini() {
31            let loca = format!("ACHIEVEMENT_{key}");
32            data.verify_exists_implied(Item::Localization, &loca, key);
33            let loca = format!("ACHIEVEMENT_DESC_{key}");
34            data.verify_exists_implied(Item::Localization, &loca, key);
35        }
36
37        if Game::is_hoi4() {
38            vd.field_integer("id");
39            vd.field_bool("hidden");
40        }
41
42        vd.field_trigger_rooted("possible", Tooltipped::No, achievement_scope());
43        vd.field_trigger_rooted("happened", Tooltipped::No, achievement_scope());
44    }
45}
46
47fn achievement_scope() -> Scopes {
48    match Game::game() {
49        #[cfg(feature = "ck3")]
50        Game::Ck3 => Scopes::Character,
51        #[cfg(feature = "vic3")]
52        Game::Vic3 => Scopes::Country,
53        #[cfg(feature = "imperator")]
54        Game::Imperator => Scopes::Country,
55        #[cfg(feature = "eu5")]
56        Game::Eu5 => Scopes::Country,
57        #[cfg(feature = "hoi4")]
58        Game::Hoi4 => Scopes::Country,
59    }
60}
61
62#[cfg(feature = "jomini")]
63#[derive(Clone, Debug)]
64pub struct AchievementGroup {}
65
66#[cfg(feature = "jomini")]
67inventory::submit! {
68    ItemLoader::Normal(GameFlags::jomini(), Item::AchievementGroup, AchievementGroup::add)
69}
70
71#[cfg(feature = "jomini")]
72impl AchievementGroup {
73    pub fn add(db: &mut Db, key: Token, block: Block) {
74        if key.is("group") {
75            if let Some(name) = block.get_field_value("name").cloned() {
76                db.add(Item::AchievementGroup, name, block, Box::new(Self {}));
77            } else {
78                let msg = "group missing `name` field";
79                err(ErrorKey::FieldMissing).msg(msg).loc(key).push();
80            }
81        } else {
82            let msg = "unknown key in achievement groups";
83            let info = "expected only `group`";
84            err(ErrorKey::UnknownField).msg(msg).info(info).loc(key).push();
85        }
86    }
87}
88
89#[cfg(feature = "jomini")]
90impl DbKind for AchievementGroup {
91    fn validate(&self, key: &Token, block: &Block, data: &Everything) {
92        let mut vd = Validator::new(block, data);
93
94        let loca = format!("ACHIEVEMENT_GROUP_{key}");
95        data.verify_exists_implied(Item::Localization, &loca, key);
96
97        vd.field_value("name");
98        vd.field_list_items("order", Item::Achievement);
99    }
100}