156 lines
4.0 KiB
Rust
156 lines
4.0 KiB
Rust
use bevy::{
|
|
asset::{AssetLoader, LoadContext, LoadedAsset},
|
|
prelude::*,
|
|
reflect::TypeUuid,
|
|
utils::BoxedFuture,
|
|
};
|
|
use bevy_console::PrintConsoleLine;
|
|
use rhai::Engine;
|
|
use serde::Deserialize;
|
|
use std::{sync::Arc, sync::RwLock};
|
|
|
|
use super::modding_api::{register_mod, register_object, register_weapon};
|
|
|
|
#[derive(Debug, Deserialize, TypeUuid)]
|
|
#[uuid = "39cadc56-aa9c-4543-8640-a018b74b5051"]
|
|
pub struct Mod {
|
|
name: String,
|
|
enabled: bool,
|
|
}
|
|
#[derive(Debug, Deserialize, TypeUuid)]
|
|
#[uuid = "39cadc56-aa9c-4543-8640-a018b74b5050"]
|
|
pub struct LoadedMod {
|
|
name: String,
|
|
}
|
|
|
|
#[derive(Debug, Deserialize, TypeUuid)]
|
|
#[uuid = "39cadc56-aa9c-4543-8640-a018b74b5052"]
|
|
pub struct ModList {
|
|
pub value: i32,
|
|
pub vec: Vec<Mod>,
|
|
}
|
|
|
|
#[derive(Default)]
|
|
pub struct ModListLoader;
|
|
impl AssetLoader for ModListLoader {
|
|
fn load<'a>(
|
|
&'a self,
|
|
bytes: &'a [u8],
|
|
load_context: &'a mut LoadContext,
|
|
) -> BoxedFuture<'a, Result<(), anyhow::Error>> {
|
|
Box::pin(async move {
|
|
let custom_asset = ron::de::from_bytes::<ModList>(bytes)?;
|
|
load_context.set_default_asset(LoadedAsset::new(custom_asset));
|
|
|
|
Ok(())
|
|
})
|
|
}
|
|
|
|
fn extensions(&self) -> &[&str] {
|
|
&["list"]
|
|
}
|
|
}
|
|
|
|
#[derive(Default)]
|
|
pub struct ModLoader;
|
|
impl AssetLoader for ModLoader {
|
|
fn load<'a>(
|
|
&'a self,
|
|
bytes: &'a [u8],
|
|
load_context: &'a mut LoadContext,
|
|
) -> BoxedFuture<'a, Result<(), anyhow::Error>> {
|
|
Box::pin(async move {
|
|
let custom_asset = LoadedMod {
|
|
name: std::str::from_utf8(bytes).unwrap().to_string(),
|
|
};
|
|
load_context.set_default_asset(LoadedAsset::new(custom_asset));
|
|
Ok(())
|
|
})
|
|
}
|
|
|
|
fn extensions(&self) -> &[&str] {
|
|
&["rhai"]
|
|
}
|
|
}
|
|
|
|
#[derive(Default)]
|
|
pub struct State {
|
|
pub handle: Handle<ModList>,
|
|
pub mod_handle: Handle<LoadedMod>,
|
|
pub loaded: bool,
|
|
pub printed: bool,
|
|
}
|
|
|
|
pub struct ModManager;
|
|
impl Plugin for ModManager {
|
|
fn build(&self, app: &mut AppBuilder) {
|
|
app.init_resource::<State>()
|
|
.add_asset::<ModList>()
|
|
.init_asset_loader::<ModListLoader>()
|
|
.add_asset::<LoadedMod>()
|
|
.init_asset_loader::<ModLoader>()
|
|
.add_startup_system(engine_settings.system())
|
|
.add_system(build_mods.system());
|
|
}
|
|
}
|
|
|
|
pub struct AddonState {
|
|
rebuild_addons: bool,
|
|
}
|
|
|
|
fn build_mods(
|
|
mut engine: ResMut<Engine>,
|
|
mut addon_state: ResMut<AddonState>,
|
|
|
|
mut console_line: EventWriter<PrintConsoleLine>,
|
|
) {
|
|
if !addon_state.rebuild_addons {
|
|
return;
|
|
}
|
|
println!("Rebuilt addons");
|
|
|
|
let logbook = Arc::new(RwLock::new(Vec::<String>::new()));
|
|
|
|
// Redirect print/debug output to 'log'
|
|
let log = logbook.clone();
|
|
engine.on_print(move |s| log.write().unwrap().push(format!("{}", s)));
|
|
|
|
let log = logbook.clone();
|
|
engine.on_debug(move |s, src, pos| {
|
|
log.write().unwrap().push(format!(
|
|
"DEBUG of {} at {:?}: {}",
|
|
src.unwrap_or("unknown"),
|
|
pos,
|
|
s
|
|
))
|
|
});
|
|
|
|
let result = engine.run(include_str!("../../assets/mods/NewSwordMod.lad"));
|
|
match result {
|
|
Ok(_) => console_line.send(PrintConsoleLine::new("Mod Loaded".to_string())),
|
|
Err(error) => console_line.send(PrintConsoleLine::new(error.to_string())),
|
|
}
|
|
|
|
for entry in logbook.read().unwrap().iter() {
|
|
console_line.send(PrintConsoleLine::new(entry.to_string()));
|
|
}
|
|
|
|
addon_state.rebuild_addons = false;
|
|
}
|
|
|
|
fn engine_settings(mut commands: Commands) {
|
|
let mut engine = Engine::new();
|
|
|
|
// Configure the engine
|
|
engine.set_max_array_size(50).set_max_operations(500);
|
|
|
|
engine.register_fn("register_mod", register_mod);
|
|
engine.register_fn("register_weapon", register_weapon);
|
|
engine.register_fn("register_object", register_object);
|
|
|
|
commands.insert_resource(engine);
|
|
commands.insert_resource(AddonState {
|
|
rebuild_addons: true,
|
|
});
|
|
}
|