~starkingdoms/starkingdoms

ref: 44af5cad10ff206a7aa471b48821d764afefcba0 starkingdoms/crates/unified/src/server/drill.rs -rw-r--r-- 5.8 KiB
44af5cadghostly_zsh feat: drill does drill, and there's a resource display 12 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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
use crate::{attachment::{PartInShip, Parts}, config::planet::Planet, ecs::{Drill, Part, PlanetSensor, Player, 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)>,
    hearty_drills: Query<(Entity, &Drill), With<Player>>,
    parts_query: Query<&Parts>,
    mut storage_part_query: Query<&mut SingleStorage, With<Part>>,
    planet_query: Query<&Planet>,
    time: Res<Time>,
) {
    for (entity, drill) in hearty_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
        };
        'adding_resources: {
            if let Ok(parts_list) = parts_query.get(entity) {
                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);
                        break 'adding_resources;
                    }
                }
            }
            let Ok(mut storage) = storage_part_query.get_mut(entity) else {
                break 'adding_resources;
            };
            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);
                break 'adding_resources;
            }
        };
    }
    for (drill, part_in_ship) in drills {
        debug!("drill");
        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);
            }
        }
    }
}