M crates/unified/src/client/crafting/ui.rs => crates/unified/src/client/crafting/ui.rs +34 -3
@@ 3,7 3,7 @@ use bevy::{input_focus::{AutoFocus, InputFocus}, ui::RelativeCursorPosition};
use crate::{attachment::PartInShip, client::colors, ecs::{CanCraft, CraftingUi, Drill, MainCamera, Me, ToggleDrillEvent}, prelude::*};
pub fn crafting_ui_plugin(app: &mut App) {
- app.add_systems(Update, (close_button, drill_button));
+ app.add_systems(Update, (close_button, drill_button, drill_state_change));
}
#[derive(Component)]
@@ 81,7 81,7 @@ fn setup_ui(
));
});
// only add the drill button if the part is a drill
- if drills.get(parent_part).is_ok() {
+ if let Ok(drill) = drills.get(parent_part) {
parent.spawn((
Node {
..Default::default()
@@ 96,7 96,11 @@ fn setup_ui(
Node {
..Default::default()
},
- Text::new("Start Drill"),
+ TextFont {
+ font_size: 10.0,
+ ..Default::default()
+ },
+ Text::new(get_drill_text(drill)),
));
});
}
@@ 134,6 138,8 @@ fn drill_button(
previous_interaction.0 = *interaction;
return
};
+ // don't allow drill toggling while not on a planet
+ if drill.on_planet.is_none() { return }
// the text is flipped because drill.drilling is an old value,
// which was now toggled
if drill.drilling {
@@ 151,6 157,31 @@ fn drill_button(
previous_interaction.0 = *interaction;
}
}
+fn drill_state_change(
+ drills: Query<&Drill, Changed<Drill>>,
+ drill_buttons: Query<(&DrillButton, &Children)>,
+ mut text_query: Query<&mut Text>,
+) {
+ for (drill_button, children) in &drill_buttons {
+ let Ok(drill) = drills.get(drill_button.0) else {
+ continue
+ };
+
+ let mut text = text_query.get_mut(children[0]).unwrap();
+ **text = get_drill_text(drill);
+ }
+}
+fn get_drill_text(drill: &Drill) -> String {
+ if drill.on_planet.is_some() {
+ if drill.drilling {
+ "Stop Drill".to_string()
+ } else {
+ "Start Drill".to_string()
+ }
+ } else {
+ "Drill not on planet".to_string()
+ }
+}
fn close_button(
mut commands: Commands,
M crates/unified/src/ecs.rs => crates/unified/src/ecs.rs +4 -0
@@ 42,6 42,9 @@ pub struct FuelText;
#[derive(Component)]
pub struct PowerText;
+#[derive(Component)]
+pub struct PlanetSensor(pub String); // corresponding planet name
+
#[derive(Component, Serialize, Deserialize, Debug)]
#[require(
RigidBody::Dynamic,
@@ 135,6 138,7 @@ pub struct Radiator {
pub struct Drill {
pub drilling: bool,
pub resource_multiplier: f32,
+ pub on_planet: Option<String>,
}
#[derive(Message, Serialize, Deserialize, Debug, MapEntities, Clone)]
pub struct ToggleDrillEvent {
M crates/unified/src/server/drill.rs => crates/unified/src/server/drill.rs +31 -2
@@ 1,7 1,7 @@
-use crate::{ecs::{Drill, ToggleDrillEvent}, prelude::*};
+use crate::{ecs::{Drill, PlanetSensor, ToggleDrillEvent}, prelude::*};
pub fn drill_plugin(app: &mut App) {
- app.add_systems(Update, toggle_drill);
+ app.add_systems(Update, (toggle_drill, drill_on_planet));
}
fn toggle_drill(
@@ 15,3 15,32 @@ fn toggle_drill(
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;
+ }
+}
M crates/unified/src/server/part.rs => crates/unified/src/server/part.rs +1 -0
@@ 160,6 160,7 @@ fn drill_bundle(entity: &mut EntityCommands, config: &DrillConfig) {
entity.insert(Drill {
drilling: false,
resource_multiplier: config.resource_multiplier,
+ on_planet: None,
});
}
fn spawn_joint_bundle(joint: &JointConfig, part: &PartConfig, parent: &Entity) -> impl Bundle {
M crates/unified/src/server/planets.rs => crates/unified/src/server/planets.rs +8 -2
@@ 1,4 1,4 @@
-use crate::config::planet::{Planet, PlanetBundle, PlanetConfigCollection};
+use crate::{config::planet::{Planet, PlanetBundle, PlanetConfigCollection}, ecs::PlanetSensor};
use bevy::asset::Handle;
use crate::prelude::*;
use bevy_replicon::prelude::Replicated;
@@ 54,7 54,13 @@ pub fn update_planets(
collider: Collider::circle(planet.radius),
mass: Mass(planet.mass)
})
- .insert(Replicated);
+ .insert(Replicated)
+ .with_child((
+ Collider::circle(planet.radius+2.0),
+ Sensor,
+ PlanetSensor(planet.name.clone()),
+ CollisionEventsEnabled,
+ ));
trace!(?planet, "new planet spawned");
}
}