tiger_lib/data/
achievements.rs1use 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}