78 lines
2.0 KiB
Rust
78 lines
2.0 KiB
Rust
use cgmath::{Deg, InnerSpace};
|
|
|
|
use crate::ShipBehavior;
|
|
use galactica_content as content;
|
|
use galactica_physics::{util, Physics, ShipHandle};
|
|
|
|
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, 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;
|
|
}
|
|
}
|