~starkingdoms/starkingdoms

0463a5645b803f979f0efb597469ed3ea3de00b3 — ghostly_zsh 13 hours ago 967e654
feat: drill drills (in theory)
M crates/unified/assets/config/parts/hearty.part.toml => crates/unified/assets/config/parts/hearty.part.toml +4 -0
@@ 69,3 69,7 @@ can_craft = true

[drill]
resource_multiplier = 1.0

[storage]
storage_type = "SingleResource"
capacity = 1000

M crates/unified/src/config/part.rs => crates/unified/src/config/part.rs +11 -0
@@ 16,6 16,7 @@ pub struct PartConfig {
    pub cooling: Option<CoolingConfig>,
    pub crafting: Option<CraftingConfig>,
    pub drill: Option<DrillConfig>,
    pub storage: Option<StorageConfig>,
}
#[derive(Deserialize, TypePath, Serialize, Clone, Debug, PartialEq)]
pub struct PartPartConfig {


@@ 75,3 76,13 @@ pub struct CraftingConfig {
pub struct DrillConfig {
    pub resource_multiplier: f32,
}
#[derive(Deserialize, TypePath, Serialize, Clone, Debug, PartialEq)]
pub struct StorageConfig {
    pub storage_type: StorageType,
    pub capacity: u32,
}
#[derive(Deserialize, TypePath, Serialize, Clone, Debug, PartialEq)]
pub enum StorageType {
    SingleResource,
    MultipleResources,
}

M crates/unified/src/ecs.rs => crates/unified/src/ecs.rs +8 -0
@@ 145,3 145,11 @@ pub struct ToggleDrillEvent {
    #[entities]
    pub drill_entity: Entity,
}

#[derive(Component, Serialize, Deserialize, Debug)]
#[require(Replicated)]
pub struct SingleStorage {
    pub resource_name: String,
    pub capacity: f32,
    pub stored: f32,
}

M crates/unified/src/server/drill.rs => crates/unified/src/server/drill.rs +47 -2
@@ 1,7 1,7 @@
use crate::{ecs::{Drill, PlanetSensor, ToggleDrillEvent}, prelude::*};
use crate::{attachment::{PartInShip, Parts}, config::planet::Planet, ecs::{Drill, Part, PlanetSensor, SingleStorage, ToggleDrillEvent}, prelude::*};

pub fn drill_plugin(app: &mut App) {
    app.add_systems(Update, (toggle_drill, drill_on_planet));
    app.add_systems(Update, (toggle_drill, drill_on_planet, do_drilling));
}

fn toggle_drill(


@@ 44,3 44,48 @@ fn drill_on_planet(
        drill.on_planet = None;
    }
}

fn do_drilling(
    drills: Query<(&Drill, &PartInShip)>,
    parts_query: Query<&Parts>,
    mut storage_part_query: Query<&mut SingleStorage, With<Part>>,
    planet_query: Query<&Planet>,
    time: Res<Time>,
) {
    for (drill, part_in_ship) in drills {
        if !drill.drilling || drill.on_planet.is_none() {
            continue
        }
        let planet_name = drill.on_planet.clone().unwrap();
        let mut planet = None;
        for q_planet in planet_query {
            if q_planet.name == planet_name {
                planet = Some(q_planet);
                break;
            }
        }
        // if the planet name doesn't match a planet, we have a big problem
        let planet = planet.expect("In do_drilling, a planet name didn't match a planet");
        let Some(ref planet_resource) = planet.planet_resource else {
            continue
        };
        let player = part_in_ship.0;
        let Ok(parts_list) = parts_query.get(player) else {
            error!("In do_drilling, there was a player without a Parts");
            continue
        };
        for part_entity in parts_list.iter() {
            let Ok(mut storage) = storage_part_query.get_mut(part_entity) else {
                continue
            };
            if storage.resource_name.is_empty() {
                storage.resource_name = planet_resource.name.clone();
            }
            // now that the name isn't empty, this will trigger
            if storage.resource_name == planet_resource.name {
                storage.stored += planet_resource.mining_speed * drill.resource_multiplier * time.delta_secs();
                storage.stored = storage.stored.min(storage.capacity);
            }
        }
    }
}

M crates/unified/src/server/part.rs => crates/unified/src/server/part.rs +14 -2
@@ 1,6 1,6 @@
use crate::attachment::{Joint, JointId, JointOf, Joints, Peer, SnapOf, SnapOfJoint};
use crate::config::part::{CoolingConfig, CraftingConfig, DrillConfig, JointConfig, PartConfig};
use crate::ecs::{CanCraft, Cooler, Drill, Part, PartHandle, Radiator, Temperature};
use crate::config::part::{CoolingConfig, CraftingConfig, DrillConfig, JointConfig, PartConfig, StorageConfig, StorageType};
use crate::ecs::{CanCraft, Cooler, Drill, Part, PartHandle, Radiator, SingleStorage, Temperature};
use crate::prelude::*;
use bevy_replicon::prelude::Replicated;
use crate::ecs::thruster::{PartThrusters, Thruster, ThrusterBundle, ThrusterId, ThrusterOfPart};


@@ 41,6 41,9 @@ fn handle_ready_parts(
            if let Some(ref drill_config) = strong_config.drill {
                drill_bundle(&mut commands.entity(entity), &drill_config);
            }
            if let Some(ref storage_config) = strong_config.storage {
                storage_bundle(&mut commands.entity(entity), &storage_config);
            }
            spawn_joints(strong_config, entity, commands.reborrow());
            spawn_thrusters(strong_config, entity, commands.reborrow());
        }


@@ 163,6 166,15 @@ fn drill_bundle(entity: &mut EntityCommands, config: &DrillConfig) {
        on_planet: None,
    });
}
fn storage_bundle(entity: &mut EntityCommands, config: &StorageConfig) {
    if matches!(config.storage_type, StorageType::SingleResource) {
        entity.insert(SingleStorage {
            resource_name: String::new(),
            capacity: config.capacity,
            stored: 0,
        });
    }
}
fn spawn_joint_bundle(joint: &JointConfig, part: &PartConfig, parent: &Entity) -> impl Bundle {
    let j_comp = Joint {
        id: JointId::from_part_and_joint_id(part.part.name.clone(), joint.id.clone()),