use super::cost::{Cost, ResourceRatio};
use super::{Food, Iron, Resources, Stone, Wood};
use crate::check_total_resource_ratio;
use derive_more::Display;
use nil_num::triangle::nearest_triangle;
use nil_util::ConstDeref;
use serde::{Deserialize, Serialize};
use std::num::NonZeroU32;
#[derive(Copy, Debug, Display, Deserialize, Serialize, ConstDeref)]
#[derive_const(Clone, PartialEq, Eq, PartialOrd, Ord)]
#[cfg_attr(feature = "typescript", derive(ts_rs::TS))]
pub struct Influence(NonZeroU32);
impl Influence {
pub const MIN: Influence = Influence(NonZeroU32::MIN);
pub const MAX: Influence = Influence(NonZeroU32::MAX);
pub const COST: Cost = Cost::new(100_000);
pub const FOOD_RATIO: ResourceRatio = ResourceRatio::new(0.19);
pub const IRON_RATIO: ResourceRatio = ResourceRatio::new(0.27);
pub const STONE_RATIO: ResourceRatio = ResourceRatio::new(0.27);
pub const WOOD_RATIO: ResourceRatio = ResourceRatio::new(0.27);
}
impl Influence {
pub const unsafe fn new_unchecked(value: u32) -> Self {
unsafe { Self(NonZeroU32::new_unchecked(value)) }
}
pub const fn resources() -> Resources {
Resources {
food: Food::from((Self::COST * Self::FOOD_RATIO).round()),
iron: Iron::from((Self::COST * Self::IRON_RATIO).round()),
stone: Stone::from((Self::COST * Self::STONE_RATIO).round()),
wood: Wood::from((Self::COST * Self::WOOD_RATIO).round()),
}
}
#[inline]
pub fn city_limit(&self) -> u32 {
nearest_triangle(self.0.get())
}
}
impl const Default for Influence {
fn default() -> Self {
Self::MIN
}
}
check_total_resource_ratio!(
Influence::FOOD_RATIO,
Influence::IRON_RATIO,
Influence::STONE_RATIO,
Influence::WOOD_RATIO
);