summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortom barrett <spalf0@gmail.com>2019-02-10 03:55:05 -0600
committertom barrett <spalf0@gmail.com>2019-02-10 03:55:05 -0600
commitf617213b4a48d73acd245580f8551a7c37ce9ad8 (patch)
tree46ab5a696d91d6405ff2d2875a57c403b94edfbd /src
parent46fa862e04bc43311ba79ef3db70abf9014b9104 (diff)
added vector math and tractorbeam module
Diffstat (limited to 'src')
-rw-r--r--src/bin/client.rs2
-rw-r--r--src/client/mod.rs1
-rw-r--r--src/client/navigation.rs11
-rw-r--r--src/client/tractorbeam.rs70
-rw-r--r--src/mass.rs87
-rw-r--r--src/math.rs91
-rw-r--r--src/modules/engines.rs52
-rw-r--r--src/modules/mod.rs1
-rw-r--r--src/modules/navigation.rs10
-rw-r--r--src/modules/tractorbeam.rs90
-rw-r--r--src/modules/types.rs1
-rw-r--r--src/server/connection.rs1
-rw-r--r--src/server/mining.rs8
-rw-r--r--src/server/mod.rs1
-rw-r--r--src/server/navigation.rs5
-rw-r--r--src/server/tractorbeam.rs70
16 files changed, 409 insertions, 92 deletions
diff --git a/src/bin/client.rs b/src/bin/client.rs
index e452492..ef5faff 100644
--- a/src/bin/client.rs
+++ b/src/bin/client.rs
@@ -17,6 +17,7 @@ use space::client::engines::client_engines;
use space::client::mining::client_mining;
use space::client::navigation::client_navigation;
use space::client::refinery::client_refinery;
+use space::client::tractorbeam::client_tractorbeam;
use space::modules::types::ModuleType;
#[derive(Debug, Deserialize)]
@@ -85,6 +86,7 @@ fn main() {
ModuleType::Engines => client_engines(stream, buff_r),
ModuleType::Refinery => client_refinery(stream, buff_r),
ModuleType::Navigation => client_navigation(name, stream, buff_r),
+ ModuleType::Tractorbeam => client_tractorbeam(stream, buff_r),
ModuleType::Construction => client_construction(stream, buff_r),
}
}
diff --git a/src/client/mod.rs b/src/client/mod.rs
index 530e2de..9045e90 100644
--- a/src/client/mod.rs
+++ b/src/client/mod.rs
@@ -4,3 +4,4 @@ pub mod engines;
pub mod mining;
pub mod navigation;
pub mod refinery;
+pub mod tractorbeam;
diff --git a/src/client/navigation.rs b/src/client/navigation.rs
index 0ab25c6..1f2ed06 100644
--- a/src/client/navigation.rs
+++ b/src/client/navigation.rs
@@ -9,7 +9,6 @@ use std::io::{BufRead, BufReader};
use std::net::TcpStream;
use crate::mass::{Mass, MassType};
-use crate::math::distance;
use crate::modules::navigation::Navigation;
pub fn client_navigation(name: String, mut stream: TcpStream, mut buff_r: BufReader<TcpStream>) {
@@ -38,14 +37,12 @@ pub fn client_navigation(name: String, mut stream: TcpStream, mut buff_r: BufRea
let target_data = get_target_status(&navigation, &mass_name);
write!(
stdout,
- "{}{}) {} ({:.2}, {:.2}, {:.2}) Distance : {:.2} {}",
+ "{}{}) {} {} Distance : {:.2} {}",
termion::cursor::Goto(1, 2 + i as u16),
i,
mass_name,
- mass.position.0,
- mass.position.1,
- mass.position.2,
- distance(mass.position, ship.position),
+ mass.position,
+ mass.position.distance_from(ship.position.clone()),
target_data
)
.unwrap();
@@ -79,6 +76,6 @@ fn get_target_status(navigation: &Navigation, mass_name: &str) -> String {
String::new()
}
}
- _ => String::new(),
+ None => String::new(),
}
}
diff --git a/src/client/tractorbeam.rs b/src/client/tractorbeam.rs
new file mode 100644
index 0000000..e9e60b2
--- /dev/null
+++ b/src/client/tractorbeam.rs
@@ -0,0 +1,70 @@
+extern crate serde_json;
+extern crate termion;
+
+use self::termion::async_stdin;
+use self::termion::raw::IntoRawMode;
+use std::io::{stdout, Read, Write};
+use std::io::{BufRead, BufReader};
+use std::net::TcpStream;
+
+use crate::modules::tractorbeam::TractorbeamStatus;
+use crate::server::tractorbeam::TractorbeamData;
+
+pub fn client_tractorbeam(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: TractorbeamData = serde_json::from_str(&recv.replace("\n", "")).unwrap();
+
+ write!(stdout, "{}", termion::clear::All).unwrap();
+
+ let clear = termion::cursor::Goto(1, 1);
+
+ if data.has_target {
+ match data.status {
+ TractorbeamStatus::None => write!(
+ stdout,
+ "{}Press o to pull, p to push, t to bring to 5m.",
+ clear
+ )
+ .unwrap(),
+ TractorbeamStatus::Push => write!(
+ stdout,
+ "{}Press o to pull, p to stop pushing, t to bring to 5m.",
+ clear
+ )
+ .unwrap(),
+ TractorbeamStatus::Pull => write!(
+ stdout,
+ "{}Press o to stop pulling, p to push, t to bring to 5m.",
+ clear
+ )
+ .unwrap(),
+ TractorbeamStatus::Bring => write!(
+ stdout,
+ "{}Press o to pulling, p to push, t to stop bringing to 5m.",
+ clear
+ )
+ .unwrap(),
+ };
+ } else {
+ write!(stdout, "{}You have no target.", clear).unwrap();
+ }
+
+ if let Some(c) = stdin.next() {
+ 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_all(send.as_bytes()).unwrap();
+ }
+ stdout.flush().unwrap();
+ }
+}
diff --git a/src/mass.rs b/src/mass.rs
index db97d49..14b0c83 100644
--- a/src/mass.rs
+++ b/src/mass.rs
@@ -4,20 +4,46 @@ use self::rand::distributions::Uniform;
use self::rand::Rng;
use crate::item::Item;
+use crate::math::Vector;
use crate::modules::construction::Construction;
use crate::modules::dashboard::Dashboard;
use crate::modules::engines::Engines;
use crate::modules::mining::Mining;
use crate::modules::navigation::Navigation;
use crate::modules::refinery::Refinery;
+use crate::modules::tractorbeam::Tractorbeam;
use crate::modules::types::ModuleType;
use crate::storage::Storage;
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Mass {
pub mass_type: MassType,
- pub position: (f64, f64, f64),
- pub velocity: (f64, f64, f64),
+ pub position: Vector,
+ pub velocity: Vector,
+ pub effects: Effects,
+}
+
+#[derive(Serialize, Deserialize, Debug, Clone, Default)]
+pub struct Effects {
+ acceleration: Vector,
+}
+
+impl Effects {
+ pub fn new() -> Effects {
+ Effects {
+ acceleration: Vector::default(),
+ }
+ }
+
+ pub fn give_acceleration(&mut self, acceleration: Vector) {
+ self.acceleration += acceleration;
+ }
+
+ pub fn take_acceleration(&mut self) -> Vector {
+ let acceleration = self.acceleration.clone();
+ self.acceleration = Vector::default();
+ acceleration
+ }
}
#[derive(Serialize, Deserialize, Debug, Clone)]
@@ -29,6 +55,7 @@ pub enum MassType {
refinery: Option<Refinery>,
dashboard: Option<Dashboard>,
navigation: Option<Navigation>,
+ tractorbeam: Option<Tractorbeam>,
construction: Option<Construction>,
},
Astroid {
@@ -47,18 +74,7 @@ impl Mass {
let mut rng = rand::thread_rng();
let p_range = Uniform::new(-50.0, 50.0);
- let position = (
- rng.sample(p_range),
- rng.sample(p_range),
- rng.sample(p_range),
- );
-
let v_range = Uniform::new(-0.5, 0.5);
- let velocity = (
- rng.sample(v_range),
- rng.sample(v_range),
- rng.sample(v_range),
- );
let mut resources = Vec::new();
for _ in 0..rng.gen_range(0, 20) {
@@ -71,8 +87,17 @@ impl Mass {
Mass {
mass_type: astroid,
- position,
- velocity,
+ position: Vector::new((
+ rng.sample(p_range),
+ rng.sample(p_range),
+ rng.sample(p_range),
+ )),
+ velocity: Vector::new((
+ rng.sample(v_range),
+ rng.sample(v_range),
+ rng.sample(v_range),
+ )),
+ effects: Effects::new(),
}
}
@@ -83,36 +108,36 @@ impl Mass {
refinery: Some(Refinery::new()),
dashboard: Some(Dashboard::new()),
navigation: Some(Navigation::new()),
+ tractorbeam: Some(Tractorbeam::new()),
construction: Some(Construction::new()),
storage: Storage::new(Vec::new()),
};
Mass {
mass_type: ship,
- position: (0.0, 0.0, 0.0),
- velocity: (0.0, 0.0, 0.0),
+ position: Vector::default(),
+ velocity: Vector::default(),
+ effects: Effects::new(),
}
}
- pub fn new_item(item: Item, position: (f64, f64, f64), velocity: (f64, f64, f64)) -> Mass {
+ pub fn new_item(item: Item, position: Vector, velocity: Vector) -> Mass {
Mass {
mass_type: MassType::Item { item },
position,
velocity,
+ effects: Effects::new(),
}
}
- pub fn new_station(
- module_type: ModuleType,
- position: (f64, f64, f64),
- velocity: (f64, f64, f64),
- ) -> Mass {
+ pub fn new_station(module_type: ModuleType, position: Vector, velocity: Vector) -> Mass {
let mass_type = MassType::Station { module_type };
Mass {
mass_type,
position,
velocity,
+ effects: Effects::new(),
}
}
@@ -123,12 +148,12 @@ impl Mass {
modules.push(ModuleType::Refinery);
modules.push(ModuleType::Dashboard);
modules.push(ModuleType::Navigation);
+ modules.push(ModuleType::Tractorbeam);
modules.push(ModuleType::Construction);
modules
}
pub fn process(&mut self) {
- let mut acceleration = (0.0, 0.0, 0.0);
if let MassType::Ship {
ref mut navigation,
ref mut engines,
@@ -142,18 +167,12 @@ impl Mass {
refinery.as_mut().unwrap().process();
navigation.as_mut().unwrap().process();
construction.as_mut().unwrap().process();
- acceleration = engines.as_mut().unwrap().recv_acceleration();
+ self.effects
+ .give_acceleration(engines.as_mut().unwrap().recv_acceleration())
}
- self.accelerate(acceleration);
- self.position.0 += self.velocity.0;
- self.position.1 += self.velocity.1;
- self.position.2 += self.velocity.2;
- }
- pub fn accelerate(&mut self, acceleration: (f64, f64, f64)) {
- self.velocity.0 += acceleration.0;
- self.velocity.1 += acceleration.1;
- self.velocity.2 += acceleration.2;
+ self.velocity += self.effects.take_acceleration();
+ self.position += self.velocity.clone();
}
pub fn has_minerals(&self) -> bool {
diff --git a/src/math.rs b/src/math.rs
index 689ee65..0816149 100644
--- a/src/math.rs
+++ b/src/math.rs
@@ -4,13 +4,96 @@ use self::rand::distributions::Alphanumeric;
use self::rand::Rng;
use std::iter::repeat;
-pub fn distance(l0: (f64, f64, f64), l1: (f64, f64, f64)) -> f64 {
- ((l1.0 - l0.0).powf(2.0) + (l1.1 - l0.1).powf(2.0) + (l1.2 - l0.2).powf(2.0)).sqrt()
-}
-
pub fn rand_name() -> String {
repeat(())
.map(|()| rand::thread_rng().sample(Alphanumeric))
.take(8)
.collect()
}
+
+#[derive(Serialize, Deserialize, Debug, Clone, Default)]
+pub struct Vector {
+ pub a: f64,
+ pub b: f64,
+ pub c: f64,
+}
+
+impl Vector {
+ pub fn new(v: (f64, f64, f64)) -> Vector {
+ Vector {
+ a: v.0,
+ b: v.1,
+ c: v.2,
+ }
+ }
+
+ pub fn distance_from(&self, other: Vector) -> f64 {
+ ((self.a - other.a).powf(2.0) + (self.b - other.b).powf(2.0) + (self.c - other.c).powf(2.0))
+ .sqrt()
+ }
+
+ pub fn unitize(&self) -> Vector {
+ let denominator = self.magnitude();
+ Vector {
+ a: self.a / denominator,
+ b: self.b / denominator,
+ c: self.c / denominator,
+ }
+ }
+
+ pub fn magnitude(&self) -> f64 {
+ (self.a.powf(2.0) + self.b.powf(2.0) + self.c.powf(2.0)).sqrt()
+ }
+}
+
+impl std::fmt::Display for Vector {
+ fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+ write!(f, "({:.2}, {:.2}, {:.2})", self.a, self.b, self.c)
+ }
+}
+
+impl std::ops::Add for Vector {
+ type Output = Vector;
+
+ fn add(self, other: Vector) -> Vector {
+ Vector {
+ a: self.a + other.a,
+ b: self.b + other.b,
+ c: self.c + other.c,
+ }
+ }
+}
+
+impl std::ops::Sub for Vector {
+ type Output = Vector;
+
+ fn sub(self, other: Vector) -> Vector {
+ Vector {
+ a: self.a - other.a,
+ b: self.b - other.b,
+ c: self.c - other.c,
+ }
+ }
+}
+
+impl std::ops::Mul<f64> for Vector {
+ type Output = Vector;
+
+ fn mul(self, other: f64) -> Vector {
+ Vector {
+ a: self.a * other,
+ b: self.b * other,
+ c: self.c * other,
+ }
+ }
+}
+
+impl std::ops::AddAssign for Vector {
+ fn add_assign(&mut self, other: Vector) {
+ *self = Vector {
+ a: self.a + other.a,
+ b: self.b + other.b,
+ c: self.c + other.c,
+ }
+ }
+}
diff --git a/src/modules/engines.rs b/src/modules/engines.rs
index a930847..f319ee5 100644
--- a/src/modules/engines.rs
+++ b/src/modules/engines.rs
@@ -1,64 +1,48 @@
use crate::mass::Mass;
+use crate::math::Vector;
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct Engines {
- acceleration: (f64, f64, f64),
+ acceleration: Vector,
}
impl Engines {
pub fn new() -> Engines {
Engines {
- acceleration: (0.0, 0.0, 0.0),
+ acceleration: Vector::default(),
}
}
- pub fn recv_acceleration(&mut self) -> (f64, f64, f64) {
- let acceleration = self.acceleration;
- self.acceleration = (0.0, 0.0, 0.0);
+ pub fn recv_acceleration(&mut self) -> Vector {
+ let acceleration = self.acceleration.clone();
+ self.acceleration = Vector::default();
acceleration
}
pub fn give_client_data(&mut self, ship: &Mass, target: Option<&Mass>, data: String) {
- let mut acceleration = (0.0, 0.0, 0.0);
+ let mut acceleration = Vector::default();
match data.as_bytes() {
- b"5\n" => acceleration.0 += 0.1,
- b"0\n" => acceleration.0 -= 0.1,
- b"8\n" => acceleration.1 += 0.1,
- b"2\n" => acceleration.1 -= 0.1,
- b"4\n" => acceleration.2 += 0.1,
- b"6\n" => acceleration.2 -= 0.1,
- b"+\n" => {
- let m_v = ship.velocity;
- acceleration = (m_v.0 * 0.05, m_v.1 * 0.05, m_v.2 * 0.05);
- }
+ b"5\n" => acceleration.a += 0.1,
+ b"0\n" => acceleration.a -= 0.1,
+ b"8\n" => acceleration.b += 0.1,
+ 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" => {
- let m_v = ship.velocity;
- acceleration = (
- -1.0 * m_v.0 * 0.05,
- -1.0 * m_v.1 * 0.05,
- -1.0 * m_v.2 * 0.05,
- );
+ acceleration = ship.velocity.clone() * -1.05;
}
b"s\n" => {
- let m_v = ship.velocity;
- acceleration = (-1.0 * m_v.0, -1.0 * m_v.1, -1.0 * m_v.2);
+ acceleration = ship.velocity.clone() * -1.0;
}
b"c\n" => {
if let Some(target) = target {
- let d_v = target.velocity;
- let m_v = ship.velocity;
- acceleration = (d_v.0 - m_v.0, d_v.1 - m_v.1, d_v.2 - m_v.2);
+ acceleration = target.velocity.clone() - ship.velocity.clone();
}
}
b"t\n" => {
if let Some(target) = target {
- 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,
- (d_p.2 - m_p.2) * 0.01,
- );
+ acceleration = (target.position.clone() - ship.position.clone()) * 0.01;
}
}
_ => (),
diff --git a/src/modules/mod.rs b/src/modules/mod.rs
index 3929e24..15c161b 100644
--- a/src/modules/mod.rs
+++ b/src/modules/mod.rs
@@ -4,4 +4,5 @@ pub mod engines;
pub mod mining;
pub mod navigation;
pub mod refinery;
+pub mod tractorbeam;
pub mod types;
diff --git a/src/modules/navigation.rs b/src/modules/navigation.rs
index 11f3e94..03a9ca5 100644
--- a/src/modules/navigation.rs
+++ b/src/modules/navigation.rs
@@ -2,7 +2,7 @@ use std::collections::HashMap;
use std::time::SystemTime;
use crate::mass::Mass;
-use crate::math::distance;
+use crate::math::Vector;
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
pub enum NavigationStatus {
@@ -52,14 +52,10 @@ impl Navigation {
self.target_name = Some(target_name);
}
- pub fn verify_target(
- &mut self,
- ship_position: (f64, f64, f64),
- masses: &HashMap<String, Mass>,
- ) {
+ pub fn verify_target(&mut self, ship_position: Vector, masses: &HashMap<String, Mass>) {
if let Some(name) = self.target_name.clone() {
let target = masses.get(&name).unwrap();
- if distance(target.position, ship_position) > self.range {
+ if target.position.distance_from(ship_position) > self.range {
self.target_name = None;
self.status = NavigationStatus::None;
}
diff --git a/src/modules/tractorbeam.rs b/src/modules/tractorbeam.rs
new file mode 100644
index 0000000..1ddc7d0
--- /dev/null
+++ b/src/modules/tractorbeam.rs
@@ -0,0 +1,90 @@
+use crate::mass::Mass;
+use crate::math::Vector;
+
+#[derive(Serialize, Deserialize, Debug, Clone, Default)]
+pub struct Tractorbeam {
+ pub status: TractorbeamStatus,
+ strength: f64,
+ desired_distance: Option<f64>,
+}
+
+#[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 {
+ status: TractorbeamStatus::None,
+ strength: 0.1,
+ desired_distance: None,
+ }
+ }
+
+ pub fn toggle_pull(&mut self) {
+ self.status = match self.status {
+ TractorbeamStatus::None => TractorbeamStatus::Pull,
+ TractorbeamStatus::Push => TractorbeamStatus::Pull,
+ TractorbeamStatus::Bring => TractorbeamStatus::Pull,
+ TractorbeamStatus::Pull => TractorbeamStatus::None,
+ }
+ }
+
+ pub fn toggle_push(&mut self) {
+ self.status = match self.status {
+ TractorbeamStatus::None => TractorbeamStatus::Push,
+ TractorbeamStatus::Pull => TractorbeamStatus::Push,
+ TractorbeamStatus::Bring => TractorbeamStatus::Push,
+ TractorbeamStatus::Push => TractorbeamStatus::None,
+ }
+ }
+
+ pub fn toggle_bring(&mut self, desired_distance: f64) {
+ self.desired_distance = Some(desired_distance);
+ self.status = match self.status {
+ TractorbeamStatus::None => TractorbeamStatus::Bring,
+ TractorbeamStatus::Pull => TractorbeamStatus::Bring,
+ TractorbeamStatus::Push => TractorbeamStatus::Bring,
+ TractorbeamStatus::Bring => TractorbeamStatus::None,
+ }
+ }
+
+ pub fn off(&mut self) {
+ self.status = TractorbeamStatus::None;
+ }
+
+ pub fn get_acceleration(&self, ship: Mass, target: Mass) -> 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(),
+ }
+ }
+}
diff --git a/src/modules/types.rs b/src/modules/types.rs
index 17e7c6c..91e41dc 100644
--- a/src/modules/types.rs
+++ b/src/modules/types.rs
@@ -5,5 +5,6 @@ pub enum ModuleType {
Refinery,
Dashboard,
Navigation,
+ Tractorbeam,
Construction,
}
diff --git a/src/server/connection.rs b/src/server/connection.rs
index 4fed2b6..662e33d 100644
--- a/src/server/connection.rs
+++ b/src/server/connection.rs
@@ -52,6 +52,7 @@ impl ServerConnection {
ModuleType::Refinery => self.server_refinery(&mut masses),
ModuleType::Dashboard => self.server_dashboard(&mut masses),
ModuleType::Navigation => self.server_navigation(&mut masses),
+ ModuleType::Tractorbeam => self.server_tractorbeam(&mut masses),
ModuleType::Construction => self.server_construction(&mut masses),
}
}
diff --git a/src/server/mining.rs b/src/server/mining.rs
index 6213e65..f6ddb41 100644
--- a/src/server/mining.rs
+++ b/src/server/mining.rs
@@ -5,7 +5,6 @@ use std::io::BufRead;
use std::io::Write;
use crate::mass::{Mass, MassType};
-use crate::math::distance;
use crate::modules::mining::{Mining, MiningStatus};
use crate::modules::navigation::Navigation;
use crate::server::connection::ServerConnection;
@@ -52,7 +51,8 @@ impl ServerConnection {
if let Some(item) = item {
if !ship.give(item.clone()) {
- let mass = Mass::new_item(item.clone(), ship.position, ship.velocity);
+ let mass =
+ Mass::new_item(item.clone(), ship.position.clone(), ship.velocity.clone());
masses.insert(item.name.clone(), mass);
}
}
@@ -109,7 +109,9 @@ fn get_mining_data(
let is_within_range = if has_astroid_target {
match target {
- Some(target) => mining.range > distance(ship.position, target.position),
+ Some(target) => {
+ mining.range > ship.position.distance_from(target.position.clone())
+ }
_ => false,
}
} else {
diff --git a/src/server/mod.rs b/src/server/mod.rs
index 0fec4dc..c195f3d 100644
--- a/src/server/mod.rs
+++ b/src/server/mod.rs
@@ -5,3 +5,4 @@ pub mod engines;
pub mod mining;
pub mod navigation;
pub mod refinery;
+pub mod tractorbeam;
diff --git a/src/server/navigation.rs b/src/server/navigation.rs
index eb9095d..5143667 100644
--- a/src/server/navigation.rs
+++ b/src/server/navigation.rs
@@ -5,7 +5,6 @@ use std::io::BufRead;
use std::io::Write;
use crate::mass::{Mass, MassType};
-use crate::math::distance;
use crate::server::connection::ServerConnection;
impl ServerConnection {
@@ -18,11 +17,11 @@ impl ServerConnection {
} = ship.mass_type
{
let navigation = navigation.as_mut().unwrap();
- navigation.verify_target(ship_clone.position, &masses);
+ navigation.verify_target(ship_clone.position.clone(), &masses);
let mut within_range: HashMap<&String, &Mass> = masses
.iter()
.filter(|&(_, mass)| {
- distance(ship_clone.position, mass.position) < navigation.range
+ ship_clone.position.distance_from(mass.position.clone()) < navigation.range
})
.collect();
within_range.insert(&self.name, &ship_clone);
diff --git a/src/server/tractorbeam.rs b/src/server/tractorbeam.rs
new file mode 100644
index 0000000..250f5fb
--- /dev/null
+++ b/src/server/tractorbeam.rs
@@ -0,0 +1,70 @@
+extern crate serde_json;
+
+use std::collections::HashMap;
+use std::io::BufRead;
+use std::io::Write;
+
+use crate::mass::{Mass, MassType};
+use crate::modules::navigation::NavigationStatus;
+use crate::modules::tractorbeam::TractorbeamStatus;
+use crate::server::connection::ServerConnection;
+
+#[derive(Serialize, Deserialize, Debug, Clone)]
+pub struct TractorbeamData {
+ pub has_target: bool,
+ pub status: TractorbeamStatus,
+}
+
+impl ServerConnection {
+ pub fn server_tractorbeam(&mut self, masses: &mut HashMap<String, Mass>) {
+ let mut ship = masses.remove(&self.name).unwrap();
+ let ship_clone = ship.clone();
+
+ if let MassType::Ship {
+ ref mut tractorbeam,
+ ref navigation,
+ ..
+ } = ship.mass_type
+ {
+ let tractorbeam = tractorbeam.as_mut().unwrap();
+ let navigation = navigation.as_ref().unwrap();
+
+ if self.open {
+ let tractorbeam_data = TractorbeamData {
+ has_target: navigation.status == NavigationStatus::Targeted,
+ status: tractorbeam.status.clone(),
+ };
+
+ let send = serde_json::to_string(&tractorbeam_data).unwrap() + "\n";
+ self.open = match self.stream.write(send.as_bytes()) {
+ Ok(_result) => true,
+ Err(_error) => false,
+ };
+
+ let mut recv = String::new();
+ if let Ok(result) = self.buff_r.read_line(&mut recv) {
+ match recv.as_bytes() {
+ b"o\n" => tractorbeam.toggle_pull(),
+ b"p\n" => tractorbeam.toggle_push(),
+ b"t\n" => tractorbeam.toggle_bring(5.0),
+ _ => {
+ if result == 0 {
+ self.open = false;
+ }
+ }
+ }
+ }
+ }
+
+ if let Some(name) = navigation.target_name.clone() {
+ let target = masses.get_mut(&name).unwrap();
+ let acceleration = tractorbeam.get_acceleration(ship_clone, target.clone());
+ target.effects.give_acceleration(acceleration);
+ } else {
+ tractorbeam.off();
+ }
+ }
+
+ masses.insert(self.name.clone(), ship);
+ }
+}