tiger_lib/data/
environment.rs1use crate::block::{BV, Block};
2use crate::db::{Db, DbKind};
3use crate::everything::Everything;
4use crate::game::Game;
5use crate::game::GameFlags;
6use crate::item::{Item, ItemLoader};
7use crate::token::Token;
8use crate::validate::validate_camera_color;
9use crate::validator::Validator;
10
11#[derive(Clone, Debug)]
12pub struct PortraitEnvironment {}
13
14inventory::submit! {
15 ItemLoader::Normal(GameFlags::jomini(), Item::PortraitEnvironment, PortraitEnvironment::add)
16}
17
18impl PortraitEnvironment {
19 pub fn add(db: &mut Db, key: Token, block: Block) {
20 db.add(Item::PortraitEnvironment, key, block, Box::new(Self {}));
21 }
22}
23
24impl DbKind for PortraitEnvironment {
25 fn validate(&self, _key: &Token, block: &Block, data: &Everything) {
26 let mut vd = Validator::new(block, data);
27
28 vd.field_item("cubemap", Item::File);
29 vd.field_precise_numeric("cubemap_intensity");
30 vd.field_precise_numeric("cubemap_y_rotation");
31
32 vd.field_validated("lights", |bv, data| {
33 match bv {
34 BV::Value(token) => data.verify_exists(Item::PortraitEnvironment, token),
35 BV::Block(block) => {
36 let mut vd = Validator::new(block, data);
37 for (_, block) in vd.integer_blocks() {
38 let mut vd = Validator::new(block, data);
39 vd.field_choice(
40 "type",
41 &["spot_light", "point_light", "directional_light"],
42 );
43 vd.field_bool("affected_by_shadow");
44 vd.field_validated_block("color", validate_camera_color);
45
46 vd.field_list_precise_numeric_exactly("position", 3);
47 if block.field_value_is("type", "spot_light")
48 || block.field_value_is("type", "directional_light")
49 {
50 vd.field_list_precise_numeric_exactly("look_at", 3);
51 if Game::is_ck3() {
52 vd.field_block("look_at_node"); } else if Game::is_vic3() {
54 vd.field_value("look_at_node");
55 }
56 } else {
57 vd.ban_field("look_at", || "spot_light or directional_light");
58 vd.ban_field("look_at_node", || "spot_light or directional_light");
59 }
60 vd.field_block("position_node"); if block.field_value_is("type", "spot_light")
63 || block.field_value_is("type", "point_light")
64 {
65 vd.field_precise_numeric("radius");
66 vd.field_precise_numeric("falloff");
67 } else {
68 vd.ban_field("radius", || "spot_light or point_light");
69 vd.ban_field("falloff", || "spot_light or point_light");
70 }
71 if block.field_value_is("type", "point_light") {
72 vd.field_precise_numeric("outer_cone_angle");
73 vd.field_precise_numeric("inner_cone_angle");
74 } else {
75 vd.advice_field(
78 "outer_cone_angle",
79 "outer_cone_angle is only for point_light",
80 );
81 vd.advice_field(
82 "inner_cone_angle",
83 "inner_cone_angle is only for point_light",
84 );
85 }
86 }
87 }
88 }
89 });
90
91 vd.field_validated("shadow_camera", |bv, data| {
92 match bv {
93 BV::Value(token) => data.verify_exists(Item::PortraitEnvironment, token),
94 BV::Block(block) => {
95 let mut vd = Validator::new(block, data);
96
97 vd.field_list_precise_numeric_exactly("position", 3);
98 vd.field_list_precise_numeric_exactly("look_at", 3);
99 if Game::is_ck3() {
100 vd.field_block("look_at_node"); } else if Game::is_vic3() {
102 vd.field_value("look_at_node"); }
104 vd.field_block("position_node"); vd.field_precise_numeric("fov");
106 vd.field_list_integers_exactly("camera_near_far", 2);
107 }
108 }
109 });
110 }
111}