use bevy::prelude::*;
use std::fs;
use super::components::{DiscoveredMods, LoadedModScenes, ModdingConfig};
pub fn discover_mods(config: Res<ModdingConfig>, mut discovered: ResMut<DiscoveredMods>) {
let mods_dir = &config.mods_directory;
discovered.clear();
if !mods_dir.exists() {
info!("mods/ directory not found, skipping mod discovery");
return;
}
let entries = match fs::read_dir(mods_dir) {
Ok(entries) => entries,
Err(e) => {
warn!("Failed to read mods/ directory: {}", e);
return;
}
};
for entry in entries.flatten() {
let path = entry.path();
if path.is_file() {
if let Some(ext) = path.extension() {
if ext == "ron" {
info!("Discovered mod file: {:?}", path);
discovered.add_ron_file(path);
}
}
}
}
info!(
"Mod discovery complete: {} files found",
discovered.ron_files.len()
);
}
pub fn load_mod_scenes(
discovered: Res<DiscoveredMods>,
mut loaded: ResMut<LoadedModScenes>,
asset_server: Option<Res<AssetServer>>,
) {
let Some(asset_server) = asset_server else {
return;
};
for path in &discovered.ron_files {
if loaded.scenes.iter().any(|(p, _)| p == path) {
continue;
}
let handle: Handle<DynamicScene> = asset_server.load(path.clone());
info!("Loading mod scene: {:?}", path);
loaded.add_scene(path.clone(), handle);
}
}
pub fn apply_mod_scenes(
mut loaded: ResMut<LoadedModScenes>,
scenes: Option<Res<Assets<DynamicScene>>>,
mut commands: Commands,
) {
let Some(scenes) = scenes else {
return;
};
let mut to_apply = Vec::new();
for (path, handle) in &loaded.scenes {
if loaded.is_applied(path) {
continue;
}
if scenes.get(handle).is_some() {
info!("Applying mod scene: {:?}", path);
commands.spawn(DynamicSceneRoot(handle.clone()));
to_apply.push(path.clone());
}
}
for path in to_apply {
loaded.mark_applied(&path);
}
}