use std::fmt::{self, Display};
use crate::{world::{graph::Node, Graph}, util::{constants::{DEFAULT_SPAWN, SPAWN_GRANTS}}, header, settings::{UniverseSettings, WorldSettings}};
use crate::uber_state::UberStateTrigger;
use super::{spoiler::SeedSpoiler, Placement};
pub struct Seed<'graph, 'settings> {
pub worlds: Vec<SeedWorld<'graph, 'settings>>,
pub graph: &'graph Graph,
pub settings: &'settings UniverseSettings,
pub spoiler: SeedSpoiler,
}
pub struct SeedWorld<'graph, 'settings> {
pub flags: Vec<String>,
pub spawn: &'graph Node,
pub placements: Vec<Placement<'graph>>,
pub headers: String,
pub world_settings: &'settings WorldSettings,
}
impl Seed<'_, '_> {
pub fn seed_files(&self) -> Result<Vec<String>, String> {
let mut seeds = self.worlds.iter().enumerate().map(|(index, world)| {
let version = env!("CARGO_PKG_VERSION");
let slug = &self.settings.slugify();
let config = &self.settings.to_json();
format!("\
{world}\
// This World: {index}\n\
// Target: ^2.0\n\
// Generator Version: {version}\n\
// Slug: {slug}\n\
// Config: {config}\n\
")
}).collect::<Vec<_>>();
header::parser::postprocess(&mut seeds, self.graph, self.settings)?;
Ok(seeds)
}
}
impl Display for SeedWorld<'_, '_> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if !self.flags.is_empty() {
writeln!(f, "Flags: {}", self.flags.join(", "))?;
}
let spawn_identifier = self.spawn.identifier();
if spawn_identifier != DEFAULT_SPAWN {
let position = self.spawn.position().expect("Seed Spawn had no coordinates");
writeln!(f, "Spawn: {}, {} // {}", position.x, position.y, spawn_identifier)?;
if let Some(spawn_item) = SPAWN_GRANTS.iter().find_map(|(spawn, item)| if *spawn == spawn_identifier { Some(item) } else { None }) {
writeln!(f, "{}|{}|mute", UberStateTrigger::spawn().code(), spawn_item.code())?;
}
}
for placement in &self.placements {
writeln!(f, "{}", placement.code())?;
}
write!(f, "{}", self.headers)?;
if !self.headers.ends_with('\n') { writeln!(f,)?; }
Ok(())
}
}