@@ 1,6 1,6 @@
[recipes]
Frame = [
- { order = 0, inputs = { Silicon = 10 } }
+ { order = 0, inputs = { Carbon = 10 } }
]
Thruster = [
{ order = 1, inputs = { Silicon = 20, Carbon = 20 } }
@@ 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(),
@@ 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()))),