use crate::prelude::*; use bevy::{ asset::{AssetLoader, LoadContext, LoadedAsset}, reflect::{TypePath, TypeUuid}, utils::BoxedFuture, }; use serde::Deserialize; /// A Tweakfile is resource used to specify game customization like asset names, /// and non-user customizations made to the game during development. pub(crate) struct TweakPlugin; impl Plugin for TweakPlugin { fn build(&self, app: &mut App) { app.add_systems(OnEnter(GameState::Loading), load_tweakfile); app.add_asset::() .init_asset_loader::(); } } fn load_tweakfile(server: Res, mut commands: Commands) { let handle: Handle = server.load("martian.tweak.toml"); commands.insert_resource(GameTweakfile(handle)); } #[derive(Debug, Resource)] struct GameTweakfile(Handle); /// Tweakfile contains tweaks made to other parts of the game #[derive(Debug, Deserialize, TypeUuid, TypePath)] #[uuid = "e5768efe-edce-4267-bdf4-dd8f8ca613c7"] pub(crate) struct Tweakfile { #[serde(default)] pub audio: audio::AudioTweaks, #[serde(default)] pub display3d: display3d::tweaks::Display3dTweaks, } #[derive(Default)] pub struct TweakfileLoader; impl AssetLoader for TweakfileLoader { fn load<'a>( &'a self, bytes: &'a [u8], load_context: &'a mut LoadContext, ) -> BoxedFuture<'a, Result<(), bevy::asset::Error>> { Box::pin(async move { let s = std::str::from_utf8(bytes)?; let custom_asset = toml::from_str::(s)?; load_context.set_default_asset(LoadedAsset::new(custom_asset)); Ok(()) }) } fn extensions(&self) -> &[&str] { &["tweak.toml"] } }