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()),