180 lines
5.2 KiB
Rust
180 lines
5.2 KiB
Rust
use std::collections::HashMap;
|
|
|
|
use anyhow::Result;
|
|
use assetpath::AssetPath;
|
|
use engine::prelude::*;
|
|
|
|
use crate::{animation_info::AnimationInfo, hitbox::HitBox};
|
|
|
|
use super::{entity_info::EntityInfo, entity_tags::EntityTags, entityparser::EntityParser};
|
|
|
|
pub struct EntityManager {
|
|
entity_directory: AssetPath,
|
|
resource_base_path: String,
|
|
|
|
entity_file_list: Vec<String>,
|
|
entity_file_map: HashMap<String, AssetPath>,
|
|
}
|
|
|
|
impl EntityManager {
|
|
pub fn new(entity_directory: impl Into<AssetPath>) -> Result<Self> {
|
|
let entity_directory = entity_directory.into();
|
|
|
|
let resource_base_path = entity_directory.prefix().unwrap().to_string();
|
|
|
|
let mut me = Self {
|
|
entity_directory,
|
|
resource_base_path,
|
|
|
|
entity_file_list: Vec::new(),
|
|
entity_file_map: HashMap::new(),
|
|
};
|
|
|
|
me.update_files()?;
|
|
|
|
Ok(me)
|
|
}
|
|
|
|
/// Updates the lists of all '.gltf' and '.ent' files
|
|
pub fn update_files(&mut self) -> Result<()> {
|
|
let (entity_file_list, entity_file_map) =
|
|
search_file_names(&self.entity_directory, ".ent")?;
|
|
|
|
self.entity_file_list = entity_file_list;
|
|
self.entity_file_map = entity_file_map;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Returns all entity files
|
|
pub fn entity_files(&self) -> &Vec<String> {
|
|
&self.entity_file_list
|
|
}
|
|
|
|
/// Returns all found entity files with expected tags
|
|
pub fn entity_files_with_tags(&self, tags: &[EntityTags]) -> Result<Vec<EntityInfo>> {
|
|
let mut entity_files = Vec::new();
|
|
|
|
if tags.is_empty() {
|
|
return Ok(entity_files);
|
|
}
|
|
|
|
for entity_file in self.entity_file_list.iter() {
|
|
// load entity file
|
|
let file = self.load_entity_file(entity_file);
|
|
let entity_parser = EntityParser::parse(file)?;
|
|
|
|
// check for tags
|
|
for tag in tags.iter() {
|
|
if entity_parser.tags.contains(tag) {
|
|
entity_files.push(EntityInfo {
|
|
file_name: entity_file.clone(),
|
|
hitbox_radius: if entity_parser.enable_hitbox {
|
|
Some(entity_parser.hitbox_radius)
|
|
} else {
|
|
None
|
|
},
|
|
tags: entity_parser.tags,
|
|
});
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
Ok(entity_files)
|
|
}
|
|
|
|
pub fn entity_info(&self, entity_file: &str) -> Result<EntityInfo> {
|
|
let file = self.load_entity_file(entity_file);
|
|
let entity_parser = EntityParser::parse(file)?;
|
|
|
|
Ok(EntityInfo {
|
|
file_name: entity_file.to_string(),
|
|
hitbox_radius: if entity_parser.enable_hitbox {
|
|
Some(entity_parser.hitbox_radius)
|
|
} else {
|
|
None
|
|
},
|
|
tags: entity_parser.tags,
|
|
})
|
|
}
|
|
|
|
pub fn get_tags(&self, entity_file: &str) -> Result<Vec<EntityTags>> {
|
|
// load entity file
|
|
let file = self.load_entity_file(entity_file);
|
|
let entity_parser = EntityParser::parse(file)?;
|
|
|
|
Ok(entity_parser.tags)
|
|
}
|
|
|
|
fn load_entity_file(&self, entity_file: &str) -> &AssetPath {
|
|
match self.entity_file_map.get(entity_file) {
|
|
Some(file) => file,
|
|
None => {
|
|
// return Err(EngineError::FileNotFound(
|
|
// "Entity".to_string(),
|
|
// entity_file.to_string(),
|
|
// ))
|
|
|
|
todo!();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
impl AssetLoader for EntityManager {
|
|
/// Loads an entity file and creates an Entity
|
|
fn load_entity(
|
|
&mut self,
|
|
assets: &mut AssetHandler<'_>,
|
|
entity_file: &str,
|
|
) -> Result<EntityObject> {
|
|
// load entity file
|
|
let file = self.load_entity_file(entity_file);
|
|
|
|
#[allow(unused_mut)]
|
|
let mut entity_parser = EntityParser::parse(file)?;
|
|
|
|
// load asset
|
|
|
|
let mut entity_object = assets.create_entity(&entity_parser.gltf_file_name)?;
|
|
|
|
#[cfg(debug_assertions)]
|
|
{
|
|
entity_object.debug_name = Some(entity_file.to_string());
|
|
}
|
|
|
|
if entity_parser.enable_hitbox {
|
|
entity_object.insert_component(HitBox::new(
|
|
entity_parser.hitbox_radius,
|
|
entity_parser.hitbox_height,
|
|
));
|
|
}
|
|
|
|
entity_parser
|
|
.animation_map
|
|
.retain(|_animation_type, indices| !indices.is_empty());
|
|
|
|
if !entity_parser.animation_map.is_empty() {
|
|
entity_object.insert_component(AnimationInfo::new(
|
|
entity_parser.animations,
|
|
entity_parser.animation_map,
|
|
));
|
|
}
|
|
|
|
if !entity_parser.sound_map.is_empty() {
|
|
for audio_path in entity_parser.sound_map.values_mut() {
|
|
if !audio_path.is_empty() {
|
|
audio_path.set_prefix(&self.resource_base_path);
|
|
}
|
|
}
|
|
|
|
entity_object.insert_component(Audio::new(
|
|
assets.world().resources.get_mut::<Context>(),
|
|
entity_parser.sound_map,
|
|
)?);
|
|
}
|
|
|
|
Ok(entity_object)
|
|
}
|
|
}
|