use super::types::GenerationType;
use crate::resources::Resource;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct GenerationConfig {
pub global_generation_multiplier: f32,
pub environment_modifiers: HashMap<GenerationType, EnvironmentModifiers>,
pub auto_remove_on_complete: bool,
pub max_generation_events: usize,
}
impl Default for GenerationConfig {
fn default() -> Self {
let mut environment_modifiers = HashMap::new();
environment_modifiers.insert(
GenerationType::Organic,
EnvironmentModifiers {
temperature_factor: 0.5,
fertility_factor: 0.8,
resource_factor: 0.3,
light_factor: 0.6,
},
);
environment_modifiers.insert(
GenerationType::Construction,
EnvironmentModifiers {
temperature_factor: 0.1,
fertility_factor: 0.2,
resource_factor: 1.0,
light_factor: 0.0,
},
);
environment_modifiers.insert(
GenerationType::Production,
EnvironmentModifiers {
temperature_factor: 0.0,
fertility_factor: 0.0,
resource_factor: 1.0,
light_factor: 0.0,
},
);
environment_modifiers.insert(
GenerationType::Recovery,
EnvironmentModifiers {
temperature_factor: 0.3,
fertility_factor: 0.1,
resource_factor: 0.7,
light_factor: 0.2,
},
);
Self {
global_generation_multiplier: 1.0,
environment_modifiers,
auto_remove_on_complete: false,
max_generation_events: 1000,
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct EnvironmentModifiers {
pub temperature_factor: f32,
pub fertility_factor: f32,
pub resource_factor: f32,
pub light_factor: f32,
}
impl EnvironmentModifiers {
pub fn calculate_modifier(
&self,
temperature: f32,
fertility: f32,
resource_availability: f32,
light_exposure: f32,
) -> f32 {
let temp_mod = self.temperature_modifier(temperature);
let fert_mod = fertility * self.fertility_factor;
let res_mod = resource_availability * self.resource_factor;
let light_mod = light_exposure * self.light_factor;
let total_factor = self.temperature_factor
+ self.fertility_factor
+ self.resource_factor
+ self.light_factor;
if total_factor > 0.0 {
(temp_mod + fert_mod + res_mod + light_mod) / total_factor
} else {
1.0
}
}
fn temperature_modifier(&self, temperature: f32) -> f32 {
if self.temperature_factor <= 0.0 {
return 0.0;
}
let optimal_temp = 22.5;
let temp_range = 15.0;
let diff = (temperature - optimal_temp).abs();
let modifier = (1.0 - (diff / temp_range)).max(0.0);
modifier * self.temperature_factor
}
}
impl Resource for GenerationConfig {}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_config() {
let config = GenerationConfig::default();
assert_eq!(config.global_generation_multiplier, 1.0);
assert!(!config.auto_remove_on_complete);
assert_eq!(config.max_generation_events, 1000);
assert!(config
.environment_modifiers
.contains_key(&GenerationType::Organic));
}
#[test]
fn test_environment_modifiers_organic() {
let modifiers = EnvironmentModifiers {
temperature_factor: 0.5,
fertility_factor: 0.8,
resource_factor: 0.3,
light_factor: 0.6,
};
let modifier = modifiers.calculate_modifier(22.0, 0.9, 1.0, 0.8);
assert!(modifier > 0.5);
let modifier = modifiers.calculate_modifier(5.0, 0.1, 0.1, 0.1);
assert!(modifier < 0.3);
}
#[test]
fn test_temperature_modifier() {
let modifiers = EnvironmentModifiers {
temperature_factor: 1.0,
fertility_factor: 0.0,
resource_factor: 0.0,
light_factor: 0.0,
};
let mod_optimal = modifiers.calculate_modifier(22.5, 0.0, 0.0, 0.0);
assert!(mod_optimal > 0.9);
let mod_cold = modifiers.calculate_modifier(5.0, 0.0, 0.0, 0.0);
assert!(mod_cold < 0.5);
let mod_hot = modifiers.calculate_modifier(40.0, 0.0, 0.0, 0.0);
assert!(mod_hot < 0.5);
}
}