~starkingdoms/starkingdoms

5ed17b2ec1a3f95349833a08850fc8d7ef5d8d4f — ghostly_zsh an hour ago 204a71c master
feat: toggle drill button
M crates/unified/assets/config/parts/hearty.part.toml => crates/unified/assets/config/parts/hearty.part.toml +3 -0
@@ 66,3 66,6 @@ heat_cooling_constant = 1.0

[crafting]
can_craft = true

[drill]
resource_multiplier = 1.0

A crates/unified/assets/config/parts/thruster.part.toml => crates/unified/assets/config/parts/thruster.part.toml +25 -0
@@ 0,0 1,25 @@
[part]
name = "Thruster"
sprite_connected = "textures/thruster_on.png"
sprite_disconnected = "textures/thruster_off.png"

[physics]
width = 50
height = 50
mass = 100

[[thruster]]
id = "main"
apply_force_at_local = [ 0, 0 ]
thrust_vector = [ 0.0, -20000.0 ]

[[joint]]
id = "Top"
target = { translation = [ 0.0, 55.0, 0.0 ], rotation = 0.0 }
snap = { translation = [ 0.0, 25.0, 0.0 ], rotation = 0.0 }

[crafting]
can_craft = false

[[crafting.recipe]]
inputs = { iron = 25 }

M crates/unified/src/client/crafting/ui.rs => crates/unified/src/client/crafting/ui.rs +51 -4
@@ 1,15 1,17 @@
use bevy::{input_focus::{AutoFocus, InputFocus}, ui::RelativeCursorPosition};

use crate::{attachment::PartInShip, client::colors, ecs::{CanCraft, CraftingUi, MainCamera, Me}, prelude::*};
use crate::{attachment::PartInShip, client::colors, ecs::{CanCraft, CraftingUi, MainCamera, Me, ToggleDrillEvent}, prelude::*};

pub fn crafting_ui_plugin(app: &mut App) {
    app.add_systems(Update, close_button);
    app.add_systems(Update, (close_button, drill_button));
}

#[derive(Component)]
struct CloseButton(Entity); // stores corresponding menu entity
#[derive(Component)]
struct PreviousInteraction(Interaction); // stores corresponding menu entity
struct PreviousInteraction(Interaction);
#[derive(Component)]
struct DrillButton(Entity); // stores corresponding part

pub fn open_crafting_ui(
    ev: On<Pointer<Press>>,


@@ 28,11 30,12 @@ pub fn open_crafting_ui(
        };
        // we have our crafting entity!
        // now make the ui
        setup_ui(transform, commands, camera);
        setup_ui(entity, transform, commands, camera);
    }
}

fn setup_ui(
    parent_part: Entity,
    parent_transform: &Transform,
    mut commands: Commands,
    camera: Single<(Entity, &Camera, &GlobalTransform), (With<MainCamera>, Without<PartInShip>)>,


@@ 75,9 78,53 @@ fn setup_ui(
                Text::new("x"),
            ));
        });
        parent.spawn((
            Node {
                ..Default::default()
            },
            Button,
            DrillButton(parent_part),
            BackgroundColor(colors::CRUST),
            PreviousInteraction(Interaction::None),
        ))
        .with_children(|parent| {
            parent.spawn((
                Node {
                    ..Default::default()
                },
                Text::new("Start Drill"),
            ));
        });
    });
}

fn drill_button(
    mut interaction_query: Query<
        (&Interaction, &mut PreviousInteraction, &mut BackgroundColor, &DrillButton, &mut Button),
        Changed<Interaction>,
    >,
    mut toggle_drill_writer: MessageWriter<ToggleDrillEvent>,
) {
    for (interaction, mut previous_interaction, mut color, drill_button, mut button) in &mut interaction_query {
        match *interaction {
            Interaction::Pressed => {
                *color = colors::SURFACE_1.into();
            }
            Interaction::Hovered => {
                *color = colors::SURFACE_0.into();
                if previous_interaction.0 == Interaction::Pressed {
                    // released
                    toggle_drill_writer.write(ToggleDrillEvent { drill_entity: drill_button.0 });
                }
            }
            Interaction::None => {
                *color = colors::CRUST.into();
            }
        }
        previous_interaction.0 = *interaction;
    }
}

fn close_button(
    mut commands: Commands,
    mut interaction_query: Query<

M crates/unified/src/config/part.rs => crates/unified/src/config/part.rs +5 -0
@@ 15,6 15,7 @@ pub struct PartConfig {
    pub joints: Vec<JointConfig>,
    pub cooling: Option<CoolingConfig>,
    pub crafting: Option<CraftingConfig>,
    pub drill: Option<DrillConfig>,
}
#[derive(Deserialize, TypePath, Serialize, Clone, Debug, PartialEq)]
pub struct PartPartConfig {


@@ 70,3 71,7 @@ pub struct CoolingConfig {
pub struct CraftingConfig {
    pub can_craft: bool,
}
#[derive(Deserialize, TypePath, Serialize, Clone, Debug, PartialEq)]
pub struct DrillConfig {
    pub resource_multiplier: f32,
}

M crates/unified/src/ecs.rs => crates/unified/src/ecs.rs +12 -0
@@ 129,3 129,15 @@ pub struct Radiator {
    pub emissivity: f32,
    pub surface_area: f32,
}

#[derive(Component, Serialize, Deserialize, Debug)]
#[require(Replicated)]
pub struct Drill {
    pub drilling: bool,
    pub resource_multiplier: f32,
}
#[derive(Message, Serialize, Deserialize, Debug, MapEntities, Clone)]
pub struct ToggleDrillEvent {
    #[entities]
    pub drill_entity: Entity,
}

A crates/unified/src/server/drill.rs => crates/unified/src/server/drill.rs +17 -0
@@ 0,0 1,17 @@
use crate::{ecs::{Drill, ToggleDrillEvent}, prelude::*};

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

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

M crates/unified/src/server/mod.rs => crates/unified/src/server/mod.rs +3 -0
@@ 2,10 2,12 @@ mod earth_parts;
mod gravity;
mod part;
mod heat;
mod drill;
pub mod planets;
pub mod player;
mod system_sets;

use crate::server::drill::drill_plugin;
use crate::server::earth_parts::spawn_parts_plugin;
use crate::server::gravity::newtonian_gravity_plugin;
use crate::server::heat::conduction::heat_conduction_plugin;


@@ 55,6 57,7 @@ impl Plugin for ServerPlugin {
        .add_plugins(heat_cooling_plugin)
        .add_plugins(heat_radiation_plugin)
        .add_plugins(heat_conduction_plugin)
        .add_plugins(drill_plugin)
        .configure_sets(Update, WorldUpdateSet.before(PlayerInputSet));
        //.configure_sets(Update, PlayerInputSet.before(PhysicsSet::SyncBackend));
    }

M crates/unified/src/shared_plugins.rs => crates/unified/src/shared_plugins.rs +3 -1
@@ 1,6 1,6 @@
use crate::attachment::{Joint, JointOf, PartInShip, Peer, Ship, SnapOf, SnapOfJoint};
use crate::config::planet::{Planet, PlanetConfigCollection};
use crate::ecs::{CanCraft, DragRequestEvent, Hi, Part, Particles, Player, PlayerStorage, Temperature};
use crate::ecs::{CanCraft, DragRequestEvent, Drill, Hi, Part, Particles, Player, PlayerStorage, Temperature, ToggleDrillEvent};
use bevy::app::{App, PluginGroup, PluginGroupBuilder};
use bevy_common_assets::toml::TomlAssetPlugin;
use crate::prelude::*;


@@ 34,6 34,7 @@ impl PluginGroup for SharedPluginGroup {
pub fn register_everything(app: &mut App) {
    app.add_mapped_client_message::<ThrustSolution>(Channel::Ordered);
    app.add_mapped_client_message::<DragRequestEvent>(Channel::Ordered);
    app.add_mapped_client_message::<ToggleDrillEvent>(Channel::Ordered);
    app.add_mapped_server_message::<Hi>(Channel::Ordered);
    app.replicate::<Transform>();
    app.replicate::<GlobalTransform>();


@@ 54,6 55,7 @@ pub fn register_everything(app: &mut App) {
    app.replicate::<ThrusterOfPart>();
    app.replicate::<CanCraft>();
    app.replicate::<Temperature>();
    app.replicate::<Drill>();
}

fn physics_setup_plugin(app: &mut App) {