use crate::envelope::Campaign;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Placement {
Prefabs,
SitePlan,
NoMap,
}
impl Placement {
#[must_use]
pub fn of(c: &Campaign) -> Self {
if c.site_plan.is_some() {
Self::SitePlan
} else if c.world.content.areas.is_empty() {
Self::NoMap
} else {
Self::Prefabs
}
}
#[must_use]
pub fn area_remedy(self) -> &'static str {
match self {
Self::Prefabs => "declare it in stage-1 `world.areas` or correct the reference",
Self::SitePlan => {
"this campaign's map is its site plan, so it has exactly one area, \
`area/site`. Point the reference at that, and do NOT declare the id in \
`world.areas`: a campaign carrying a site plan declares an empty `areas` list \
(`DW0839`), and an entry with no prefab bound to it is refused again \
(`DW0160`)"
}
Self::NoMap => {
"this campaign declares no area at all: `world.areas` is empty and there is \
no `site-plan.json`, so it has no map for a reference to land in. Give it one \
placement authority, and only one (`DW0839`): either declare the area in \
stage-1 `world.areas` with a `prefab` or `prefab_pool` bound to it, or write \
the map pipeline (`geometry-brief.json`, then `layout-graph.json`, then \
`site-plan.json`) and name the campaign's one area `area/site`"
}
}
}
#[must_use]
pub fn anchor_remedy(self, prefab: &str) -> &str {
match self {
Self::Prefabs => prefab,
Self::SitePlan => {
"this campaign's map is its site plan, so there is no prefab metadata to \
read. Its anchor names are the ones the derivation places: `anchor/node-<place>` \
for each place the layout graph declares, `anchor/seam-<edge>` over each barred \
connection, `anchor/unlock-<edge>` on the far side of a one-sided one, and \
`spawn` for the entry — plus every `stations[]` name its nodes declare. Write \
one of those, or declare this name as a station on the node it belongs to, and \
do NOT add an `areas[]` entry to get a prefab: a campaign carrying a site plan \
declares an empty `areas` list (`DW0839`)"
}
Self::NoMap => {
"this campaign has no map yet: `world.areas` is empty and there is no \
`site-plan.json`, so nothing places an anchor and no name can resolve. Give it \
one placement authority, and only one (`DW0839`): either declare an area in \
stage-1 `world.areas` with a `prefab` bound to it and write an anchor that \
prefab's metadata exposes, or write the map pipeline (`geometry-brief.json`, \
then `layout-graph.json`, then `site-plan.json`) and write one of the names its \
derivation places (`anchor/node-<place>`, `anchor/seam-<edge>`, \
`anchor/unlock-<edge>`, `spawn`, or a `stations[]` name a node declares)"
}
}
}
#[must_use]
pub fn lighting_field(self) -> &'static str {
match self {
Self::Prefabs | Self::NoMap => "`world.areas[].lighting`",
Self::SitePlan => "the site plan's `lighting`",
}
}
#[must_use]
pub fn has_area_mitigation(self) -> bool {
!matches!(self, Self::SitePlan)
}
}
#[must_use]
pub fn anchor_vocabulary_unknowable(c: &Campaign) -> bool {
matches!(Placement::of(c), Placement::SitePlan) && c.layout_graph.is_none()
}