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
use crate::gui::GuiTheme;
use crate::prelude::*;

#[derive(Debug, Clone)]
pub struct GameParams {
    pub name: String,
    pub version: String,
    pub data_path: String,
    pub modules_path: String,
    pub characters_path: String,
    pub assets_path: String,
    pub new_character_build_points: u32,
    pub skip_character_creation: bool,
}

impl Default for GameParams {
    fn default() -> Self {
        GameParams {
            name: "Unnamed Game".to_string(),
            version: "0.1.0".to_string(),
            data_path: "data".to_string(),
            modules_path: "modules".to_string(),
            characters_path: "characters".to_string(),
            assets_path: "assets".to_string(),
            new_character_build_points: 6,
            skip_character_creation: false,
        }
    }
}

#[cfg(not(any(target_family = "wasm", target_os = "android")))]
async fn load_resources(game_params: &GameParams) {
    let coroutine = {
        let game_params = game_params.clone();

        start_coroutine(async move {
            match Resources::new(&game_params).await {
                Err(err) => panic!("Resources: {}", err),
                Ok(mut resources) => {
                    load_modules(&game_params, &mut resources).await.unwrap();

                    storage::store(resources);
                }
            }
        })
    };

    while !coroutine.is_done() {
        clear_background(color::BLACK);
        draw_text(
            "Loading game resources...",
            vec2(get_screen_width() / 2.0, get_screen_height() / 2.0),
            HorizontalAlignment::Center,
            VerticalAlignment::Center,
            TextParams {
                ..Default::default()
            },
        );

        end_frame().await;
    }
}

#[cfg(target_family = "wasm")]
async fn load_resources(game_params: &GameParams) {
    let mut state = ResourceLoadingState::None;

    let mut resources = Resources::new(&game_params.data_path).await.unwrap();
    load_modules(&mut state, &game_params, &mut resources)
        .await
        .unwrap();

    storage::store(resources);
}

// This will perform all the initialization necessary prior to starting a game loop
pub async fn init(params: GameParams) -> Result<()> {
    fs::create_dir_all(&params.characters_path)?;
    storage::store(params.clone());

    load_resources(&params).await;

    let gui_theme = GuiTheme::load().await?;
    let gui_skins = GuiSkins::new(gui_theme);
    storage::store(gui_skins);

    let player_id = generate_id();
    let local_player = LocalPlayer::new(&player_id);
    storage::store(local_player);

    dispatch_event(Event::OpenMainMenu);

    Ok(())
}

pub fn begin_frame() {
    clear_background(color::BLACK);
    draw_gui();
}

pub async fn end_frame() {
    next_frame().await;
}