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

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

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

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
32
33
34
35

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

    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));

47
48
49
        schedule_builder
            .add_thread_local(collect_bottledrops_system())
            .add_thread_local(update_bottle_shift_system(self.hours));
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
    }
}

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)]
70
#[write_component(components::Sprite)]
71
pub fn collect_bottledrops(
72
    world: &mut legion::world::SubWorld,
73
74
75
76
77
78
79
80
81
82
83
    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();

84
    let mut bottledrops = <(&components::Matebottledrop, &mut components::Sprite)>::query();
85
86
87
88
89
90
91
92
93
94
    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();
95
96
97
        if let Ok((_, sprite)) = bottledrops.get_mut(world, entity) {
            *sprite = components::Sprite::new(sprites::Sprite::BottleDropPointEmpty);
            cmd.remove_component::<components::Matebottledrop>(entity);
98
99
100
            bottle_angel_state.collected_drops += 1;
        }
    }
Rahix's avatar
Rahix committed
101
}
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121

#[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();
    }
}