bottle_angel.rs 3.29 KB
Newer Older
1
2
3
4
5
6
use crate::colliders;
use crate::components;
use crate::entities;
use crate::resources;
use crate::svg_loader;

Rahix's avatar
Rahix committed
7
8
pub struct BottleAngelShift {
    hours: usize,
Rahix's avatar
Rahix committed
9
    level: String,
Rahix's avatar
Rahix committed
10
11
12
13
14
15
}

impl BottleAngelShift {
    pub fn generate(rng: &mut impl rand::Rng) -> BottleAngelShift {
        BottleAngelShift {
            hours: rng.gen_range(1, 3),
Rahix's avatar
Rahix committed
16
17
            // TODO: When there are more levels, randomly select one here.
            level: "assembly-hall-1.svg".to_owned(),
Rahix's avatar
Rahix committed
18
19
20
21
22
23
24
25
26
27
28
29
30
        }
    }
}

impl super::AngelShiftImpl for BottleAngelShift {
    fn metadata(&self) -> super::ShiftMetadata {
        super::ShiftMetadata {
            title: "Bottle Angel".to_owned(),
            description: "Collect bottles from all bottle drop points in the designated area."
                .to_owned(),
            hours: self.hours,
        }
    }
Rahix's avatar
Rahix committed
31
32
33
34

    fn level_name(&self) -> &str {
        &self.level
    }
35
36
37
38
39
40
41
42
43
44
45

    fn init_gameworld(
        &self,
        world: &mut legion::World,
        resources: &mut legion::Resources,
        schedule_builder: &mut legion::systems::Builder,
        level: &svg_loader::SvgLevel,
    ) {
        entities::create_drop_points(world, level);
        resources.insert(BottleAngelState::new(4));

46
47
48
        schedule_builder
            .add_thread_local(collect_bottledrops_system())
            .add_thread_local(update_bottle_shift_system(self.hours));
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
    }
}

pub struct BottleAngelState {
    collected_drops: usize,
    drops_in_map: usize,
}

impl BottleAngelState {
    fn new(drops_in_map: usize) -> BottleAngelState {
        BottleAngelState {
            collected_drops: 0,
            drops_in_map,
        }
    }
}

#[legion::system]
#[read_component(colliders::Collider)]
#[read_component(components::Matebottledrop)]
pub fn collect_bottledrops(
    world: &legion::world::SubWorld,
    cmd: &mut legion::systems::CommandBuffer,
    #[resource] player: &resources::Player,
    #[resource] collision_world: &colliders::CollisionWorld,
    #[resource] bottle_angel_state: &mut BottleAngelState,
) {
    use legion::IntoQuery;

    let collider = <&colliders::Collider>::query()
        .get(world, player.0)
        .unwrap();

    let mut bottledrops = <&components::Matebottledrop>::query();
    for pair in collision_world
        .world
        .proximities_with(collider.handle.unwrap(), false)
        .unwrap()
    {
        if pair.3 != ncollide2d::query::Proximity::Intersecting {
            continue;
        }

        let entity = *collision_world.world.objects.get(pair.1).unwrap().data();
        if bottledrops.get(world, entity).is_ok() {
            cmd.remove(entity);
            bottle_angel_state.collected_drops += 1;
        }
    }
Rahix's avatar
Rahix committed
98
}
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118

#[legion::system]
#[write_component(components::Player)]
pub fn update_bottle_shift(
    #[state] hours_to_award: &usize,
    world: &mut legion::world::SubWorld,
    #[resource] player: &mut resources::Player,
    #[resource] bottle_angel_state: &mut BottleAngelState,
    #[resource] game_manager: &mut resources::GameManager,
) {
    use legion::IntoQuery;

    if bottle_angel_state.collected_drops >= bottle_angel_state.drops_in_map {
        let player = <&mut components::Player>::query()
            .get_mut(world, player.0)
            .unwrap();
        player.collected_hours += *hours_to_award as u32;
        game_manager.request_return_to_heaven();
    }
}