Galactica/crates/content/src/part/faction.rs

99 lines
2.3 KiB
Rust
Raw Normal View History

2023-12-30 16:57:03 -08:00
use anyhow::Result;
use serde::Deserialize;
use std::collections::HashMap;
use crate::{handle::FactionHandle, Content};
pub(crate) mod syntax {
use std::collections::HashMap;
use serde::Deserialize;
// Raw serde syntax structs.
// These are never seen by code outside this crate.
#[derive(Debug, Deserialize)]
pub struct Faction {
pub display_name: String,
pub relationship: HashMap<String, super::Relationship>,
}
}
#[derive(Debug, Deserialize, Clone, Copy)]
pub enum Relationship {
#[serde(rename = "hostile")]
Hostile,
#[serde(rename = "neutral")]
Neutral,
#[serde(rename = "enemy")]
Enemy,
}
/// Represents a game faction
#[derive(Debug, Clone)]
pub struct Faction {
/// The name of this faction
pub name: String,
/// This faction's handle
pub handle: FactionHandle,
pub relationships: HashMap<FactionHandle, Relationship>,
}
impl crate::Build for Faction {
type InputSyntax = HashMap<String, syntax::Faction>;
fn build(factions: Self::InputSyntax, ct: &mut Content) -> Result<()> {
// Keeps track of position in faction array.
// This lets us build FactionHandles before finishing all factions.
let faction_names: Vec<String> = factions.keys().map(|x| x.to_owned()).collect();
for f_idx in 0..faction_names.len() {
let faction_name = &faction_names[f_idx];
let faction = &factions[faction_name];
// Handle for this faction
let h = FactionHandle { index: f_idx };
// Compute relationships
let mut relationships = HashMap::new();
for i in 0..faction_names.len() {
let f_other = &faction_names[i];
let h_other = FactionHandle { index: i };
if let Some(r) = faction.relationship.get(f_other) {
relationships.insert(h_other, *r);
} else {
// Default relationship, if not specified
// Look at reverse direction...
let other = factions[f_other].relationship.get(faction_name);
relationships.insert(
h_other,
// ... and pick a relationship based on that.
match other {
Some(Relationship::Hostile) => Relationship::Hostile {},
_ => Relationship::Neutral {},
},
);
}
}
let relationships = faction
.relationship
.iter()
.map(|x| (h, x.1.clone()))
.collect();
ct.factions.push(Self {
name: faction_name.to_owned(),
handle: h,
relationships,
});
}
return Ok(());
}
}