~starkingdoms/starkingdoms

f6a4a4cbf42b10fc967ec425dd01205622442e8f — ghostly_zsh 17 hours ago 11e8a56 master
feat: crafting removes resources from the ship now
M crates/unified/assets/config/recipes.rc.toml => crates/unified/assets/config/recipes.rc.toml +1 -1
@@ 1,6 1,6 @@
[recipes]
Frame = [
    { order = 0, inputs = { Silicon = 10 } }
    { order = 0, inputs = { Carbon = 10 } }
]
Thruster = [
    { order = 1, inputs = { Silicon = 20, Carbon = 20 } }

M crates/unified/src/client/crafting/ui.rs => crates/unified/src/client/crafting/ui.rs +0 -1
@@ 254,7 254,6 @@ fn recipe_buttons(
                *color = colors::SURFACE_0.into();
                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(),

M crates/unified/src/server/craft.rs => crates/unified/src/server/craft.rs +72 -4
@@ 1,4 1,6 @@
use crate::{ecs::{CraftPartRequest, Part}, prelude::*, server::part::{SpawnPartBundle, SpawnPartRequest}};
use std::collections::HashMap;

use crate::{attachment::{PartInShip, Parts}, ecs::{CraftPartRequest, Part, Player, SingleStorage}, prelude::*, server::part::{SpawnPartBundle, SpawnPartRequest}};

pub fn craft_plugin(app: &mut App) {
    app.add_systems(Update, receive_crafting_request);


@@ 6,16 8,82 @@ pub fn craft_plugin(app: &mut App) {

fn receive_crafting_request(
    mut craft_part_request: MessageReader<FromClient<CraftPartRequest>>,
    mut part_query: Query<(&Transform, &Part)>,
    part_query: Query<(&Transform, &Part, &PartInShip)>,
    player_query: Query<(Entity, &Transform, &Part), With<Player>>,
    parts_query: Query<&Parts>,
    mut storage_query: Query<(&mut SingleStorage)>,
    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 {
    'request: for request in craft_part_request.read() {
        // TODO: make crafting take time
        let (transform, part, parts_list) = if let Ok((transform, part, part_in_ship)) = part_query.get(request.crafting_part) {
            // this is a normal part
            let Ok(parts_list) = parts_query.get(part_in_ship.0) else {
                warn!("Couldn't find parts list in part in ship");
                continue;
            };
            let parts_list = parts_list.iter().collect::<Vec<_>>();
            (transform, part, parts_list)
        } else if let Ok((entity, transform, part)) = player_query.get(request.crafting_part) {
            // this is a player
            let parts_list = if let Ok(parts_list) = parts_query.get(entity) {
                let mut parts_list = parts_list.iter().collect::<Vec<_>>();
                parts_list.push(entity);
                parts_list
            } else {
                vec![entity]
            };
            (transform, part, parts_list)
        } else {
            warn!("When receiving a crafting request, the crafting part didn't exist.");
            continue;
        };

        // find total resource in the ship
        let mut total_resource = HashMap::new();
        for part in parts_list.iter() {
            let Ok(storage) = storage_query.get_mut(*part) else {
                continue;
            };
            if let Some(resource) = total_resource.get_mut(&storage.resource_name) {
                *resource += storage.stored;
            } else {
                total_resource.insert(storage.resource_name.clone(), storage.stored);
            }
        }

        // check if resources in ship are sufficient
        for (resource_name, amount) in total_resource {
            if let Some(resource) = request.inputs.get(&resource_name) {
                if (*resource as f32) > amount {
                    continue 'request;
                }
            } else {
                // resource doesn't exist in the first place, continue
                continue 'request;
            }
        }
        // ok, we have enough resources

        // subtract recipe resources from ship
        let mut inputs = request.inputs.clone();
        for part in parts_list.iter() {
            let Ok(mut storage) = storage_query.get_mut(*part) else {
                continue;
            };
            if let Some(resource) = inputs.get_mut(&storage.resource_name) {
                if (*resource as f32) > storage.stored {
                    *resource -= storage.stored as u32;
                    storage.stored = 0.0;
                } else {
                    storage.stored -= *resource as f32;
                    inputs.remove(&storage.resource_name);
                }
            }
        }
        
        // ok, everything is good! spawn the part
        commands.spawn(SpawnPartBundle {
            req: SpawnPartRequest(asset_server.load(
                         format!("config/parts/{}.part.toml", request.crafted_part.to_lowercase()))),