rust/mapgen/src/template/wavefront_collapse.rs
author unC0Rr
Tue, 10 Sep 2024 13:56:51 +0200
branchtransitional_engine
changeset 16061 31cc1e450273
parent 15955 b0e8cc72bfef
permissions -rw-r--r--
Add maze land generator ported from pascal engine

use integral_geometry::Size;

use landgen::wavefront_collapse::generator::*;
use serde_derive::Deserialize;

use std::collections::hash_map::HashMap;

#[derive(Deserialize)]
#[serde(remote = "EdgeDescription")]
pub struct EdgeDesc {
    pub name: String,
    pub reversed: Option<bool>,
    pub symmetrical: Option<bool>,
}

#[derive(Deserialize)]
#[serde(remote = "EdgesDescription")]
pub struct EdgesDesc {
    #[serde(with = "EdgeDesc")]
    pub top: EdgeDescription,
    #[serde(with = "EdgeDesc")]
    pub right: EdgeDescription,
    #[serde(with = "EdgeDesc")]
    pub bottom: EdgeDescription,
    #[serde(with = "EdgeDesc")]
    pub left: EdgeDescription,
}

#[derive(Deserialize)]
#[serde(remote = "TileDescription")]
pub struct TileDesc {
    pub name: String,
    #[serde(with = "EdgesDesc")]
    pub edges: EdgesDescription,
    pub is_negative: Option<bool>,
    pub can_flip: Option<bool>,
    pub can_mirror: Option<bool>,
    pub can_rotate90: Option<bool>,
    pub can_rotate180: Option<bool>,
    pub can_rotate270: Option<bool>,
}

#[derive(Deserialize)]
pub struct TileDescriptionHelper(#[serde(with = "TileDesc")] TileDescription);
#[derive(Deserialize)]
pub struct EdgeDescriptionHelper(#[serde(with = "EdgeDesc")] EdgeDescription);

#[derive(Deserialize)]
pub struct NonStrictEdgesDesc {
    pub top: Option<EdgeDescriptionHelper>,
    pub right: Option<EdgeDescriptionHelper>,
    pub bottom: Option<EdgeDescriptionHelper>,
    pub left: Option<EdgeDescriptionHelper>,
}

#[derive(Deserialize)]
pub struct TemplateDesc {
    pub width: usize,
    pub height: usize,
    pub can_invert: bool,
    pub is_negative: bool,
    pub put_girders: bool,
    pub max_hedgehogs: u8,
    pub wrap: bool,
    pub edges: Option<NonStrictEdgesDesc>,
    pub tiles: Vec<TileDescriptionHelper>,
}

#[derive(Deserialize)]
pub struct TemplateCollectionDesc {
    pub templates: Vec<TemplateDesc>,
    pub template_types: HashMap<String, Vec<usize>>,
}

impl From<&TemplateDesc> for TemplateDescription {
    fn from(desc: &TemplateDesc) -> Self {
        let [top, right, bottom, left] = if let Some(edges) = &desc.edges {
            [
                edges.top.as_ref(),
                edges.right.as_ref(),
                edges.bottom.as_ref(),
                edges.left.as_ref(),
            ]
            .map(|e| e.map(|EdgeDescriptionHelper(e)| e.clone()))
        } else {
            [None, None, None, None]
        };

        Self {
            size: Size::new(desc.width, desc.height),
            tiles: desc
                .tiles
                .iter()
                .map(|TileDescriptionHelper(t)| t.clone())
                .collect(),
            wrap: desc.wrap,
            edges: NonStrictEdgesDescription {
                top,
                right,
                bottom,
                left,
            },
        }
    }
}