diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/astroid.rs | 26 | ||||
-rw-r--r-- | src/bin/client.rs | 4 | ||||
-rw-r--r-- | src/connection.rs | 3 | ||||
-rw-r--r-- | src/engines.rs | 18 | ||||
-rw-r--r-- | src/item.rs | 14 | ||||
-rw-r--r-- | src/lib.rs | 3 | ||||
-rw-r--r-- | src/mass.rs | 3 | ||||
-rw-r--r-- | src/mining.rs | 124 | ||||
-rw-r--r-- | src/module.rs | 1 | ||||
-rw-r--r-- | src/navigation.rs | 6 | ||||
-rw-r--r-- | src/ship.rs | 96 | ||||
-rw-r--r-- | src/storage.rs | 16 | ||||
-rw-r--r-- | src/targeting.rs | 14 |
13 files changed, 283 insertions, 45 deletions
diff --git a/src/astroid.rs b/src/astroid.rs index 5b2a3b3..ef1d401 100644 --- a/src/astroid.rs +++ b/src/astroid.rs @@ -4,15 +4,18 @@ use astroid::rand::distributions::Sample; extern crate rand; extern crate serde_json; -use mass::{Mass, Type}; +use storage::Storage; use astroid::rand::Rng; +use mass::{Mass, MassType}; +use item::Item; #[derive(Serialize, Deserialize, Debug, Clone)] pub struct Astroid { name : String, - mass_type : Type, + mass_type : MassType, position : (f64, f64, f64), velocity : (f64, f64, f64), + resouces : Storage, } impl Astroid { @@ -21,16 +24,25 @@ impl Astroid { .gen_ascii_chars() .take(8) .collect(); - let mut pr = Range::new(-50.0, 50.0); - let mut vr = Range::new(-0.5, 0.5); let mut rng = rand::thread_rng(); + + let mut pr = Range::new(-50.0, 50.0); let position = (pr.sample(&mut rng), pr.sample(&mut rng), pr.sample(&mut rng)); + + let mut vr = Range::new(-0.5, 0.5); let velocity = (vr.sample(&mut rng), vr.sample(&mut rng), vr.sample(&mut rng)); + + let mut rr = Range::new(0, 20); + let mut resouces = Vec::new(); + for _ in 0..rr.sample(&mut rng) { + resouces.push(Item::new("Iron", 1)) + } Astroid { name : name, - mass_type : Type::Astroid, + mass_type : MassType::Astroid, position : position, velocity : velocity, + resouces : Storage::new(resouces), } } } @@ -40,6 +52,10 @@ impl Mass for Astroid { &self.name } + fn recv_mass_type(&self) -> MassType { + self.mass_type.clone() + } + fn position(&self) -> (f64, f64, f64) { self.position } diff --git a/src/bin/client.rs b/src/bin/client.rs index 1c64b39..7eb89ae 100644 --- a/src/bin/client.rs +++ b/src/bin/client.rs @@ -6,8 +6,9 @@ use std::net::TcpStream; extern crate serde_json; extern crate space; -use space::dashboard::client_dashboard; +use space::mining::client_mining; use space::engines::client_engines; +use space::dashboard::client_dashboard; use space::navigation::client_navigation; use space::module::Module; @@ -48,5 +49,6 @@ fn main() { Module::Dashboard => client_dashboard(buff_r), Module::Engines => client_engines(stream, buff_r), Module::Navigation => client_navigation(name, stream, buff_r), + Module::Mining => client_mining(stream, buff_r), } } diff --git a/src/connection.rs b/src/connection.rs index 77afc06..081805b 100644 --- a/src/connection.rs +++ b/src/connection.rs @@ -32,7 +32,7 @@ impl Connection { let mass = masses.iter().find(|ship| ship.name() == name).unwrap(); let ship = mass.downcast_ref::<Ship>().unwrap(); - let modules = ship.get_modules(); + let modules = ship.recv_modules(); stream.write(modules.as_bytes()).unwrap(); let mut recv = String::new(); @@ -55,6 +55,7 @@ impl Connection { Module::Engines => self.server_engines(&mut masses), Module::Dashboard => self.server_dashboard(&mut masses), Module::Navigation => self.server_navigation(&mut masses), + Module::Mining => self.server_mining(&mut masses), }; } } diff --git a/src/engines.rs b/src/engines.rs index 3966c1b..cba189e 100644 --- a/src/engines.rs +++ b/src/engines.rs @@ -7,9 +7,11 @@ use std::time::Duration; use std::io::{BufRead, BufReader}; extern crate termion; +extern crate serde_json; use ship::Ship; use mass::Mass; +use targeting::TargetingStatus; use connection::Connection; pub fn client_engines(mut stream : TcpStream, mut buff_r : BufReader<TcpStream>) { @@ -20,11 +22,7 @@ pub fn client_engines(mut stream : TcpStream, mut buff_r : BufReader<TcpStream>) loop { let mut recv = String::new(); buff_r.read_line(&mut recv).unwrap(); - - let has_target = match recv.as_bytes() { - b"true\n" => true, - _ => false - }; + let has_target = serde_json::from_str(&recv.replace("\n", "")).unwrap(); write!(stdout, "{}{}use numpad to freely move\n", termion::clear::All, termion::cursor::Goto(1, 1)).unwrap(); write!(stdout, "{}+ : speedup", termion::cursor::Goto(1, 2)).unwrap(); @@ -61,11 +59,9 @@ impl Connection { let mass = masses.into_iter().find(|ship| ship.name() == &self.name).unwrap(); let ship = mass.downcast_mut::<Ship>().unwrap(); - let mut send = String::new(); - match ship.recv_target().is_some() { - true => send.push_str("true\n"), - false => send.push_str("false\n"), - } + let targeted = ship.recv_targeting_status() == TargetingStatus::Targeted; + let send = serde_json::to_string(&targeted).unwrap() + "\n"; + match self.stream.write(send.as_bytes()) { Ok(_result) => (), Err(_error) => return false, @@ -100,7 +96,7 @@ impl Connection { match ship.recv_target() { Some(name) => { let target = m.into_iter().find(|target| target.name() == &name).unwrap(); - let d_p = target.recv_velocity(); + let d_p = target.position(); let m_p = ship.position(); acceleration = ((d_p.0 - m_p.0) * 0.01, (d_p.1 - m_p.1) * 0.01, diff --git a/src/item.rs b/src/item.rs new file mode 100644 index 0000000..63e7b01 --- /dev/null +++ b/src/item.rs @@ -0,0 +1,14 @@ +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct Item { + name : String, + size : usize, +} + +impl Item { + pub fn new(name : &str, size : usize) -> Item { + Item { + name : String::from(name), + size : size, + } + } +} @@ -7,9 +7,12 @@ extern crate termion; extern crate time; pub mod mass; +pub mod item; pub mod ship; pub mod math; pub mod module; +pub mod mining; +pub mod storage; pub mod astroid; pub mod engines; pub mod dashboard; diff --git a/src/mass.rs b/src/mass.rs index 800ef58..186391b 100644 --- a/src/mass.rs +++ b/src/mass.rs @@ -2,6 +2,7 @@ use downcast::Any; pub trait Mass : Any { fn name(&self) -> &String; + fn recv_mass_type(&self) -> MassType; fn position(&self) -> (f64, f64, f64); fn serialize(&self) -> String; fn process(&mut self); @@ -17,7 +18,7 @@ impl Clone for Box<Mass> { } #[derive(Serialize, Deserialize, Debug, Clone)] -pub enum Type { +pub enum MassType { Ship, Astroid, } diff --git a/src/mining.rs b/src/mining.rs new file mode 100644 index 0000000..ecc83c5 --- /dev/null +++ b/src/mining.rs @@ -0,0 +1,124 @@ +use std::io::{BufReader, BufRead}; +use std::net::TcpStream; +use std::io::{stdout, Read, Write}; +use termion::raw::IntoRawMode; +use termion::async_stdin; + +extern crate serde_json; +extern crate termion; + +use ship::Ship; +use math::distance; +use mass::{Mass, MassType}; +use connection::Connection; + +#[derive(Serialize, Deserialize, Debug, Clone)] +struct ServerData { + has_astroid_target : bool, + is_within_range : bool, + mining_range : f64, + mining_status : bool, +} + +pub fn client_mining(mut stream : TcpStream, mut buff_r : BufReader<TcpStream>) { + let stdout = stdout(); + let mut stdout = stdout.lock().into_raw_mode().unwrap(); + let mut stdin = async_stdin().bytes(); + + loop { + let mut recv = String::new(); + buff_r.read_line(&mut recv).unwrap(); + let data : ServerData = serde_json::from_str(&recv.replace("\n", "")).unwrap(); + + write!(stdout, "{}", termion::clear::All).unwrap(); + + match data.has_astroid_target { + true => match data.is_within_range { + true => write!(stdout, "{}Press F to begin mining.", termion::cursor::Goto(1,1)).unwrap(), + false => write!(stdout, "{}Astroid must be within range of {}.", termion::cursor::Goto(1,1), data.mining_range).unwrap(), + }, + false => write!(stdout, "{}Ship has no astroid targeted.", termion::cursor::Goto(1,1)).unwrap(), + } + + match stdin.next() { + Some(c) => { + let c = c.unwrap(); + let mut send = String::new(); + send.push(c as char); + if send.as_bytes() == b"q" { + break; + } + send.push_str("\n"); + stream.write(send.as_bytes()).unwrap(); + } + None => () + } + + stdout.flush().unwrap(); + } +} + +impl Connection { + pub fn server_mining(&mut self, masses : &mut Vec<Box<Mass>>) -> bool { + let m = masses.to_vec(); + let mass = masses.into_iter().find(|ship| ship.name() == &self.name).unwrap(); + let ship = mass.downcast_mut::<Ship>().unwrap(); + let target = match ship.recv_target() { + Some(name) => m.iter().find(|target| target.name() == &name), + None => None, + }; + + let has_astroid_target = match target { + Some(target) => match target.recv_mass_type() { + MassType::Ship => false, + MassType::Astroid => true, + }, + None => false, + }; + + let is_within_range = match has_astroid_target { + true => match target { + Some(target) => match ship.recv_mining_range() > distance(ship.position(), target.position()) { + true => true, + false => false, + }, + None => false, + } + false => false, + }; + + let send = serde_json::to_string(&ServerData { + has_astroid_target : has_astroid_target, + is_within_range : is_within_range, + mining_range : ship.recv_mining_range(), + mining_status : ship.recv_mining_status(), + }).unwrap() + "\n"; + + match self.stream.write(send.as_bytes()) { + Ok(_result) => (), + Err(_error) => return false, + } + + let mut recv = String::new(); + match self.buff_r.read_line(&mut recv) { + Ok(result) => match recv.as_bytes() { + b"F\n" => { + if is_within_range { + match ship.recv_mining_status() { + true => ship.stop_mining(), + false => ship.start_mining(), + } + } + }, + _ => { + if result == 0 { + return false + } + }, + } + Err(_error) => (), + } + + true + } +} diff --git a/src/module.rs b/src/module.rs index b051e60..8d9a361 100644 --- a/src/module.rs +++ b/src/module.rs @@ -3,4 +3,5 @@ pub enum Module { Dashboard, Navigation, Engines, + Mining, } diff --git a/src/navigation.rs b/src/navigation.rs index f9fa92a..b15103e 100644 --- a/src/navigation.rs +++ b/src/navigation.rs @@ -43,7 +43,7 @@ pub fn client_navigation(name : String, mut stream : TcpStream, mut buff_r : Buf let target_data = match ship.recv_target() { Some(name) => { if &name == mass.name() { - serde_json::to_string(&ship.recv_target_status()).unwrap() + serde_json::to_string(&ship.recv_targeting_status()).unwrap() } else { String::new() @@ -100,7 +100,7 @@ impl Connection { match ship.recv_target() { Some(name) => { let target = m.iter().find(|target| target.name() == &name).unwrap(); - if distance(target.position(), ship.position()) > ship.range() { + if distance(target.position(), ship.position()) > ship.recv_range() { ship.give_target(None); } } @@ -108,7 +108,7 @@ impl Connection { } let within_range : Vec<&Box<Mass>> = m.iter().filter(|mass| - distance(ship.position(), mass.position()) < ship.range()) + distance(ship.position(), mass.position()) < ship.recv_range()) .collect(); let mut send = String::new(); for mass in within_range { diff --git a/src/ship.rs b/src/ship.rs index 44f7d06..cfe913e 100644 --- a/src/ship.rs +++ b/src/ship.rs @@ -1,18 +1,23 @@ +use std::time::SystemTime; + extern crate serde_json; use module::Module; -use mass::{Mass, Type}; +use mass::{Mass, MassType}; use targeting::{Targeting, TargetingStatus}; +use storage::Storage; #[derive(Serialize, Deserialize, Debug, Clone)] pub struct Ship { name : String, + mass_type : MassType, position : (f64, f64, f64), velocity : (f64, f64, f64), - mass_type : Type, - r : f64, + range : f64, modules : Vec<Module>, targeting : Targeting, + mining : Mining, + storage : Storage, } impl Ship { @@ -22,15 +27,18 @@ impl Ship { modules.push(Module::Navigation); modules.push(Module::Engines); modules.push(Module::Dashboard); + modules.push(Module::Mining); Ship { - name : String::from(name), - position : position, - velocity : (0.0, 0.0, 0.0), - mass_type : Type::Ship, - r : 100.0, - targeting : Targeting::new(), - modules : modules, + name : String::from(name), + mass_type : MassType::Ship, + position : position, + velocity : (0.0, 0.0, 0.0), + range : 100.0, + modules : modules, + targeting : Targeting::new(), + mining : Mining::new(), + storage : Storage::new(Vec::new()), } } @@ -63,8 +71,24 @@ impl Ship { self.velocity.2 *= 1.05; } - pub fn range(&self) -> f64 { - self.r + pub fn start_mining(&mut self) { + self.mining.start() + } + + pub fn stop_mining(&mut self) { + self.mining.stop() + } + + pub fn recv_range(&self) -> f64 { + self.range + } + + pub fn recv_mining_range(&self) -> f64 { + self.mining.recv_range() + } + + pub fn recv_mining_status(&self) -> bool { + self.mining.recv_status() } pub fn give_target(&mut self, target : Option<String>) { @@ -72,14 +96,14 @@ impl Ship { } pub fn recv_target(&self) -> Option<String> { - self.targeting.get_target() + self.targeting.recv_target() } - pub fn recv_target_status(&self) -> TargetingStatus { - self.targeting.get_status() + pub fn recv_targeting_status(&self) -> TargetingStatus { + self.targeting.recv_status() } - pub fn get_modules(&self) -> String { + pub fn recv_modules(&self) -> String { serde_json::to_string(&self.modules).unwrap() + "\n" } } @@ -89,6 +113,10 @@ impl Mass for Ship { &self.name } + fn recv_mass_type(&self) -> MassType { + self.mass_type.clone() + } + fn process(&mut self) { self.position.0 += self.velocity.0; self.position.1 += self.velocity.1; @@ -118,3 +146,39 @@ impl Mass for Ship { self.velocity.2 += acceleration.2; } } + + +#[derive(Serialize, Deserialize, Debug, Clone)] +struct Mining { + range : f64, + status : bool, + time : u64, + start : Option<SystemTime>, +} + +impl Mining { + pub fn new() -> Mining { + Mining { + range : 10.0, + status : false, + time : 1, + start : None, + } + } + + pub fn start(&mut self) { + self.status = true; + } + + pub fn stop(&mut self) { + self.status = false; + } + + pub fn recv_range(&self) -> f64 { + self.range + } + + pub fn recv_status(&self) -> bool { + self.status + } +} diff --git a/src/storage.rs b/src/storage.rs new file mode 100644 index 0000000..00dca8b --- /dev/null +++ b/src/storage.rs @@ -0,0 +1,16 @@ +use item::Item; + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct Storage { + items : Vec<Item>, + capacity : usize, +} + +impl Storage { + pub fn new(items : Vec<Item>) -> Storage { + Storage { + items : items, + capacity : 100, + } + } +} diff --git a/src/targeting.rs b/src/targeting.rs index 754e7a4..49fdc54 100644 --- a/src/targeting.rs +++ b/src/targeting.rs @@ -1,6 +1,6 @@ use std::time::SystemTime; -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub enum TargetingStatus { None, Targeting, @@ -28,10 +28,10 @@ impl Targeting { pub fn process(&mut self) { match self.start { Some(time) => { - if time.elapsed().unwrap().as_secs() > self.time { - self.status = TargetingStatus::Targeted; - self.start = None; - } + if time.elapsed().unwrap().as_secs() > self.time { + self.status = TargetingStatus::Targeted; + self.start = None; + } } None => (), } @@ -50,11 +50,11 @@ impl Targeting { } } - pub fn get_target(&self) -> Option<String> { + pub fn recv_target(&self) -> Option<String> { self.target.clone() } - pub fn get_status(&self) -> TargetingStatus { + pub fn recv_status(&self) -> TargetingStatus { self.status.clone() } } |