Skip to main content

nil_core/infrastructure/
catalog.rs

1// Copyright (C) Call of Nil contributors
2// SPDX-License-Identifier: AGPL-3.0-only
3
4#[doc(hidden)]
5#[macro_export]
6macro_rules! decl_recruit_catalog_entry {
7  ($building:ident) => {
8    paste::paste! {
9      #[derive(Clone, Debug, Deserialize, Serialize)]
10      #[serde(tag = "kind", rename_all = "kebab-case")]
11      #[cfg_attr(feature = "typescript", derive(ts_rs::TS))]
12      pub enum [<$building RecruitCatalogEntry>] {
13        /// Unit is available for recruitment.
14        Available { recipe: Box<[<$building RecruitCatalogRecipe>]> },
15        /// City does not meet the requirements for recruitment.
16        Unmet {
17          requirements: InfrastructureRequirements,
18        },
19      }
20
21      impl [<$building RecruitCatalogEntry>] {
22        fn new(unit: &dyn Unit, infrastructure: &Infrastructure) -> Self {
23          let infra_req = unit.infrastructure_requirements();
24          if !infra_req.has_required_levels(infrastructure) {
25            return Self::Unmet { requirements: infra_req.clone() };
26          }
27
28          let chunk = unit.chunk();
29          let recipe = Box::new([<$building RecruitCatalogRecipe>] {
30            resources: chunk.resources(),
31            maintenance: chunk.maintenance(),
32            workforce: chunk.workforce(),
33            requirements: infra_req.clone(),
34          });
35
36          Self::Available { recipe }
37        }
38      }
39
40      #[derive(Clone, Debug, Deserialize, Serialize)]
41      #[serde(rename_all = "camelCase")]
42      #[cfg_attr(feature = "typescript", derive(ts_rs::TS))]
43      pub struct [<$building RecruitCatalogRecipe>] {
44        resources: Resources,
45        maintenance: Maintenance,
46        workforce: Workforce,
47        requirements: InfrastructureRequirements,
48      }
49    }
50  };
51}