From 070485e093dc540a5db9650d438cffe3d18d3883 Mon Sep 17 00:00:00 2001 From: tom barrett Date: Tue, 12 Feb 2019 13:20:06 -0600 Subject: added constants file, made so items are referred to by an enum, figured better ways than ship_clone --- src/bin/server.rs | 5 ++-- src/client/construction.rs | 8 +++--- src/client/refinery.rs | 4 +-- src/constants.rs | 20 +++++++++++++++ src/item.rs | 23 ++++++++++++----- src/lib.rs | 1 + src/mass.rs | 60 +++++++++++---------------------------------- src/modules/construction.rs | 8 +++--- src/modules/engines.rs | 18 +++++++++----- src/modules/mining.rs | 8 +++--- src/modules/navigation.rs | 5 ++-- src/modules/refinery.rs | 6 +++-- src/modules/tractorbeam.rs | 9 ++++--- src/server/construction.rs | 39 ++++++++++++++--------------- src/server/engines.rs | 8 ++++-- src/server/mining.rs | 57 +++++++++++++++++++++++++----------------- src/server/navigation.rs | 2 +- src/server/refinery.rs | 29 +++++++++++----------- src/server/tractorbeam.rs | 4 +-- src/storage.rs | 49 +++++++++++++++++++++++------------- 20 files changed, 203 insertions(+), 160 deletions(-) create mode 100644 src/constants.rs (limited to 'src') diff --git a/src/bin/server.rs b/src/bin/server.rs index ea961b7..0429224 100644 --- a/src/bin/server.rs +++ b/src/bin/server.rs @@ -5,6 +5,7 @@ use std::net::TcpListener; use std::thread::sleep; use std::time::Duration; +use space::constants; use space::mass::Mass; use space::math::rand_name; use space::server::connection::ServerConnection; @@ -12,7 +13,7 @@ use space::server::connection::ServerConnection; fn populate() -> HashMap { let mut masses: HashMap = HashMap::new(); - for _ in 0..10 { + for _ in 0..constants::ASTROID_COUNT { masses.insert(rand_name(), Mass::new_astroid()); } @@ -48,7 +49,7 @@ fn main() { mass.process(); } - sleep(Duration::from_millis(100)); + sleep(Duration::from_millis(constants::SLEEP_DURATION)); } } } diff --git a/src/client/construction.rs b/src/client/construction.rs index b034b77..8cb812f 100644 --- a/src/client/construction.rs +++ b/src/client/construction.rs @@ -7,6 +7,7 @@ use std::io::{stdout, Read, Write}; use std::io::{BufRead, BufReader}; use std::net::TcpStream; +use crate::constants; use crate::modules::construction::ConstructionStatus; use crate::server::construction::ConstructionData; @@ -24,7 +25,7 @@ pub fn client_construction(mut stream: TcpStream, mut buff_r: BufReader { write!(stdout, "{}Press c to create a refinery.", clear).unwrap() @@ -34,8 +35,9 @@ pub fn client_construction(mut stream: TcpStream, mut buff_r: BufReader) let clear = termion::cursor::Goto(1, 1); - if data.has_minerals { + if data.has_crude_minerals { match data.status { RefineryStatus::None => { write!(stdout, "{}Press R to begin refining.", clear).unwrap() @@ -32,7 +32,7 @@ pub fn client_refinery(mut stream: TcpStream, mut buff_r: BufReader) _ => write!(stdout, "{}Press R to stop refining.", clear).unwrap(), }; } else { - write!(stdout, "{}You have no refinable minerals.", clear).unwrap(); + write!(stdout, "{}You have no crude minerals.", clear).unwrap(); } if let Some(c) = stdin.next() { diff --git a/src/constants.rs b/src/constants.rs new file mode 100644 index 0000000..c896a39 --- /dev/null +++ b/src/constants.rs @@ -0,0 +1,20 @@ +pub const ASTROID_COUNT: usize = 10; +pub const ASTROID_STORAGE_CAPACITY: usize = 100; +pub const ASTROID_STARTING_MINERALS_MAX: usize = 20; +pub const ASTROID_STARTING_VELOCITY_MAX: f64 = 0.5; +pub const ASTROID_STARTING_POSITION_MAX: f64 = 50.0; + +pub const SHIP_STORAGE_CAPACITY: usize = 100; +pub const SHIP_CONSTRUCTION_IRON_COST: usize = 5; +pub const SHIP_CONSTRUCTION_TIME: u64 = 5; +pub const SHIP_MINING_TIME: u64 = 5; +pub const SHIP_MINING_RANGE: f64 = 10.0; +pub const SHIP_NAVIGATION_TIME: u64 = 3; +pub const SHIP_NAVIGATION_RANGE: f64 = 100.0; +pub const SHIP_REFINERY_TIME: u64 = 5; +pub const SHIP_TRACTORBEAM_STRENGTH: f64 = 0.1; + +pub const IRON_SIZE: usize = 1; +pub const CRUDE_MINERALS_SIZE: usize = 10; + +pub const SLEEP_DURATION: u64 = 100; diff --git a/src/item.rs b/src/item.rs index c51b1a2..0d655e4 100644 --- a/src/item.rs +++ b/src/item.rs @@ -1,18 +1,29 @@ +use crate::constants; +use crate::math::rand_name; + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] +pub enum ItemType { + CrudeMinerals, + Iron, +} + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct Item { + pub itemtype: ItemType, pub name: String, pub size: usize, } impl Item { - pub fn new(name: &str, size: usize) -> Item { + pub fn new(itemtype: ItemType) -> Item { + let size = match itemtype { + ItemType::CrudeMinerals => constants::CRUDE_MINERALS_SIZE, + ItemType::Iron => constants::IRON_SIZE, + }; Item { - name: String::from(name), + name: serde_json::to_string(&itemtype).unwrap() + &rand_name(), + itemtype, size, } } - - pub fn is_mineral(&self) -> bool { - self.name == "Mineral" - } } diff --git a/src/lib.rs b/src/lib.rs index 406bab9..2b76cc6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,6 +2,7 @@ extern crate serde_derive; pub mod client; +pub mod constants; pub mod item; pub mod mass; pub mod math; diff --git a/src/mass.rs b/src/mass.rs index 14b0c83..0c19bad 100644 --- a/src/mass.rs +++ b/src/mass.rs @@ -3,7 +3,8 @@ extern crate rand; use self::rand::distributions::Uniform; use self::rand::Rng; -use crate::item::Item; +use crate::constants; +use crate::item::{Item, ItemType}; use crate::math::Vector; use crate::modules::construction::Construction; use crate::modules::dashboard::Dashboard; @@ -73,16 +74,22 @@ impl Mass { pub fn new_astroid() -> Mass { let mut rng = rand::thread_rng(); - let p_range = Uniform::new(-50.0, 50.0); - let v_range = Uniform::new(-0.5, 0.5); + let p_range = Uniform::new( + constants::ASTROID_STARTING_POSITION_MAX * -1.0, + constants::ASTROID_STARTING_POSITION_MAX, + ); + let v_range = Uniform::new( + constants::ASTROID_STARTING_VELOCITY_MAX * -1.0, + constants::ASTROID_STARTING_VELOCITY_MAX, + ); let mut resources = Vec::new(); - for _ in 0..rng.gen_range(0, 20) { - resources.push(Item::new("Mineral", 1)); + for _ in 0..rng.gen_range(0, constants::ASTROID_STARTING_MINERALS_MAX) { + resources.push(Item::new(ItemType::CrudeMinerals)); } let astroid = MassType::Astroid { - resources: Storage::new(resources), + resources: Storage::new(resources, constants::ASTROID_STORAGE_CAPACITY), }; Mass { @@ -110,7 +117,7 @@ impl Mass { navigation: Some(Navigation::new()), tractorbeam: Some(Tractorbeam::new()), construction: Some(Construction::new()), - storage: Storage::new(Vec::new()), + storage: Storage::new(Vec::new(), constants::SHIP_STORAGE_CAPACITY), }; Mass { @@ -174,43 +181,4 @@ impl Mass { self.velocity += self.effects.take_acceleration(); self.position += self.velocity.clone(); } - - pub fn has_minerals(&self) -> bool { - match self.mass_type { - MassType::Ship { ref storage, .. } => storage.has_minerals(), - MassType::Astroid { ref resources, .. } => resources.has_minerals(), - _ => false, - } - } - - pub fn refined_count(&self) -> usize { - match self.mass_type { - MassType::Ship { ref storage, .. } => storage.refined_count(), - _ => 0, - } - } - - pub fn take(&mut self, name: &str) -> Option { - match self.mass_type { - MassType::Ship { - ref mut storage, .. - } => storage.take(name), - MassType::Astroid { - ref mut resources, .. - } => resources.take(name), - _ => None, - } - } - - pub fn give(&mut self, item: Item) -> bool { - match self.mass_type { - MassType::Ship { - ref mut storage, .. - } => storage.give(item), - MassType::Astroid { - ref mut resources, .. - } => resources.give(item), - _ => false, - } - } } diff --git a/src/modules/construction.rs b/src/modules/construction.rs index f55a2fb..20f1688 100644 --- a/src/modules/construction.rs +++ b/src/modules/construction.rs @@ -1,6 +1,8 @@ -use crate::modules::types::ModuleType; use std::time::SystemTime; +use crate::constants; +use crate::modules::types::ModuleType; + #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub enum ConstructionStatus { None, @@ -27,7 +29,7 @@ impl Construction { Construction { status: ConstructionStatus::None, construction: None, - time: 5, + time: constants::SHIP_CONSTRUCTION_TIME, start: None, } } @@ -58,7 +60,7 @@ impl Construction { self.status = ConstructionStatus::None; } - pub fn take(&mut self) { + pub fn taken(&mut self) { self.off() } } diff --git a/src/modules/engines.rs b/src/modules/engines.rs index f319ee5..55b9af9 100644 --- a/src/modules/engines.rs +++ b/src/modules/engines.rs @@ -19,7 +19,13 @@ impl Engines { acceleration } - pub fn give_client_data(&mut self, ship: &Mass, target: Option<&Mass>, data: String) { + pub fn give_client_data( + &mut self, + position: Vector, + velocity: Vector, + target: Option<&Mass>, + data: String, + ) { let mut acceleration = Vector::default(); match data.as_bytes() { b"5\n" => acceleration.a += 0.1, @@ -28,21 +34,21 @@ impl Engines { b"2\n" => acceleration.b -= 0.1, b"4\n" => acceleration.c += 0.1, b"6\n" => acceleration.c -= 0.1, - b"+\n" => acceleration = ship.velocity.clone() * 0.05, + b"+\n" => acceleration = velocity * 0.05, b"-\n" => { - acceleration = ship.velocity.clone() * -1.05; + acceleration = velocity * -1.05; } b"s\n" => { - acceleration = ship.velocity.clone() * -1.0; + acceleration = velocity * -1.0; } b"c\n" => { if let Some(target) = target { - acceleration = target.velocity.clone() - ship.velocity.clone(); + acceleration = target.velocity.clone() - velocity; } } b"t\n" => { if let Some(target) = target { - acceleration = (target.position.clone() - ship.position.clone()) * 0.01; + acceleration = (target.position.clone() - position) * 0.01; } } _ => (), diff --git a/src/modules/mining.rs b/src/modules/mining.rs index b923480..1295593 100644 --- a/src/modules/mining.rs +++ b/src/modules/mining.rs @@ -1,5 +1,7 @@ use std::time::SystemTime; +use crate::constants; + #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub enum MiningStatus { None, @@ -24,9 +26,9 @@ pub struct Mining { impl Mining { pub fn new() -> Mining { Mining { - range: 10.0, + range: constants::SHIP_MINING_RANGE, status: MiningStatus::None, - time: 5, + time: constants::SHIP_MINING_TIME, start: None, } } @@ -57,7 +59,7 @@ impl Mining { self.status = MiningStatus::None; } - pub fn take(&mut self) { + pub fn taken(&mut self) { self.status = MiningStatus::Mining; } } diff --git a/src/modules/navigation.rs b/src/modules/navigation.rs index 03a9ca5..0e855f8 100644 --- a/src/modules/navigation.rs +++ b/src/modules/navigation.rs @@ -1,6 +1,7 @@ use std::collections::HashMap; use std::time::SystemTime; +use crate::constants; use crate::mass::Mass; use crate::math::Vector; @@ -30,9 +31,9 @@ impl Navigation { pub fn new() -> Navigation { Navigation { target_name: None, - range: 100.0, + range: constants::SHIP_NAVIGATION_RANGE, status: NavigationStatus::None, - time: 3, + time: constants::SHIP_NAVIGATION_TIME, start: None, } } diff --git a/src/modules/refinery.rs b/src/modules/refinery.rs index 5fdc10c..5760306 100644 --- a/src/modules/refinery.rs +++ b/src/modules/refinery.rs @@ -1,5 +1,7 @@ use std::time::SystemTime; +use crate::constants; + #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub enum RefineryStatus { None, @@ -23,7 +25,7 @@ pub struct Refinery { impl Refinery { pub fn new() -> Refinery { Refinery { - time: 5, + time: constants::SHIP_REFINERY_TIME, start: None, status: RefineryStatus::None, } @@ -55,7 +57,7 @@ impl Refinery { self.status = RefineryStatus::None; } - pub fn take(&mut self) { + pub fn taken(&mut self) { self.status = RefineryStatus::Refining; } } diff --git a/src/modules/tractorbeam.rs b/src/modules/tractorbeam.rs index 1ddc7d0..445b066 100644 --- a/src/modules/tractorbeam.rs +++ b/src/modules/tractorbeam.rs @@ -1,3 +1,4 @@ +use crate::constants; use crate::mass::Mass; use crate::math::Vector; @@ -26,7 +27,7 @@ impl Tractorbeam { pub fn new() -> Tractorbeam { Tractorbeam { status: TractorbeamStatus::None, - strength: 0.1, + strength: constants::SHIP_TRACTORBEAM_STRENGTH, desired_distance: None, } } @@ -63,14 +64,14 @@ impl Tractorbeam { self.status = TractorbeamStatus::None; } - pub fn get_acceleration(&self, ship: Mass, target: Mass) -> Vector { - let acceleration = ship.position.clone() - target.position.clone(); + 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 > ship.position.distance_from(target.position) { + if desired_distance > position.distance_from(target.position) { acceleration.unitize() * -0.05 //some sort of velocity limiter //if target.speed_torwards(ship) < 10.0 { diff --git a/src/server/construction.rs b/src/server/construction.rs index 70038ae..9c700ae 100644 --- a/src/server/construction.rs +++ b/src/server/construction.rs @@ -4,58 +4,52 @@ use std::collections::HashMap; use std::io::BufRead; use std::io::Write; +use crate::constants; +use crate::item::ItemType; use crate::mass::{Mass, MassType}; use crate::modules::construction::Construction; use crate::modules::construction::ConstructionStatus; use crate::modules::types::ModuleType; use crate::server::connection::ServerConnection; +use crate::storage::Storage; #[derive(Serialize, Deserialize, Debug, Clone)] pub struct ConstructionData { pub status: ConstructionStatus, - pub has_refined: bool, + pub has_enough: bool, } impl ServerConnection { pub fn server_construction(&mut self, masses: &mut HashMap) { let mut ship = masses.remove(&self.name).unwrap(); - let ship_clone = ship.clone(); - let mut construct = false; if let MassType::Ship { ref mut construction, + ref mut storage, .. } = ship.mass_type { let construction = construction.as_mut().unwrap(); - let construction_data = get_construction_data(ship_clone.clone(), construction); + let construction_data = get_construction_data(storage, construction); if self.open && self.txrx_construction(&construction_data) { construction.toggle(); } if construction_data.status == ConstructionStatus::Constructed { - construction.take(); + storage.take_items(ItemType::Iron, constants::SHIP_CONSTRUCTION_IRON_COST); masses.insert( "Station".to_string(), Mass::new_station( ModuleType::Refinery, - ship_clone.position, - ship_clone.velocity, + ship.position.clone(), + ship.velocity.clone(), ), ); - construct = true; + construction.taken(); } } - if construct { - ship.take("Refined Mineral"); - ship.take("Refined Mineral"); - ship.take("Refined Mineral"); - ship.take("Refined Mineral"); - ship.take("Refined Mineral"); - } - masses.insert(self.name.clone(), ship); } @@ -69,7 +63,7 @@ impl ServerConnection { if let Ok(result) = self.buff_r.read_line(&mut recv) { match recv.as_bytes() { b"c\n" => { - if construction_data.has_refined { + if construction_data.has_enough { return true; } } @@ -85,11 +79,14 @@ impl ServerConnection { } } -fn get_construction_data(ship: Mass, construction: &Construction) -> ConstructionData { - let has_refined = ship.refined_count() >= 5; - +fn get_construction_data(storage: &Storage, construction: &Construction) -> ConstructionData { ConstructionData { status: construction.status.clone(), - has_refined, + has_enough: storage + .items + .iter() + .filter(|item| item.itemtype == ItemType::Iron) + .count() + >= constants::SHIP_CONSTRUCTION_IRON_COST, } } diff --git a/src/server/engines.rs b/src/server/engines.rs index 559ecd9..f3e68f0 100644 --- a/src/server/engines.rs +++ b/src/server/engines.rs @@ -12,7 +12,6 @@ impl ServerConnection { pub fn server_engines(&mut self, masses: &mut HashMap) { if self.open { let mut ship = masses.remove(&self.name).unwrap(); - let ship_clone = ship.clone(); if let MassType::Ship { ref mut engines, @@ -36,7 +35,12 @@ impl ServerConnection { let mut recv = String::new(); if let Ok(result) = self.buff_r.read_line(&mut recv) { - engines.give_client_data(&ship_clone, target, recv); + engines.give_client_data( + ship.position.clone(), + ship.velocity.clone(), + target, + recv, + ); if result == 0 { self.open = false; } diff --git a/src/server/mining.rs b/src/server/mining.rs index f6ddb41..4c1d3f6 100644 --- a/src/server/mining.rs +++ b/src/server/mining.rs @@ -4,7 +4,9 @@ use std::collections::HashMap; use std::io::BufRead; use std::io::Write; +use crate::item::ItemType; use crate::mass::{Mass, MassType}; +use crate::math::Vector; use crate::modules::mining::{Mining, MiningStatus}; use crate::modules::navigation::Navigation; use crate::server::connection::ServerConnection; @@ -21,18 +23,17 @@ pub struct MiningData { impl ServerConnection { pub fn server_mining(&mut self, masses: &mut HashMap) { let mut ship = masses.remove(&self.name).unwrap(); - let ship_clone = ship.clone(); - let mut item = None; if let MassType::Ship { ref mut mining, + ref mut storage, ref navigation, .. } = ship.mass_type { let mining = mining.as_mut().unwrap(); let navigation = navigation.as_ref().unwrap(); - let mining_data = get_mining_data(ship_clone, mining, navigation, masses); + let mining_data = get_mining_data(ship.position.clone(), mining, navigation, masses); if self.open && self.txrx_mining(&mining_data) { mining.toggle(); @@ -41,19 +42,28 @@ impl ServerConnection { if !mining_data.is_within_range { mining.off(); } else if mining.status == MiningStatus::Mined { - mining.take(); if let Some(name) = navigation.target_name.clone() { let target = masses.get_mut(&name).unwrap(); - item = target.take("Mineral"); + 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(), + ship.position.clone(), + ship.velocity.clone(), + ); + masses.insert(item.name.clone(), mass); + } + } + None => mining.off(), + } + } } - } - } - - if let Some(item) = item { - if !ship.give(item.clone()) { - let mass = - Mass::new_item(item.clone(), ship.position.clone(), ship.velocity.clone()); - masses.insert(item.name.clone(), mass); + mining.taken(); } } @@ -86,7 +96,7 @@ impl ServerConnection { } fn get_mining_data( - ship: Mass, + position: Vector, mining: &Mining, navigation: &Navigation, masses: &mut HashMap, @@ -97,21 +107,22 @@ fn get_mining_data( let mut astroid_has_minerals = false; let has_astroid_target = match target { - Some(target) => { - astroid_has_minerals = target.has_minerals(); - match target.mass_type { - MassType::Astroid { .. } => true, - _ => false, + Some(target) => match target.mass_type { + MassType::Astroid { ref resources, .. } => { + astroid_has_minerals = resources + .items + .iter() + .any(|item| item.itemtype == ItemType::CrudeMinerals); + true } - } + _ => false, + }, None => false, }; let is_within_range = if has_astroid_target { match target { - Some(target) => { - mining.range > ship.position.distance_from(target.position.clone()) - } + Some(target) => mining.range > position.distance_from(target.position.clone()), _ => false, } } else { diff --git a/src/server/navigation.rs b/src/server/navigation.rs index 5143667..8fc7731 100644 --- a/src/server/navigation.rs +++ b/src/server/navigation.rs @@ -17,7 +17,7 @@ impl ServerConnection { } = ship.mass_type { let navigation = navigation.as_mut().unwrap(); - navigation.verify_target(ship_clone.position.clone(), &masses); + navigation.verify_target(ship.position.clone(), &masses); let mut within_range: HashMap<&String, &Mass> = masses .iter() .filter(|&(_, mass)| { diff --git a/src/server/refinery.rs b/src/server/refinery.rs index d4eb26b..7cec23e 100644 --- a/src/server/refinery.rs +++ b/src/server/refinery.rs @@ -4,31 +4,34 @@ use std::collections::HashMap; use std::io::BufRead; use std::io::Write; -use crate::item::Item; +use crate::item::{Item, ItemType}; use crate::mass::{Mass, MassType}; use crate::modules::refinery::RefineryStatus; use crate::server::connection::ServerConnection; #[derive(Serialize, Deserialize, Debug, Clone)] pub struct RefineryData { - pub has_minerals: bool, + pub has_crude_minerals: bool, pub status: RefineryStatus, } impl ServerConnection { pub fn server_refinery(&mut self, masses: &mut HashMap) { let mut ship = masses.remove(&self.name).unwrap(); - let ship_clone = ship.clone(); - let mut refine = false; if let MassType::Ship { - ref mut refinery, .. + ref mut refinery, + ref mut storage, + .. } = ship.mass_type { let refinery = refinery.as_mut().unwrap(); let refinery_data = RefineryData { - has_minerals: ship_clone.has_minerals(), + has_crude_minerals: storage + .items + .iter() + .any(|item| item.itemtype == ItemType::CrudeMinerals), status: refinery.status.clone(), }; @@ -36,21 +39,17 @@ impl ServerConnection { refinery.toggle(); } - if !refinery_data.has_minerals { + if !refinery_data.has_crude_minerals { refinery.off(); } if refinery.status == RefineryStatus::Refined { - refinery.take(); - refine = true; + storage.take_item(ItemType::CrudeMinerals); + storage.give_item(Item::new(ItemType::Iron)); + refinery.taken(); } } - if refine { - ship.take("Mineral"); - ship.give(Item::new("Refined Mineral", 1)); - } - masses.insert(self.name.clone(), ship); } @@ -64,7 +63,7 @@ impl ServerConnection { if let Ok(result) = self.buff_r.read_line(&mut recv) { match recv.as_bytes() { b"R\n" => { - if refinery_data.has_minerals { + if refinery_data.has_crude_minerals { return true; } } diff --git a/src/server/tractorbeam.rs b/src/server/tractorbeam.rs index 250f5fb..fc76b7c 100644 --- a/src/server/tractorbeam.rs +++ b/src/server/tractorbeam.rs @@ -18,7 +18,6 @@ pub struct TractorbeamData { impl ServerConnection { pub fn server_tractorbeam(&mut self, masses: &mut HashMap) { let mut ship = masses.remove(&self.name).unwrap(); - let ship_clone = ship.clone(); if let MassType::Ship { ref mut tractorbeam, @@ -58,7 +57,8 @@ impl ServerConnection { if let Some(name) = navigation.target_name.clone() { let target = masses.get_mut(&name).unwrap(); - let acceleration = tractorbeam.get_acceleration(ship_clone, target.clone()); + let acceleration = + tractorbeam.get_acceleration(ship.position.clone(), target.clone()); target.effects.give_acceleration(acceleration); } else { tractorbeam.off(); diff --git a/src/storage.rs b/src/storage.rs index f43bec4..b9ca287 100644 --- a/src/storage.rs +++ b/src/storage.rs @@ -1,37 +1,27 @@ -use crate::item::Item; +use crate::item::{Item, ItemType}; #[derive(Serialize, Deserialize, Debug, Clone)] pub struct Storage { - items: Vec, + pub items: Vec, carrying: usize, capacity: usize, } impl Storage { - pub fn new(items: Vec) -> Storage { + pub fn new(items: Vec, capacity: usize) -> Storage { let mut carrying = 0; for item in items.iter() { carrying += item.size; } Storage { items, - capacity: 10, + capacity, carrying, } } - pub fn has_minerals(&self) -> bool { - self.items.iter().any(|item| item.is_mineral()) - } - - pub fn refined_count(&self) -> usize { - let mut items = self.items.clone(); - items.retain(|item| item.name == "Refined Mineral"); - items.len() - } - - pub fn take(&mut self, name: &str) -> Option { - match self.items.iter().position(|item| item.name == name) { + pub fn take_item(&mut self, itemtype: ItemType) -> Option { + match self.items.iter().position(|item| item.itemtype == itemtype) { Some(index) => { let item = self.items.remove(index); self.carrying -= item.size; @@ -41,7 +31,32 @@ impl Storage { } } - pub fn give(&mut self, item: Item) -> bool { + pub fn take_items(&mut self, itemtype: ItemType, count: usize) -> Option> { + if self + .items + .iter() + .filter(|item| item.itemtype == itemtype) + .count() + >= count + { + let mut items = Vec::new(); + for _ in 0..count { + let index = self + .items + .iter() + .position(|item| item.itemtype == itemtype) + .unwrap(); + let item = self.items.remove(index); + self.carrying -= item.size; + items.push(item); + } + Some(items) + } else { + None + } + } + + pub fn give_item(&mut self, item: Item) -> bool { if self.capacity >= self.carrying + item.size { self.carrying += item.size; self.items.push(item); -- cgit v1.2.3