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) {