Skip to main content

nil_core/
ethic.rs

1// Copyright (C) Call of Nil contributors
2// SPDX-License-Identifier: AGPL-3.0-only
3
4use bon::Builder;
5use rand::seq::IndexedRandom;
6use serde::{Deserialize, Serialize};
7use std::fmt::Debug;
8use strum::{EnumIs, VariantArray};
9
10#[derive(Builder, Clone, Debug, Deserialize, Serialize)]
11#[serde(rename_all = "camelCase")]
12#[builder(const)]
13pub struct Ethics {
14  power: EthicPowerAxis,
15  truth: EthicTruthAxis,
16}
17
18impl Ethics {
19  pub fn random() -> Self {
20    Self {
21      power: EthicPowerAxis::random(),
22      truth: EthicTruthAxis::random(),
23    }
24  }
25
26  #[inline]
27  pub const fn power(&self) -> EthicPowerAxis {
28    self.power
29  }
30
31  #[inline]
32  pub const fn truth(&self) -> EthicTruthAxis {
33    self.truth
34  }
35
36  #[inline]
37  pub const fn is_militarist(&self) -> bool {
38    self.power.is_militarist()
39  }
40
41  #[inline]
42  pub const fn is_fanatic_militarist(&self) -> bool {
43    self.power.is_fanatic_militarist()
44  }
45
46  #[inline]
47  pub const fn is_pacifist(&self) -> bool {
48    self.power.is_pacifist()
49  }
50
51  #[inline]
52  pub const fn is_fanatic_pacifist(&self) -> bool {
53    self.power.is_fanatic_pacifist()
54  }
55
56  #[inline]
57  pub const fn is_materialist(&self) -> bool {
58    self.truth.is_materialist()
59  }
60
61  #[inline]
62  pub const fn is_fanatic_materialist(&self) -> bool {
63    self.truth.is_fanatic_materialist()
64  }
65
66  #[inline]
67  pub const fn is_spiritualist(&self) -> bool {
68    self.truth.is_spiritualist()
69  }
70
71  #[inline]
72  pub const fn is_fanatic_spiritualist(&self) -> bool {
73    self.truth.is_fanatic_spiritualist()
74  }
75}
76
77impl Default for Ethics {
78  fn default() -> Self {
79    Self::random()
80  }
81}
82
83#[derive(Clone, Copy, Debug, EnumIs, PartialEq, Eq, Deserialize, Serialize, VariantArray)]
84#[serde(rename_all = "kebab-case")]
85pub enum EthicPowerAxis {
86  Militarist,
87  FanaticMilitarist,
88  Pacifist,
89  FanaticPacifist,
90}
91
92impl EthicPowerAxis {
93  pub fn random() -> Self {
94    Self::VARIANTS
95      .choose_weighted(&mut rand::rng(), |ethic| {
96        match ethic {
97          Self::Militarist | Self::Pacifist => 4u8,
98          Self::FanaticMilitarist | Self::FanaticPacifist => 1u8,
99        }
100      })
101      .copied()
102      .expect("`Self::VARIANTS` should never be empty")
103  }
104}
105
106#[derive(Clone, Copy, Debug, EnumIs, PartialEq, Eq, Deserialize, Serialize, VariantArray)]
107#[serde(rename_all = "kebab-case")]
108pub enum EthicTruthAxis {
109  Materialist,
110  FanaticMaterialist,
111  Spiritualist,
112  FanaticSpiritualist,
113}
114
115impl EthicTruthAxis {
116  pub fn random() -> Self {
117    Self::VARIANTS
118      .choose_weighted(&mut rand::rng(), |ethic| {
119        match ethic {
120          Self::Materialist | Self::Spiritualist => 4u8,
121          Self::FanaticMaterialist | Self::FanaticSpiritualist => 1u8,
122        }
123      })
124      .copied()
125      .expect("`Self::VARIANTS` should never be empty")
126  }
127}