~starkingdoms/starkingdoms

ref: 0463a5645b803f979f0efb597469ed3ea3de00b3 starkingdoms/crates/unified/src/server/drill.rs -rw-r--r-- 3.6 KiB
0463a564ghostly_zsh feat: drill drills (in theory) 15 hours ago
                                                                                
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
use crate::{attachment::{PartInShip, Parts}, config::planet::Planet, ecs::{Drill, Part, PlanetSensor, SingleStorage, ToggleDrillEvent}, prelude::*};

pub fn drill_plugin(app: &mut App) {
    app.add_systems(Update, (toggle_drill, drill_on_planet, do_drilling));
}

fn toggle_drill(
    mut toggle_drill_reader: MessageReader<FromClient<ToggleDrillEvent>>,
    mut drills: Query<&mut Drill>,
) {
    for toggle_drill_event in toggle_drill_reader.read() {
        // this getting of the drill also serves to check whether or not
        // the entity is a drill
        let Ok(mut drill) = drills.get_mut(toggle_drill_event.drill_entity) else { return };
        drill.drilling = !drill.drilling;
    }
}

fn drill_on_planet(
    mut collision_start: MessageReader<CollisionStart>,
    mut collision_end: MessageReader<CollisionEnd>,
    planet_sensors: Query<&PlanetSensor>,
    mut drills: Query<&mut Drill>,
) {
    for event in collision_start.read() {
        let (planet_sensor, mut drill) = if let (Ok(planet_sensor), Ok(drill)) = (planet_sensors.get(event.collider1), drills.get_mut(event.collider2)) {
            (planet_sensor, drill)
        } else if let (Ok(drill), Ok(planet_sensor)) = (drills.get_mut(event.collider1), planet_sensors.get(event.collider2)) {
            (planet_sensor, drill)
        } else {
            continue
        };
        drill.on_planet = Some(planet_sensor.0.clone());
    }
    for event in collision_end.read() {
        let (_, mut drill) = if let (Ok(planet_sensor), Ok(drill)) = (planet_sensors.get(event.collider1), drills.get_mut(event.collider2)) {
            (planet_sensor, drill)
        } else if let (Ok(drill), Ok(planet_sensor)) = (drills.get_mut(event.collider1), planet_sensors.get(event.collider2)) {
            (planet_sensor, drill)
        } else {
            continue
        };
        drill.drilling = false;
        drill.on_planet = None;
    }
}

fn do_drilling(
    drills: Query<(&Drill, &PartInShip)>,
    parts_query: Query<&Parts>,
    mut storage_part_query: Query<&mut SingleStorage, With<Part>>,
    planet_query: Query<&Planet>,
    time: Res<Time>,
) {
    for (drill, part_in_ship) in drills {
        if !drill.drilling || drill.on_planet.is_none() {
            continue
        }
        let planet_name = drill.on_planet.clone().unwrap();
        let mut planet = None;
        for q_planet in planet_query {
            if q_planet.name == planet_name {
                planet = Some(q_planet);
                break;
            }
        }
        // if the planet name doesn't match a planet, we have a big problem
        let planet = planet.expect("In do_drilling, a planet name didn't match a planet");
        let Some(ref planet_resource) = planet.planet_resource else {
            continue
        };
        let player = part_in_ship.0;
        let Ok(parts_list) = parts_query.get(player) else {
            error!("In do_drilling, there was a player without a Parts");
            continue
        };
        for part_entity in parts_list.iter() {
            let Ok(mut storage) = storage_part_query.get_mut(part_entity) else {
                continue
            };
            if storage.resource_name.is_empty() {
                storage.resource_name = planet_resource.name.clone();
            }
            // now that the name isn't empty, this will trigger
            if storage.resource_name == planet_resource.name {
                storage.stored += planet_resource.mining_speed * drill.resource_multiplier * time.delta_secs();
                storage.stored = storage.stored.min(storage.capacity);
            }
        }
    }
}