From 4c612ac480fa5c6a4ea8ef3cecd0f71e7d9424f9 Mon Sep 17 00:00:00 2001 From: ghostly_zsh Date: Thu, 27 Mar 2025 12:49:46 -0500 Subject: [PATCH] mining is back --- crates/server/src/crafting/components.rs | 50 ++++++++++--- crates/server/src/crafting/mining.rs | 71 +++++++++++++++++++ crates/server/src/crafting/mod.rs | 1 + crates/server/src/main.rs | 1 + crates/server/src/player/client_login.rs | 15 ++-- crates/server/src/player/mod.rs | 19 +++-- .../server/src/player/player_mouse_input.rs | 27 ++++++- 7 files changed, 154 insertions(+), 30 deletions(-) create mode 100644 crates/server/src/crafting/mining.rs diff --git a/crates/server/src/crafting/components.rs b/crates/server/src/crafting/components.rs index cfa99870a902e423228ea5171768660aa4197a1b..5b3405772daa1c3bae1abd83bfda0a5e679de6f0 100644 --- a/crates/server/src/crafting/components.rs +++ b/crates/server/src/crafting/components.rs @@ -1,21 +1,53 @@ use std::collections::HashMap; use bevy::prelude::Component; +use starkingdoms_common::PlanetType; -#[derive(Debug, Clone, Copy, PartialEq)] +#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)] pub enum MaterialType { - Silicon, // Mercury - Sulfur, // Venus - Iron, // Mars - Hydrogen, // Jupiter - Helium, // Saturn - Rubber, // Uranus - Composite, // Neptune - Ice, // Pluto + Plasma, // Sun + Composite, // Mercury + Sulfur, // Venus + Silicon, // Moon + Iron, // Mars + Hydrogen, // Jupiter + Helium, // Saturn + Rubber, // Uranus + Methane, // Neptune + Ice, // Pluto +} +impl TryFrom for MaterialType { + type Error = (); + fn try_from(value: PlanetType) -> Result { + match value { + PlanetType::Sun => Ok(Self::Plasma), + PlanetType::Mercury => Ok(Self::Composite), + PlanetType::Venus => Ok(Self::Sulfur), + PlanetType::Moon => Ok(Self::Silicon), + PlanetType::Mars => Ok(Self::Iron), + PlanetType::Jupiter => Ok(Self::Hydrogen), + PlanetType::Saturn => Ok(Self::Helium), + PlanetType::Uranus => Ok(Self::Rubber), + PlanetType::Neptune => Ok(Self::Methane), + PlanetType::Pluto => Ok(Self::Ice), + _ => Err(()), + } + } } #[derive(Component, Debug, Clone)] pub struct MaterialStorage { + pub material_type: MaterialType, + pub stored: u32, + pub capacity: u32, +} + +#[derive(Component, Debug, Clone, Default)] +pub struct VarietyMaterialStorage { pub materials: HashMap, pub capacity: u32, } + +#[derive(Component, Debug, Clone, Default)] +pub struct IsMining(pub bool); + diff --git a/crates/server/src/crafting/mining.rs b/crates/server/src/crafting/mining.rs new file mode 100644 index 0000000000000000000000000000000000000000..f757830371d74c7a9ec71a13a4c2933d0faa5e18 --- /dev/null +++ b/crates/server/src/crafting/mining.rs @@ -0,0 +1,71 @@ +use bevy::prelude::{Children, Entity, Query, Res, With}; +use bevy_rapier2d::plugin::RapierContext; +use crate::{module::component::Attach, planet::PlanetType}; + +use super::components::{IsMining, MaterialType, VarietyMaterialStorage}; +pub fn mine_materials( + rapier_context: Res, + planet_query: Query<(&PlanetType, &Children)>, + mut mineable_query: Query<(Entity, &mut Attach, Option<&IsMining>, Option<&mut VarietyMaterialStorage>)>, +) { + for (planet_type, children) in &planet_query { + for (entity1, entity2, intersecting) in rapier_context.intersection_pairs_with(*children.first().unwrap()) { + if !intersecting { continue } + let other = if *children.first().unwrap() == entity1 { + entity2 + } else { + entity1 + }; + let (entity, attach, mineable, _) = match mineable_query.get(other) { + Ok(m) => m, + Err(_) => continue, + }; + let associated_player = match attach.associated_player { + Some(e) => e, + None => entity + }; + // is the module mining + if let Some(mineable) = mineable { + if mineable.0 { + if let Some(storage_entity) = find_storage(associated_player, &mineable_query) { + let (_, _, _, storage) = mineable_query.get_mut(storage_entity).unwrap(); + if let Some(mut storage) = storage { + if let Ok(material) = planet_type.0.try_into() { + match storage.materials.get_mut(&material) { + Some(v) => *v += 1, + None => { storage.materials.insert(material, 1); } + } + } + } + } + } + } + } + } +} +pub fn find_storage( + player: Entity, + mineable_query: &Query<(Entity, &mut Attach, Option<&IsMining>, Option<&mut VarietyMaterialStorage>)>, +) -> Option { + for (entity, attach, _, storage) in mineable_query.iter() { + if let Some(storage) = storage { + if attach.associated_player == Some(player) { + // found a valid storage + if storage.materials.values().sum::() > storage.capacity { + // cannot store more materials in a filled storage + continue; + } + return Some(entity); + } else if attach.associated_player == None { + // this is a player + if storage.materials.values().sum::() > storage.capacity { + // cannot store more materials in a filled storage + continue; + } + return Some(entity); + } + } + + } + return None; +} diff --git a/crates/server/src/crafting/mod.rs b/crates/server/src/crafting/mod.rs index f188f2c26df92954cf6bc22d15be25d77f9dc62f..334e6a7224f9b581351370208a824a8f926ce2b9 100644 --- a/crates/server/src/crafting/mod.rs +++ b/crates/server/src/crafting/mod.rs @@ -1 +1,2 @@ pub mod components; +pub mod mining; diff --git a/crates/server/src/main.rs b/crates/server/src/main.rs index c7b69c8b134c2d3c4eaf88f0153d6f70ba746f94..f907a083f77f09e79697491d191a3711f6bd9ef6 100644 --- a/crates/server/src/main.rs +++ b/crates/server/src/main.rs @@ -164,6 +164,7 @@ fn main() { player::packet::on_position_change, module::save::save_eligibility, module::convert_modules, + crafting::mining::mine_materials, ), ) .add_systems( diff --git a/crates/server/src/player/client_login.rs b/crates/server/src/player/client_login.rs index 3b098c06cd02dacfc570a51f81848ef71c40fb88..60597f38b41f152184faf64f2053249c5d43e123 100644 --- a/crates/server/src/player/client_login.rs +++ b/crates/server/src/player/client_login.rs @@ -1,4 +1,4 @@ -use std::net::SocketAddr; +use std::{collections::HashMap, net::SocketAddr}; use bevy::{math::vec2, prelude::*}; use bevy_rapier2d::prelude::*; @@ -9,14 +9,10 @@ use sha2::Sha256; use starkingdoms_common::{packet::{MessageType, Packet, Part, Planet, ProtoPartFlags}, proto_part_flags, proto_transform, unpack_savefile, PartType as c_PartType, PlanetType as c_PlanetType}; use crate::{ - config::StkConfig, - module::{ + config::StkConfig, crafting::components::{IsMining, VarietyMaterialStorage}, module::{ component::{Attach, CanAttach, LooseAttach, PartBundle, PartFlags, PartType}, save::load_savefile, - }, - planet::PlanetType, - ws::{PacketMessageConvert, WsEvent}, - AppKeys, UserToken, CLIENT_SCALE, + }, planet::PlanetType, ws::{PacketMessageConvert, WsEvent}, AppKeys, UserToken, CLIENT_SCALE }; use super::component::{Input, Player}; @@ -96,6 +92,11 @@ pub fn spawn_player( ..default() }); entity_id + .insert(VarietyMaterialStorage { + materials: HashMap::new(), + capacity: 200, + }) + .insert(IsMining(false)) .insert(Collider::cuboid(0.5, 0.5)) .insert(AdditionalMassProperties::MassProperties(MassProperties { local_center_of_mass: vec2(0.0, 0.0), diff --git a/crates/server/src/player/mod.rs b/crates/server/src/player/mod.rs index 4ee19a6f9e422066d7d147bc5aecabb58f95c0cb..8b58e139a30cadb41d1463687ac33ee7098438db 100644 --- a/crates/server/src/player/mod.rs +++ b/crates/server/src/player/mod.rs @@ -8,17 +8,10 @@ use send_message::send_message; use starkingdoms_common::{packet::Packet, PartType as c_PartType}; use crate::{ - config::StkConfig, - err_or_cont, - mathutil::rot2d, - module::{ + config::StkConfig, crafting::components::IsMining, err_or_cont, mathutil::rot2d, module::{ component::{Attach, CanAttach, LooseAttach, PartFlags, PartType}, PART_HALF_SIZE, - }, - part, - planet::PlanetType, - ws::{PacketMessageConvert, WsEvent}, - AppKeys, CLIENT_SCALE, + }, part, planet::PlanetType, ws::{PacketMessageConvert, WsEvent}, AppKeys, CLIENT_SCALE }; pub mod client_login; @@ -66,6 +59,7 @@ pub fn on_message( ), Without, >, + mut mining_query: Query<&mut IsMining>, mut packet_recv: Local>, mut packet_event_send: ResMut>, app_keys: Res, @@ -160,11 +154,11 @@ pub fn on_message( x, y, released, - button: _, + button, } => { let x = x / CLIENT_SCALE; let y = y / CLIENT_SCALE; - for (entity, mut q_player, _transform, _velocity, _attach, _) in + for (entity, mut q_player, transform, _velocity, _attach, _) in &mut player_query { if q_player.addr == *from { @@ -192,9 +186,12 @@ pub fn on_message( mouse_picking( &attached_query, &part_query, + (entity, transform), + &mut mining_query, &mut q_player, x, y, + &button, entity, ); } diff --git a/crates/server/src/player/player_mouse_input.rs b/crates/server/src/player/player_mouse_input.rs index 5fa6e0994c0ec877133ed488fcc1f4d2457b5cc1..0f329b8dec6bffc07b87a63c11dc2daf03417395 100644 --- a/crates/server/src/player/player_mouse_input.rs +++ b/crates/server/src/player/player_mouse_input.rs @@ -2,10 +2,9 @@ use bevy::{math::vec3, prelude::*}; use bevy_rapier2d::prelude::*; use crate::{ - module::component::{Attach, CanAttach, LooseAttach, PartFlags, PartType}, - planet::PlanetType, + crafting::components::IsMining, module::component::{Attach, CanAttach, LooseAttach, PartFlags, PartType}, planet::PlanetType }; -use starkingdoms_common::PartType as c_PartType; +use starkingdoms_common::{packet::ButtonType, PartType as c_PartType}; use super::component::Player; @@ -120,9 +119,12 @@ pub fn mouse_picking( ), (Without, Without, Without), >, + player: (Entity, &Transform), + mining_query: &mut Query<&mut IsMining>, q_player: &mut Player, x: f32, y: f32, + button: &ButtonType, entity: Entity, ) { for (m_entity, part_type, transform, m_attach, _velocity, _, _, _) in attached_query.iter() { @@ -170,4 +172,23 @@ pub fn mouse_picking( break; } } + { + let transform = player.1; + let pos = transform.translation; + let rel_x = pos.x - x; + let rel_y = pos.y - y; + let angle = -transform.rotation.z; + let x = rel_x * angle.cos() - rel_y * angle.sin(); + let y = rel_x * angle.sin() + rel_y * angle.cos(); + let bound = [-0.5, 0.5, -0.5, 0.5]; // left, right, top, bottom + + if bound[0] < x && x < bound[1] && bound[2] < y && y < bound[3] { + if *button == ButtonType::Right { + // toggle mining + if let Ok(mut is_mining) = mining_query.get_mut(entity) { + is_mining.0 = !is_mining.0; + } + } + } + } }