1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
use std::collections::HashMap;

use raylib::{texture::Texture2D, RaylibHandle, RaylibThread};

use crate::{
    asset_manager::{load_json_structure, load_texture_from_internal_data},
    rendering::utilities::anim_texture::AnimatedTexture,
};

use super::world_object::{WorldObject, WorldObjectRef};

#[derive(Debug, thiserror::Error)]
pub enum WorldObjectPackageLoadError {
    #[error(transparent)]
    JsonError(#[from] crate::asset_manager::InternalJsonLoadError),
    #[error(transparent)]
    ResourceError(#[from] crate::asset_manager::ResourceLoadError),
}

/// A simply interface for the madness
#[derive(Debug)]
pub struct WorldObjectPackage {
    /// The object definitions
    pub object_definitions: HashMap<String, WorldObject>,
    /// The object references
    pub object_references: Vec<WorldObjectRef>,
    /// Bottom static textures
    pub bottom_static_textures: HashMap<String, Texture2D>,
    /// Top static textures
    pub top_static_textures: HashMap<String, Texture2D>,
    /// Bottom animated textures
    pub bottom_animated_textures: HashMap<String, AnimatedTexture>,
    /// Top animated textures
    pub top_animated_textures: HashMap<String, AnimatedTexture>,
}

impl WorldObjectPackage {
    pub fn load(
        raylib_handle: &mut RaylibHandle,
        thread: &RaylibThread,
        map_objects_file_path: &str,
    ) -> Result<Self, WorldObjectPackageLoadError> {
        // Attempt to load the object reference list
        let object_references: Vec<WorldObjectRef> = load_json_structure(map_objects_file_path)?;

        // We also need to load the object definitions
        let mut object_definitions = HashMap::new();
        let mut bottom_static_textures = HashMap::new();
        let mut top_static_textures = HashMap::new();
        let mut bottom_animated_textures = HashMap::new();
        let mut top_animated_textures = HashMap::new();
        for reference in &object_references {
            // If this is a new object, load it.
            let object_key = format!("{}:{}", reference.kind, reference.name);
            if !object_definitions.contains_key(object_key.as_str()) {
                // Construct the file path from the data we know about the reference
                let path = format!(
                    "assets/{}/{}/{}.json",
                    reference.kind, reference.name, reference.name
                );

                // Attempt to load the object definition
                let object_definition: WorldObject = load_json_structure(&path)?;

                // If this object has a static bottom texture, load it
                if object_definition.bottom_texture.animated.unwrap_or(false) {
                    panic!("Animated bottom textures are not supported yet")
                } else {
                    // Load the bottom texture and save it
                    bottom_static_textures.insert(
                        object_key.to_string(),
                        load_texture_from_internal_data(
                            raylib_handle,
                            thread,
                            &object_definition.bottom_texture.file_path,
                        )?,
                    );
                }

                // If there is a top texture, load it
                if let Some(top_texture) = &object_definition.top_texture {
                    if top_texture.animated.unwrap_or(false) {
                        panic!("Animated top textures are not supported yet")
                    } else {
                        // Load the top texture and save it
                        top_static_textures.insert(
                            object_key.to_string(),
                            load_texture_from_internal_data(
                                raylib_handle,
                                thread,
                                &top_texture.file_path,
                            )?,
                        );
                    }
                }

                // Store the object definition
                object_definitions.insert(object_key.to_string(), object_definition);
            }
        }

        Ok(Self {
            object_definitions,
            object_references,
            bottom_static_textures,
            top_static_textures,
            bottom_animated_textures,
            top_animated_textures,
        })
    }
}