A crates/unified/assets/config/parts/frame.part.toml => crates/unified/assets/config/parts/frame.part.toml +32 -0
@@ 0,0 1,32 @@
+[part]
+name = "Frame"
+sprite_connected = "textures/hub_on.png"
+sprite_disconnected = "textures/hub_off.png"
+emissivity = 0.1
+specific_heat = 500.0
+radiation_area = 20.0
+
+[physics]
+width = 50
+height = 50
+mass = 10
+
+[[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 }
+
+[[joint]]
+id = "Right"
+target = { translation = [ 55.0, 0.0, 0.0 ], rotation = -90.0 }
+snap = { translation = [ 25.0, 0.0, 0.0 ], rotation = 0.0 }
+
+[[joint]]
+id = "Bottom"
+target = { translation = [ 0.0, -55.0, 0.0 ], rotation = -180.0 }
+snap = { translation = [ 0.0, -25.0, 0.0 ], rotation = 0.0 }
+
+[[joint]]
+id = "Left"
+target = { translation = [ -55.0, 0.0, 0.0 ], rotation = -270.0 }
+snap = { translation = [ -25.0, 0.0, 0.0 ], rotation = 0.0 }
M crates/unified/assets/config/parts/thruster.part.toml => crates/unified/assets/config/parts/thruster.part.toml +3 -6
@@ 2,6 2,9 @@
name = "Thruster"
sprite_connected = "textures/thruster_on.png"
sprite_disconnected = "textures/thruster_off.png"
+emissivity = 0.1
+specific_heat = 500.0
+radiation_area = 20.0
[physics]
width = 50
@@ 17,9 20,3 @@ thrust_vector = [ 0.0, -20000.0 ]
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/assets/config/planets.pc.toml => crates/unified/assets/config/planets.pc.toml +1 -1
@@ 39,7 39,7 @@ indicator_sprite = "textures/moon_icon.png"
radius = 545.4 # m
mass = 360_236_000.0 # kg
default_transform = [312_700.0, 0.0, 0.0]
-planet_resource = { name = "Silicon", color = { LinearRgba = { red = 0.7, green = 0.7, blue = 0.7, alpha = 1.0 } }, mining_speed = 2.0 }
+planet_resource = { name = "Silicon", color = { LinearRgba = { red = 0.7, green = 0.7, blue = 0.7, alpha = 1.0 } }, mining_speed = 5.0 }
orbit = { orbiting = "Earth", eccentricity = 0.0549 }
[[planets]]
M crates/unified/src/client/crafting/ui.rs => crates/unified/src/client/crafting/ui.rs +7 -1
@@ 2,7 2,7 @@ use std::collections::HashMap;
use bevy::{input_focus::{AutoFocus, InputFocus}, ui::RelativeCursorPosition};
-use crate::{attachment::PartInShip, client::colors, config::recipe::RecipesConfig, ecs::{CanCraft, CraftingUi, Drill, MainCamera, Me, Part, SingleStorage, ToggleDrillEvent}, prelude::*};
+use crate::{attachment::PartInShip, client::colors, config::recipe::RecipesConfig, ecs::{CanCraft, CraftPartRequest, CraftingUi, Drill, MainCamera, Me, Part, SingleStorage, ToggleDrillEvent}, prelude::*};
pub fn crafting_ui_plugin(app: &mut App) {
app.init_resource::<RecipeCollection>();
@@ 243,6 243,7 @@ fn create_recipe_list(
fn recipe_buttons(
mut interaction_query: Query<(&Interaction, &mut PreviousInteraction, &mut BackgroundColor, &RecipeElement),
Changed<Interaction>>,
+ mut crafting_message_writer: MessageWriter<CraftPartRequest>,
) {
for (interaction, mut previous_interaction, mut color, recipe) in &mut interaction_query {
match *interaction {
@@ 254,6 255,11 @@ fn recipe_buttons(
if previous_interaction.0 == Interaction::Pressed {
// released
debug!("{:?} {} {:?}", recipe.0, recipe.1, recipe.2);
+ crafting_message_writer.write(CraftPartRequest {
+ crafting_part: recipe.0,
+ crafted_part: recipe.1.clone(),
+ inputs: recipe.2.clone(),
+ });
}
}
Interaction::None => {
M crates/unified/src/ecs.rs => crates/unified/src/ecs.rs +8 -0
@@ 8,6 8,7 @@ use crate::prelude::*;
use bevy_replicon::prelude::Replicated;
use serde::{Deserialize, Serialize};
use avian2d::prelude::*;
+use std::collections::HashMap;
use std::sync::LazyLock;
#[derive(States, Debug, Clone, PartialEq, Eq, Hash)]
@@ 117,6 118,13 @@ pub struct Hi {
pub struct CanCraft;
#[derive(Component, Serialize, Deserialize, Debug)]
pub struct CraftingUi;
+#[derive(Message, Serialize, Deserialize, Debug, Clone, MapEntities)]
+pub struct CraftPartRequest {
+ #[entities]
+ pub crafting_part: Entity,
+ pub crafted_part: String,
+ pub inputs: HashMap<String, u32>,
+}
#[derive(Component, Serialize, Deserialize, Debug)]
#[require(Replicated)]
A crates/unified/src/server/craft.rs => crates/unified/src/server/craft.rs +25 -0
@@ 0,0 1,25 @@
+use crate::{ecs::{CraftPartRequest, Part}, prelude::*, server::part::{SpawnPartBundle, SpawnPartRequest}};
+
+pub fn craft_plugin(app: &mut App) {
+ app.add_systems(Update, receive_crafting_request);
+}
+
+fn receive_crafting_request(
+ mut craft_part_request: MessageReader<FromClient<CraftPartRequest>>,
+ mut part_query: Query<(&Transform, &Part)>,
+ mut commands: Commands,
+ asset_server: Res<AssetServer>,
+) {
+ for request in craft_part_request.read() {
+ let Ok((transform, part)) = part_query.get(request.crafting_part) else {
+ warn!("When receiving a crafting request, the crafting part didn't exist.");
+ continue;
+ };
+
+ commands.spawn(SpawnPartBundle {
+ req: SpawnPartRequest(asset_server.load(
+ format!("config/parts/{}.part.toml", request.crafted_part.to_lowercase()))),
+ transform: transform.with_translation(transform.translation + vec3(50.0, 0.0, 0.0)),
+ });
+ }
+}
M crates/unified/src/server/mod.rs => crates/unified/src/server/mod.rs +3 -0
@@ 3,10 3,12 @@ mod gravity;
mod part;
mod heat;
mod drill;
+mod craft;
pub mod planets;
pub mod player;
mod system_sets;
+use crate::server::craft::craft_plugin;
use crate::server::drill::drill_plugin;
use crate::server::earth_parts::spawn_parts_plugin;
use crate::server::gravity::newtonian_gravity_plugin;
@@ 58,6 60,7 @@ impl Plugin for ServerPlugin {
.add_plugins(heat_radiation_plugin)
.add_plugins(heat_conduction_plugin)
.add_plugins(drill_plugin)
+ .add_plugins(craft_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 +2 -1
@@ 1,7 1,7 @@
use crate::attachment::{Joint, JointOf, PartInShip, Peer, Ship, SnapOf, SnapOfJoint};
use crate::config::planet::{Planet, PlanetConfigCollection};
use crate::config::recipe::RecipesConfig;
-use crate::ecs::{CanCraft, DragRequestEvent, Drill, Hi, Part, Particles, Player, PlayerStorage, SingleStorage, Temperature, ToggleDrillEvent};
+use crate::ecs::{CanCraft, CraftPartRequest, DragRequestEvent, Drill, Hi, Part, Particles, Player, PlayerStorage, SingleStorage, Temperature, ToggleDrillEvent};
use bevy::app::{App, PluginGroup, PluginGroupBuilder};
use bevy_common_assets::toml::TomlAssetPlugin;
use crate::prelude::*;
@@ 37,6 37,7 @@ 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_client_message::<CraftPartRequest>(Channel::Ordered);
app.add_mapped_server_message::<Hi>(Channel::Ordered);
app.replicate::<Transform>();
app.replicate::<GlobalTransform>();