tiger_lib/imperator/
events.rs1use crate::block::Block;
2use crate::context::ScopeContext;
3use crate::data::events::Event;
4use crate::desc::validate_desc;
5use crate::effect::{validate_effect, validate_effect_internal};
6use crate::everything::Everything;
7use crate::item::Item;
8use crate::lowercase::Lowercase;
9use crate::report::{ErrorKey, err, warn};
10use crate::scopes::Scopes;
11use crate::special_tokens::SpecialTokens;
12use crate::token::Token;
13use crate::tooltipped::Tooltipped;
14use crate::validate::{ListType, validate_ai_chance, validate_modifiers_with_base};
15use crate::validator::Validator;
16
17const EVENT_TYPES: &[&str] = &[
18 "character_event",
19 "minor_character_event",
20 "country_event",
21 "minor_country_event",
22 "major_country_event",
23 "state_event",
24 "province_event",
25];
26
27pub fn get_event_scope(key: &Token, block: &Block) -> (Scopes, Token) {
28 if let Some(event_type) = block.get_field_value("type") {
29 match event_type.as_str() {
30 "minor_character_event" | "character_event" => (Scopes::Character, event_type.clone()),
31 "country_event" | "minor_country_event" | "major_country_event" => {
32 (Scopes::Country, event_type.clone())
33 }
34 "state_event" => (Scopes::State, event_type.clone()),
35 "province_event" => (Scopes::Province, event_type.clone()),
36 _ => (Scopes::Country, key.clone()),
37 }
38 } else {
39 (Scopes::Country, key.clone())
40 }
41}
42
43pub fn validate_event(event: &Event, data: &Everything, sc: &mut ScopeContext) {
44 let mut vd = Validator::new(&event.block, data);
45
46 let mut tooltipped_immediate = Tooltipped::Past;
47 let mut tooltipped = Tooltipped::Yes;
48
49 vd.field_choice("type", EVENT_TYPES);
50 vd.field_bool("hidden");
51 vd.field_bool("interface_lock");
52 vd.field_bool("fire_only_once");
53
54 vd.field_trigger("trigger", Tooltipped::No, sc);
55 vd.field_validated_block_sc("weight_multiplier", sc, validate_modifiers_with_base);
56
57 vd.field_item_or_target(
58 "goto_location",
59 sc,
60 Item::Province,
61 Scopes::Province.union(Scopes::Country),
62 );
63
64 vd.field_validated_sc("title", sc, validate_desc);
65 vd.field_validated_sc("desc", sc, validate_desc);
66
67 sc.wipe_temporaries();
68 vd.field_effect("immediate", tooltipped_immediate, sc);
69
70 let hidden = event.block.field_value_is("hidden", "yes");
71 if hidden {
72 tooltipped_immediate = Tooltipped::No;
73 tooltipped = Tooltipped::No;
74 }
75
76 let mut minor_event = false;
77 if event.block.field_value_is("type", "minor_character_event")
78 || event.block.field_value_is("type", "minor_country_event")
79 {
80 minor_event = true;
81 }
82
83 if !hidden && !minor_event {
84 vd.req_field("picture");
85 }
86 vd.field_item("picture", Item::EventPicture);
87
88 for field in &["left_portrait", "right_portrait"] {
89 let mut count = 0;
90 vd.multi_field_validated_value(field, |_, mut vd| {
91 count += 1;
92 vd.target_ok_this(sc, Scopes::Character);
93 if count == 4 {
94 let msg = format!("Event has more than 3 {field} attributes.");
95 let info = "Events can only have up to 3 portraits displayed at a time.";
96 warn(ErrorKey::Validation).msg(msg).info(info).loc(&event.key).push();
97 }
98 });
99 }
100
101 if !hidden {
102 vd.req_field("option");
103 }
104 let mut has_options = false;
105 vd.multi_field_validated_block("option", |block, data| {
106 has_options = true;
107 sc.wipe_temporaries();
108 validate_event_option(block, data, sc, tooltipped);
109 });
110
111 vd.field_validated_key_block("after", |key, block, data| {
112 if !has_options {
113 let msg = "`after` effect will not run if there are no `option` blocks";
114 let info = "you can put it in `immediate` instead";
115 err(ErrorKey::Logic).msg(msg).info(info).loc(key).push();
116 }
117 sc.wipe_temporaries();
118 validate_effect(block, data, sc, tooltipped_immediate);
119 });
120}
121
122fn validate_event_option(
123 block: &Block,
124 data: &Everything,
125 sc: &mut ScopeContext,
126 tooltipped: Tooltipped,
127) {
128 let mut vd = Validator::new(block, data);
129 vd.field_validated_sc("name", sc, validate_desc);
130
131 vd.field_trigger("trigger", Tooltipped::No, sc);
132
133 vd.field_bool("exclusive");
134 vd.field_bool("highlight");
135 vd.field_validated_sc("ai_chance", sc, validate_ai_chance);
136 validate_effect_internal(
137 &Lowercase::new_unchecked("option"),
138 ListType::None,
139 block,
140 data,
141 sc,
142 &mut vd,
143 tooltipped,
144 &mut SpecialTokens::none(),
145 );
146}