flatland_presentation/
player_config.rs1use std::path::Path;
4
5use serde::Deserialize;
6
7use crate::SpriteModeMap;
8
9#[derive(Debug, Clone, Default, Deserialize)]
10pub struct PlayerPresentationDoc {
11 #[serde(default)]
12 pub player_presentation: PlayerPresentationConfig,
13}
14
15#[derive(Debug, Clone, Default, Deserialize)]
16pub struct PlayerPresentationConfig {
17 #[serde(default)]
18 pub tile_id: Option<String>,
19 #[serde(default)]
21 pub paperdoll_ref: Option<String>,
22 #[serde(default)]
23 pub sprite_modes: SpriteModeMap,
24}
25
26impl PlayerPresentationConfig {
27 pub fn empty() -> Self {
28 Self::default()
29 }
30}
31
32pub fn default_player_presentation_path() -> Option<std::path::PathBuf> {
33 if let Ok(p) = std::env::var("FLATLAND_PLAYER_PRESENTATION") {
34 let path = std::path::PathBuf::from(p);
35 if path.is_file() {
36 return Some(path);
37 }
38 }
39 if let Ok(sprites) = std::env::var("FLATLAND_SPRITES_DIR") {
40 let path = std::path::PathBuf::from(sprites).join("player-presentation.yaml");
41 if path.is_file() {
42 return Some(path);
43 }
44 }
45 if let Ok(home) = std::env::var("HOME") {
47 let current = std::path::PathBuf::from(home)
48 .join(".flatland3/assets/current/player-presentation.yaml");
49 if current.is_file() {
50 return Some(current);
51 }
52 }
53 let mut dir = std::env::current_dir().ok()?;
54 for _ in 0..8 {
55 let candidate = dir.join("assets/gfx/player-presentation.yaml");
56 if candidate.is_file() {
57 return Some(candidate);
58 }
59 if !dir.pop() {
60 break;
61 }
62 }
63 None
64}
65
66pub fn load_player_presentation(
67 path: impl AsRef<Path>,
68) -> anyhow::Result<PlayerPresentationConfig> {
69 let raw = std::fs::read_to_string(path.as_ref())?;
70 let doc: PlayerPresentationDoc = serde_yaml::from_str(&raw)?;
71 Ok(doc.player_presentation)
72}
73
74pub fn load_player_presentation_default() -> PlayerPresentationConfig {
75 default_player_presentation_path()
76 .and_then(|p| load_player_presentation(&p).ok())
77 .unwrap_or_default()
78}
79
80#[cfg(test)]
81mod tests {
82 use super::*;
83
84 #[test]
85 fn loads_repo_default() {
86 let path = default_player_presentation_path().expect("player-presentation.yaml");
87 let cfg = load_player_presentation(&path).expect("parse");
88 assert!(cfg.tile_id.is_some() || !cfg.sprite_modes.is_empty());
89 }
90}