station/crates/game_core/src/lib.rs

70 lines
2.0 KiB
Rust
Raw Normal View History

//! Shared game code: data definitions, components, map loading and network protocol.
pub mod components;
pub mod data;
pub mod grid;
pub mod map;
pub mod protocol;
use std::path::{Path, PathBuf};
use bevy::prelude::*;
pub use data::GameData;
/// Map loaded when no other map is configured, relative to the assets directory.
pub const DEFAULT_MAP: &str = "maps/station.tmx";
pub const DEFAULT_PORT: u16 = 5000;
/// Bump when the protocol changes in incompatible ways.
pub const PROTOCOL_ID: u64 = 1;
/// Locates the `assets` directory.
///
/// Uses `GAME_ASSETS_DIR` if set, otherwise searches upwards from the working
/// directory and the executable for a directory named `assets` containing `data/`.
pub fn assets_dir() -> PathBuf {
if let Some(dir) = std::env::var_os("GAME_ASSETS_DIR") {
return dir.into();
}
let starts = [
std::env::current_dir().ok(),
std::env::current_exe().ok(),
Some(PathBuf::from(env!("CARGO_MANIFEST_DIR"))),
];
starts
.into_iter()
.flatten()
.find_map(|start| {
start
.ancestors()
.map(|p| p.join("assets"))
.find(|p| p.join("data").is_dir())
})
.unwrap_or_else(|| PathBuf::from("assets"))
}
/// Absolute path for an asset-relative path.
pub fn asset_path(relative: impl AsRef<Path>) -> PathBuf {
assets_dir().join(relative)
}
/// Loads [`GameData`] and registers the network protocol.
pub struct CorePlugin;
impl Plugin for CorePlugin {
fn build(&self, app: &mut App) {
let dir = assets_dir().join("data");
let data = GameData::load_dir(&dir).unwrap_or_else(|e| panic!("{e}"));
info!(
"loaded {} items, {} recipes, {} buildings, {} skills from `{}`",
data.items.len(),
data.recipes.len(),
data.buildings.len(),
data.skills.len(),
dir.display()
);
app.insert_resource(data)
.add_plugins(protocol::ProtocolPlugin);
}
}