~starkingdoms/starkingdoms

11e8a560ca3014cf9edbaacaf41d2818fdaabc3d — ghostly_zsh 20 hours ago b296131
feat: crafting buttons cause parts to spawn
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>();