From a4efade392aa7127c373b0247d39274cb0decd10 Mon Sep 17 00:00:00 2001 From: tom barrett Date: Tue, 19 Feb 2019 13:24:25 -0600 Subject: unified all server->client connection and brought logic to modules --- src/modules/construction.rs | 94 +++++++++++++++++++++++++--------- src/modules/engines.rs | 17 ++++++- src/modules/mining.rs | 120 +++++++++++++++++++++++++++++++++++--------- src/modules/navigation.rs | 56 +++++++++++++++------ src/modules/refinery.rs | 79 ++++++++++++++++++++--------- src/modules/tractorbeam.rs | 101 +++++++++++++++++++++---------------- 6 files changed, 335 insertions(+), 132 deletions(-) (limited to 'src/modules') diff --git a/src/modules/construction.rs b/src/modules/construction.rs index 0f7f8f2..ca4dd2d 100644 --- a/src/modules/construction.rs +++ b/src/modules/construction.rs @@ -1,21 +1,12 @@ +use std::collections::HashMap; use std::time::SystemTime; use crate::constants; +use crate::item::ItemType; +use crate::mass::Mass; +use crate::math::Vector; use crate::modules::types::ModuleType; -use crate::server::construction::ConstructionData; - -#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] -pub enum ConstructionStatus { - None, - Constructing, - Constructed, -} - -impl Default for ConstructionStatus { - fn default() -> Self { - ConstructionStatus::None - } -} +use crate::storage::Storage; #[derive(Serialize, Deserialize, Debug, Clone, Default)] pub struct Construction { @@ -35,41 +26,98 @@ impl Construction { } } - pub fn process(&mut self) { + pub fn process( + &mut self, + ship_velocity: Vector, + ship_position: Vector, + masses: &mut HashMap, + storage: &mut Storage, + ) { + if !self.has_enough(storage) { + self.off(); + } if let Some(timer) = self.start { if timer.elapsed().unwrap().as_secs() > self.time { self.start = Some(SystemTime::now()); self.status = ConstructionStatus::Constructed; } } + if self.status == ConstructionStatus::Constructed { + storage + .take_items(ItemType::Iron, constants::SHIP_CONSTRUCTION_IRON_COST) + .unwrap(); + masses.insert( + "Station".to_string(), + Mass::new_station( + ModuleType::Refinery, + ship_position.clone(), + ship_velocity.clone(), + ), + ); + self.constructed(); + } } - pub fn give_recv(&mut self, recv: String, construction_data: &ConstructionData) { + pub fn get_client_data(&self, storage: &Storage) -> String { + let client_data = ConstructionClientData { + has_enough: self.has_enough(storage), + status: self.status.clone(), + }; + serde_json::to_string(&client_data).unwrap() + "\n" + } + + pub fn give_received_data(&mut self, recv: String) { if let "c" = recv.as_str() { - if construction_data.has_enough { - self.toggle() - } + self.toggle() } } - pub fn toggle(&mut self) { + fn has_enough(&self, storage: &Storage) -> bool { + storage + .items + .iter() + .filter(|item| item.item_type == ItemType::Iron) + .count() + >= constants::SHIP_CONSTRUCTION_IRON_COST + } + + fn toggle(&mut self) { match self.status { ConstructionStatus::None => self.on(), _ => self.off(), }; } - pub fn on(&mut self) { + fn on(&mut self) { self.start = Some(SystemTime::now()); self.status = ConstructionStatus::Constructing; } - pub fn off(&mut self) { + fn off(&mut self) { self.start = None; self.status = ConstructionStatus::None; } - pub fn constructed(&mut self) { + fn constructed(&mut self) { self.off() } } + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct ConstructionClientData { + pub status: ConstructionStatus, + pub has_enough: bool, +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] +pub enum ConstructionStatus { + None, + Constructing, + Constructed, +} + +impl Default for ConstructionStatus { + fn default() -> Self { + ConstructionStatus::None + } +} diff --git a/src/modules/engines.rs b/src/modules/engines.rs index 007787c..63e1fcd 100644 --- a/src/modules/engines.rs +++ b/src/modules/engines.rs @@ -1,6 +1,7 @@ use crate::constants; use crate::mass::Mass; use crate::math::Vector; +use crate::modules::navigation::NavigationStatus; #[derive(Serialize, Deserialize, Debug, Clone, Default)] pub struct Engines { @@ -27,7 +28,7 @@ impl Engines { } } - pub fn give_recv( + pub fn give_received_data( &mut self, recv: String, position: Vector, @@ -61,6 +62,14 @@ impl Engines { self.acceleration = acceleration; } + pub fn get_client_data(&self, status: NavigationStatus) -> String { + let client_data = EnginesClientData { + has_target: status == NavigationStatus::Targeted, + fuel: self.fuel, + }; + serde_json::to_string(&client_data).unwrap() + "\n" + } + pub fn take_acceleration(&mut self) -> Vector { let mut acceleration = self.acceleration.clone(); self.acceleration = Vector::default(); @@ -76,3 +85,9 @@ impl Engines { } } } + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct EnginesClientData { + pub has_target: bool, + pub fuel: f64, +} diff --git a/src/modules/mining.rs b/src/modules/mining.rs index a6cea92..8e5b001 100644 --- a/src/modules/mining.rs +++ b/src/modules/mining.rs @@ -1,20 +1,11 @@ use std::time::SystemTime; use crate::constants; -use crate::server::mining::MiningData; - -#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] -pub enum MiningStatus { - None, - Mining, - Mined, -} - -impl Default for MiningStatus { - fn default() -> Self { - MiningStatus::None - } -} +use crate::item::ItemType; +use crate::mass::{Mass, MassType}; +use crate::math::Vector; +use crate::storage::Storage; +use std::collections::HashMap; #[derive(Serialize, Deserialize, Debug, Clone, Default)] pub struct Mining { @@ -34,41 +25,122 @@ impl Mining { } } - pub fn process(&mut self) { + pub fn process( + &mut self, + ship_position: Vector, + masses: &mut HashMap, + target: &mut Mass, + storage: &mut Storage, + ) { + if self.range < ship_position.distance_from(target.position.clone()) { + self.off(); + } if let Some(timer) = self.start { if timer.elapsed().unwrap().as_secs() > self.time { self.status = MiningStatus::Mined; - self.start = Some(SystemTime::now()); + self.start = None; + } + } + if self.status == MiningStatus::Mined { + if let MassType::Astroid { + ref mut resources, .. + } = target.mass_type + { + match resources.take_item(ItemType::CrudeMinerals) { + Some(item) => { + if !storage.give_item(item.clone()) { + let mass = Mass::new_item( + item.clone(), + target.position.clone(), + target.velocity.clone(), + ); + masses.insert(item.name.clone(), mass); + } + } + None => self.off(), + } } + self.mined(); } } - pub fn give_recv(&mut self, recv: String, mining_data: MiningData) { - if !mining_data.is_within_range { - self.off(); - } else if let "F" = recv.as_str() { + pub fn give_received_data(&mut self, recv: String) { + if let "F" = recv.as_str() { self.toggle() } } - pub fn toggle(&mut self) { + pub fn get_client_data(&self, ship_position: Vector, target: Option<&Mass>) -> String { + let mut astroid_has_minerals = false; + let mut is_within_range = false; + let has_astroid_target = match target { + Some(target) => match target.mass_type { + MassType::Astroid { ref resources, .. } => { + astroid_has_minerals = resources + .items + .iter() + .any(|item| item.item_type == ItemType::CrudeMinerals); + is_within_range = + self.range > ship_position.distance_from(target.position.clone()); + true + } + _ => false, + }, + None => false, + }; + + let client_data = MiningClientData { + has_astroid_target, + astroid_has_minerals, + is_within_range, + range: self.range, + status: self.status.clone(), + }; + + serde_json::to_string(&client_data).unwrap() + "\n" + } + + fn toggle(&mut self) { match self.status { MiningStatus::None => self.on(), _ => self.off(), }; } - pub fn on(&mut self) { + fn on(&mut self) { self.start = Some(SystemTime::now()); self.status = MiningStatus::Mining; } - pub fn off(&mut self) { + fn off(&mut self) { self.start = None; self.status = MiningStatus::None; } - pub fn mined(&mut self) { + fn mined(&mut self) { self.status = MiningStatus::Mining; + self.start = Some(SystemTime::now()); + } +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct MiningClientData { + pub has_astroid_target: bool, + pub astroid_has_minerals: bool, + pub is_within_range: bool, + pub status: MiningStatus, + pub range: f64, +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] +pub enum MiningStatus { + None, + Mining, + Mined, +} + +impl Default for MiningStatus { + fn default() -> Self { + MiningStatus::None } } diff --git a/src/modules/navigation.rs b/src/modules/navigation.rs index 5fcf89f..b15beef 100644 --- a/src/modules/navigation.rs +++ b/src/modules/navigation.rs @@ -5,19 +5,6 @@ use crate::constants; use crate::mass::Mass; use crate::math::Vector; -#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] -pub enum NavigationStatus { - None, - Targeting, - Targeted, -} - -impl Default for NavigationStatus { - fn default() -> Self { - NavigationStatus::None - } -} - #[derive(Serialize, Deserialize, Debug, Clone, Default)] pub struct Navigation { pub range: f64, @@ -38,7 +25,8 @@ impl Navigation { } } - pub fn process(&mut self) { + pub fn process(&mut self, ship_position: Vector, masses: &mut HashMap) { + self.verify_target(ship_position, masses); if let Some(timer) = self.start { if timer.elapsed().unwrap().as_secs() > self.time { self.status = NavigationStatus::Targeted; @@ -47,7 +35,7 @@ impl Navigation { } } - pub fn give_recv(&mut self, recv: String) { + pub fn give_received_data(&mut self, recv: String) { if !recv.is_empty() { self.start = Some(SystemTime::now()); self.status = NavigationStatus::Targeting; @@ -55,7 +43,22 @@ impl Navigation { } } - pub fn verify_target(&mut self, ship_position: Vector, masses: &HashMap) { + pub fn get_client_data(&self, ship_position: Vector, masses: &HashMap) -> String { + let client_data = NavigationClientData { + ship_position: ship_position.clone(), + status: self.status.clone(), + target_name: self.target_name.clone(), + available_targets: masses + .iter() + .filter(|(_, mass)| ship_position.distance_from(mass.position.clone()) < self.range) + .map(|(name, mass)| (name.to_string(), mass.position.clone())) + .collect(), + }; + + serde_json::to_string(&client_data).unwrap() + "\n" + } + + fn verify_target(&mut self, ship_position: Vector, masses: &HashMap) { if let Some(name) = self.target_name.clone() { let target = masses.get(&name).unwrap(); if target.position.distance_from(ship_position) > self.range { @@ -65,3 +68,24 @@ impl Navigation { } } } + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct NavigationClientData { + pub ship_position: Vector, + pub available_targets: Vec<(String, Vector)>, + pub status: NavigationStatus, + pub target_name: Option, +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] +pub enum NavigationStatus { + None, + Targeting, + Targeted, +} + +impl Default for NavigationStatus { + fn default() -> Self { + NavigationStatus::None + } +} diff --git a/src/modules/refinery.rs b/src/modules/refinery.rs index 4a4ca85..a0a401b 100644 --- a/src/modules/refinery.rs +++ b/src/modules/refinery.rs @@ -1,20 +1,8 @@ use std::time::SystemTime; use crate::constants; -use crate::server::refinery::RefineryData; - -#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] -pub enum RefineryStatus { - None, - Refining, - Refined, -} - -impl Default for RefineryStatus { - fn default() -> Self { - RefineryStatus::None - } -} +use crate::item::{Item, ItemType}; +use crate::storage::Storage; #[derive(Serialize, Deserialize, Debug, Clone, Default)] pub struct Refinery { @@ -32,41 +20,84 @@ impl Refinery { } } - pub fn process(&mut self) { + pub fn process(&mut self, storage: &mut Storage) { + if !self.has_crude_minerals(storage) { + self.off(); + } if let Some(timer) = self.start { if timer.elapsed().unwrap().as_secs() > self.time { self.status = RefineryStatus::Refined; - self.start = Some(SystemTime::now()); + self.start = None } } + if self.status == RefineryStatus::Refined { + storage.take_item(ItemType::CrudeMinerals); + storage.give_item(Item::new(ItemType::Iron)); + storage.give_item(Item::new(ItemType::Hydrogen)); + self.taken(); + } } - pub fn give_recv(&mut self, recv: String, refinery_data: RefineryData) { - if !refinery_data.has_crude_minerals { - self.off(); - } else if let "R" = recv.as_str() { + pub fn get_client_data(&self, storage: &Storage) -> String { + let client_data = RefineryClientData { + has_crude_minerals: self.has_crude_minerals(storage), + status: self.status.clone(), + }; + + serde_json::to_string(&client_data).unwrap() + "\n" + } + + pub fn give_received_data(&mut self, recv: String) { + if let "R" = recv.as_str() { self.toggle(); } } - pub fn toggle(&mut self) { + fn has_crude_minerals(&self, storage: &Storage) -> bool { + storage + .items + .iter() + .any(|item| item.item_type == ItemType::CrudeMinerals) + } + + fn toggle(&mut self) { match self.status { RefineryStatus::None => self.on(), _ => self.off(), }; } - pub fn on(&mut self) { + fn on(&mut self) { self.start = Some(SystemTime::now()); self.status = RefineryStatus::Refining; } - pub fn off(&mut self) { + fn off(&mut self) { self.start = None; self.status = RefineryStatus::None; } - pub fn taken(&mut self) { + fn taken(&mut self) { self.status = RefineryStatus::Refining; + self.start = Some(SystemTime::now()); + } +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct RefineryClientData { + pub has_crude_minerals: bool, + pub status: RefineryStatus, +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] +pub enum RefineryStatus { + None, + Refining, + Refined, +} + +impl Default for RefineryStatus { + fn default() -> Self { + RefineryStatus::None } } diff --git a/src/modules/tractorbeam.rs b/src/modules/tractorbeam.rs index c77ea1f..3bbb32a 100644 --- a/src/modules/tractorbeam.rs +++ b/src/modules/tractorbeam.rs @@ -9,20 +9,6 @@ pub struct Tractorbeam { desired_distance: Option, } -#[derive(Serialize, Deserialize, Debug, Clone)] -pub enum TractorbeamStatus { - None, - Push, - Pull, - Bring, -} - -impl Default for TractorbeamStatus { - fn default() -> Self { - TractorbeamStatus::None - } -} - impl Tractorbeam { pub fn new() -> Tractorbeam { Tractorbeam { @@ -32,7 +18,18 @@ impl Tractorbeam { } } - pub fn give_recv(&mut self, recv: String) { + pub fn process(&mut self) {} + + pub fn get_client_data(&self, target: Option<&Mass>) -> String { + let client_data = TractorbeamClientData { + has_target: target.is_some(), + status: self.status.clone(), + }; + + serde_json::to_string(&client_data).unwrap() + "\n" + } + + pub fn give_received_data(&mut self, recv: String) { match recv.as_str() { "o" => self.toggle_pull(), "p" => self.toggle_push(), @@ -41,7 +38,32 @@ impl Tractorbeam { } } - pub fn toggle_pull(&mut self) { + pub fn get_acceleration(&self, ship_position: Vector, target_position: Vector) -> Vector { + let acceleration = ship_position.clone() - target_position.clone(); + match self.status { + TractorbeamStatus::Push => acceleration.unitize() * -0.05, + TractorbeamStatus::Pull => acceleration.unitize() * 0.05, + TractorbeamStatus::Bring => match self.desired_distance { + Some(desired_distance) => { + if desired_distance > ship_position.distance_from(target_position) { + acceleration.unitize() * -0.05 + //some sort of velocity limiter + //if target.speed_torwards(ship) < 10.0 { + // acceleration.unitize() * -0.05 + //} else { + // Vector::default() + //} + } else { + acceleration.unitize() * 0.05 + } + } + None => Vector::default(), + }, + TractorbeamStatus::None => Vector::default(), + } + } + + fn toggle_pull(&mut self) { self.status = match self.status { TractorbeamStatus::None => TractorbeamStatus::Pull, TractorbeamStatus::Push => TractorbeamStatus::Pull, @@ -50,7 +72,7 @@ impl Tractorbeam { } } - pub fn toggle_push(&mut self) { + fn toggle_push(&mut self) { self.status = match self.status { TractorbeamStatus::None => TractorbeamStatus::Push, TractorbeamStatus::Pull => TractorbeamStatus::Push, @@ -59,7 +81,7 @@ impl Tractorbeam { } } - pub fn toggle_bring(&mut self, desired_distance: f64) { + fn toggle_bring(&mut self, desired_distance: f64) { self.desired_distance = Some(desired_distance); self.status = match self.status { TractorbeamStatus::None => TractorbeamStatus::Bring, @@ -68,33 +90,24 @@ impl Tractorbeam { TractorbeamStatus::Bring => TractorbeamStatus::None, } } +} - pub fn off(&mut self) { - self.status = TractorbeamStatus::None; - } +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct TractorbeamClientData { + pub has_target: bool, + pub status: TractorbeamStatus, +} - pub fn get_acceleration(&self, position: Vector, target: Mass) -> Vector { - let acceleration = position.clone() - target.position.clone(); - match self.status { - TractorbeamStatus::Push => acceleration.unitize() * -0.05, - TractorbeamStatus::Pull => acceleration.unitize() * 0.05, - TractorbeamStatus::Bring => match self.desired_distance { - Some(desired_distance) => { - if desired_distance > position.distance_from(target.position) { - acceleration.unitize() * -0.05 - //some sort of velocity limiter - //if target.speed_torwards(ship) < 10.0 { - // acceleration.unitize() * -0.05 - //} else { - // Vector::default() - //} - } else { - acceleration.unitize() * 0.05 - } - } - None => Vector::default(), - }, - TractorbeamStatus::None => Vector::default(), - } +#[derive(Serialize, Deserialize, Debug, Clone)] +pub enum TractorbeamStatus { + None, + Push, + Pull, + Bring, +} + +impl Default for TractorbeamStatus { + fn default() -> Self { + TractorbeamStatus::None } } -- cgit v1.2.3