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
use std::{thread, time};

use specs::{prelude::*, World};

use crate::{floor::Floor, Player};

pub mod components;
pub mod systems;

use components::{UnitComponent, UnitType};
use systems::{PlayerSystem, SludgeSystem, UiSystem};

pub fn start(floor: Floor, player: impl Player + Send + Sync + 'static) -> Result<(), String> {
    let mut world = World::new();

    let player_system = PlayerSystem::new(player);
    let ui_system = UiSystem::new(floor);
    let mut dispatcher = DispatcherBuilder::new()
        .with(player_system, "player", &[])
        .with(SludgeSystem, "sludge", &["player"])
        .with(ui_system, "ui", &["player", "sludge"])
        .build();

    dispatcher.setup(&mut world);

    UnitComponent::create_warrior(&mut world, floor.warrior);

    if let Some(sludge) = floor.sludge {
        UnitComponent::create_sludge(&mut world, sludge);
    }

    floor.draw();

    let mut step = 0;
    loop {
        step += 1;

        if step > 20 {
            return Err("You seem to have gotten lost...".to_owned());
        }

        {
            let units = world.read_storage::<UnitComponent>();
            for entity in world.entities().join() {
                match units.get(entity) {
                    Some(warrior) if warrior.unit_type == UnitType::Warrior => {
                        let (current, _) = warrior.hp;
                        if current == 0 {
                            return Err("You died!".to_owned());
                        }
                        if warrior.position == floor.stairs {
                            return Ok(());
                        }
                    }
                    _ => {}
                }
            }
        }

        dispatcher.dispatch(&world);
        world.maintain();

        thread::sleep(time::Duration::from_millis(500));
    }
}