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