use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub struct CultureConfig {
pub base_stress_rate: f32,
pub base_fervor_growth_rate: f32,
pub stress_breakdown_threshold: f32,
pub fervor_fanaticism_threshold: f32,
pub culture_strength: f32,
pub enable_stress_decay: bool,
pub stress_decay_rate: f32,
}
impl crate::resources::Resource for CultureConfig {}
impl Default for CultureConfig {
fn default() -> Self {
Self {
base_stress_rate: 0.03, base_fervor_growth_rate: 0.02, stress_breakdown_threshold: 0.8, fervor_fanaticism_threshold: 0.9, culture_strength: 1.0, enable_stress_decay: true,
stress_decay_rate: 0.01, }
}
}
impl CultureConfig {
pub fn new(
stress_rate: f32,
fervor_rate: f32,
stress_threshold: f32,
fervor_threshold: f32,
culture_strength: f32,
) -> Self {
Self {
base_stress_rate: stress_rate.clamp(0.0, 1.0),
base_fervor_growth_rate: fervor_rate.clamp(0.0, 1.0),
stress_breakdown_threshold: stress_threshold.clamp(0.0, 1.0),
fervor_fanaticism_threshold: fervor_threshold.clamp(0.0, 1.0),
culture_strength: culture_strength.clamp(0.0, 2.0),
enable_stress_decay: true,
stress_decay_rate: 0.01,
}
}
pub fn with_stress_rate(mut self, rate: f32) -> Self {
self.base_stress_rate = rate.clamp(0.0, 1.0);
self
}
pub fn with_fervor_rate(mut self, rate: f32) -> Self {
self.base_fervor_growth_rate = rate.clamp(0.0, 1.0);
self
}
pub fn with_stress_threshold(mut self, threshold: f32) -> Self {
self.stress_breakdown_threshold = threshold.clamp(0.0, 1.0);
self
}
pub fn with_fervor_threshold(mut self, threshold: f32) -> Self {
self.fervor_fanaticism_threshold = threshold.clamp(0.0, 1.0);
self
}
pub fn with_culture_strength(mut self, strength: f32) -> Self {
self.culture_strength = strength.clamp(0.0, 2.0);
self
}
pub fn with_stress_decay(mut self, enable: bool) -> Self {
self.enable_stress_decay = enable;
self
}
pub fn with_stress_decay_rate(mut self, rate: f32) -> Self {
self.stress_decay_rate = rate.clamp(0.0, 1.0);
self
}
pub fn is_valid(&self) -> bool {
self.base_stress_rate >= 0.0
&& self.base_stress_rate <= 1.0
&& self.base_fervor_growth_rate >= 0.0
&& self.base_fervor_growth_rate <= 1.0
&& self.stress_breakdown_threshold >= 0.0
&& self.stress_breakdown_threshold <= 1.0
&& self.fervor_fanaticism_threshold >= 0.0
&& self.fervor_fanaticism_threshold <= 1.0
&& self.culture_strength >= 0.0
&& self.culture_strength <= 2.0
&& self.stress_decay_rate >= 0.0
&& self.stress_decay_rate <= 1.0
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_config() {
let config = CultureConfig::default();
assert_eq!(config.base_stress_rate, 0.03);
assert_eq!(config.base_fervor_growth_rate, 0.02);
assert_eq!(config.stress_breakdown_threshold, 0.8);
assert_eq!(config.fervor_fanaticism_threshold, 0.9);
assert_eq!(config.culture_strength, 1.0);
assert!(config.enable_stress_decay);
assert_eq!(config.stress_decay_rate, 0.01);
assert!(config.is_valid());
}
#[test]
fn test_custom_config() {
let config = CultureConfig::new(0.05, 0.03, 0.7, 0.85, 1.5);
assert_eq!(config.base_stress_rate, 0.05);
assert_eq!(config.base_fervor_growth_rate, 0.03);
assert_eq!(config.stress_breakdown_threshold, 0.7);
assert_eq!(config.fervor_fanaticism_threshold, 0.85);
assert_eq!(config.culture_strength, 1.5);
assert!(config.is_valid());
}
#[test]
fn test_builder_pattern() {
let config = CultureConfig::default()
.with_stress_rate(0.04)
.with_fervor_rate(0.025)
.with_stress_threshold(0.75)
.with_fervor_threshold(0.88)
.with_culture_strength(1.2)
.with_stress_decay(false)
.with_stress_decay_rate(0.02);
assert_eq!(config.base_stress_rate, 0.04);
assert_eq!(config.base_fervor_growth_rate, 0.025);
assert_eq!(config.stress_breakdown_threshold, 0.75);
assert_eq!(config.fervor_fanaticism_threshold, 0.88);
assert_eq!(config.culture_strength, 1.2);
assert!(!config.enable_stress_decay);
assert_eq!(config.stress_decay_rate, 0.02);
}
#[test]
fn test_clamping() {
let config = CultureConfig::new(1.5, -0.2, 2.0, -1.0, 3.0);
assert_eq!(config.base_stress_rate, 1.0); assert_eq!(config.base_fervor_growth_rate, 0.0); assert_eq!(config.stress_breakdown_threshold, 1.0); assert_eq!(config.fervor_fanaticism_threshold, 0.0); assert_eq!(config.culture_strength, 2.0); assert!(config.is_valid());
}
#[test]
fn test_serialization() {
let config = CultureConfig::default();
let json = serde_json::to_string(&config).unwrap();
let deserialized: CultureConfig = serde_json::from_str(&json).unwrap();
assert_eq!(config, deserialized);
}
#[test]
fn test_extreme_weak_culture() {
let config = CultureConfig::default().with_culture_strength(0.1);
assert_eq!(config.culture_strength, 0.1);
assert!(config.is_valid());
}
#[test]
fn test_extreme_strong_culture() {
let config = CultureConfig::default().with_culture_strength(2.0);
assert_eq!(config.culture_strength, 2.0);
assert!(config.is_valid());
}
#[test]
fn test_is_valid_with_invalid_values() {
let config = CultureConfig {
base_stress_rate: 1.5, ..Default::default()
};
assert!(!config.is_valid());
}
#[test]
fn test_stress_decay_disabled() {
let config = CultureConfig::default().with_stress_decay(false);
assert!(!config.enable_stress_decay);
assert!(config.is_valid());
}
}