150 lines
3.1 KiB
Rust
150 lines
3.1 KiB
Rust
use cgmath::{Deg, InnerSpace};
|
|
|
|
use crate::{
|
|
content,
|
|
inputstatus::InputStatus,
|
|
physics::{util, Physics, ShipHandle},
|
|
};
|
|
|
|
pub trait ShipBehavior
|
|
where
|
|
Self: Send,
|
|
{
|
|
fn update_controls(
|
|
&mut self,
|
|
physics: &mut Physics,
|
|
input: &InputStatus,
|
|
content: &content::Content,
|
|
);
|
|
fn get_handle(&self) -> ShipHandle;
|
|
}
|
|
|
|
pub struct Dummy {
|
|
_handle: ShipHandle,
|
|
}
|
|
|
|
impl Dummy {
|
|
pub fn new(handle: ShipHandle) -> Box<Self> {
|
|
Box::new(Self { _handle: handle })
|
|
}
|
|
}
|
|
|
|
impl ShipBehavior for Dummy {
|
|
fn update_controls(
|
|
&mut self,
|
|
_physics: &mut Physics,
|
|
_input: &InputStatus,
|
|
_content: &content::Content,
|
|
) {
|
|
}
|
|
fn get_handle(&self) -> ShipHandle {
|
|
return self._handle;
|
|
}
|
|
}
|
|
|
|
pub struct Player {
|
|
handle: ShipHandle,
|
|
}
|
|
|
|
impl Player {
|
|
pub fn new(handle: ShipHandle) -> Box<Self> {
|
|
Box::new(Self { handle })
|
|
}
|
|
}
|
|
|
|
impl ShipBehavior for Player {
|
|
fn update_controls(
|
|
&mut self,
|
|
physics: &mut Physics,
|
|
input: &InputStatus,
|
|
_content: &content::Content,
|
|
) {
|
|
let s = physics.get_ship_mut(&self.handle).unwrap();
|
|
s.controls.left = input.key_left;
|
|
s.controls.right = input.key_right;
|
|
s.controls.guns = input.key_guns;
|
|
s.controls.thrust = input.key_thrust;
|
|
}
|
|
|
|
fn get_handle(&self) -> ShipHandle {
|
|
return self.handle;
|
|
}
|
|
}
|
|
|
|
pub struct Point {
|
|
handle: ShipHandle,
|
|
}
|
|
|
|
impl Point {
|
|
pub fn new(handle: ShipHandle) -> Box<Self> {
|
|
Box::new(Self { handle })
|
|
}
|
|
}
|
|
|
|
impl ShipBehavior for Point {
|
|
fn update_controls(
|
|
&mut self,
|
|
physics: &mut Physics,
|
|
_input: &InputStatus,
|
|
content: &content::Content,
|
|
) {
|
|
// Turn off all controls
|
|
let s = physics.get_ship_mut(&self.handle).unwrap();
|
|
s.controls.left = false;
|
|
s.controls.right = false;
|
|
s.controls.guns = false;
|
|
s.controls.thrust = false;
|
|
|
|
let (my_s, my_r) = physics.get_ship_body(&self.handle).unwrap();
|
|
let my_position = util::rigidbody_position(my_r);
|
|
let my_rotation = util::rigidbody_rotation(my_r);
|
|
let my_angvel = my_r.angvel();
|
|
let my_faction = content.get_faction(my_s.faction);
|
|
|
|
// Iterate all possible targets
|
|
let mut it = physics
|
|
.iter_ship_body()
|
|
.filter(|(s, _)| match my_faction.relationships[&s.faction] {
|
|
content::Relationship::Hostile => true,
|
|
_ => false,
|
|
})
|
|
.map(|(_, r)| r);
|
|
|
|
// Find the closest target
|
|
let mut closest_enemy_position = match it.next() {
|
|
Some(c) => util::rigidbody_position(c),
|
|
None => return, // Do nothing if no targets are available
|
|
};
|
|
let mut d = (my_position - closest_enemy_position).magnitude();
|
|
for r in it {
|
|
let p = util::rigidbody_position(r);
|
|
let new_d = (my_position - p).magnitude();
|
|
if new_d < d {
|
|
d = new_d;
|
|
closest_enemy_position = p;
|
|
}
|
|
}
|
|
|
|
let angle_delta: Deg<f32> = (my_rotation)
|
|
.angle(closest_enemy_position - my_position)
|
|
.into();
|
|
|
|
let s = physics.get_ship_mut(&self.handle).unwrap();
|
|
s.controls.left = false;
|
|
s.controls.right = false;
|
|
|
|
if angle_delta < Deg(0.0) && my_angvel > -0.3 {
|
|
s.controls.right = true;
|
|
} else if angle_delta > Deg(0.0) && my_angvel < 0.3 {
|
|
s.controls.left = true;
|
|
}
|
|
|
|
s.controls.guns = true;
|
|
s.controls.thrust = false;
|
|
}
|
|
|
|
fn get_handle(&self) -> ShipHandle {
|
|
return self.handle;
|
|
}
|
|
}
|