From a83976b6cd5008d1d7f3995e247233124903232c Mon Sep 17 00:00:00 2001 From: ghostly_zsh Date: Sat, 4 Apr 2026 15:55:57 -0500 Subject: [PATCH] feat: drill checks if on planet, plus drill toggle button changed to match --- crates/unified/src/client/crafting/ui.rs | 37 ++++++++++++++++++++++-- crates/unified/src/ecs.rs | 4 +++ crates/unified/src/server/drill.rs | 33 +++++++++++++++++++-- crates/unified/src/server/part.rs | 1 + crates/unified/src/server/planets.rs | 10 +++++-- 5 files changed, 78 insertions(+), 7 deletions(-) diff --git a/crates/unified/src/client/crafting/ui.rs b/crates/unified/src/client/crafting/ui.rs index 620cb22a5b8310d96e33b100f3ce47e86a0ff327..d7171cf6fe13d9794bdbb8c23e4f052592e896f9 100644 --- a/crates/unified/src/client/crafting/ui.rs +++ b/crates/unified/src/client/crafting/ui.rs @@ -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_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, diff --git a/crates/unified/src/ecs.rs b/crates/unified/src/ecs.rs index 6ccfac24ab9c65458a18aca6af4e22404bc75aed..db42290e43c58b0b613c8a5d3685223d0d0de73d 100644 --- a/crates/unified/src/ecs.rs +++ b/crates/unified/src/ecs.rs @@ -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, } #[derive(Message, Serialize, Deserialize, Debug, MapEntities, Clone)] pub struct ToggleDrillEvent { diff --git a/crates/unified/src/server/drill.rs b/crates/unified/src/server/drill.rs index eb0a8008e48e2b2cef7c5fa30c02e22cdbafc926..83743b80ee0cadd27e2bb63972314ef5161cbc2d 100644 --- a/crates/unified/src/server/drill.rs +++ b/crates/unified/src/server/drill.rs @@ -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, + mut collision_end: MessageReader, + 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; + } +} diff --git a/crates/unified/src/server/part.rs b/crates/unified/src/server/part.rs index 0bbd44cb2adaf41570036815818473b1c2bba7f8..15906abf5168c733be3ccd3f6806d4859cd53f26 100644 --- a/crates/unified/src/server/part.rs +++ b/crates/unified/src/server/part.rs @@ -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 { diff --git a/crates/unified/src/server/planets.rs b/crates/unified/src/server/planets.rs index 3cc153a4d32770bcab8deb19f2e871e652e6a983..e510adc603e8c04080da1b1a47ffe92ecc915f02 100644 --- a/crates/unified/src/server/planets.rs +++ b/crates/unified/src/server/planets.rs @@ -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"); } }