Minor fixes
parent
1493a97f01
commit
5815bb9f9f
|
@ -38,13 +38,7 @@ pub enum ShipState {
|
|||
},
|
||||
|
||||
/// This ship has been destroyed, and is playing its collapse sequence.
|
||||
Collapsing {
|
||||
/// Total collapse sequence length, in seconds
|
||||
total: f32,
|
||||
|
||||
/// How many seconds of the collapse sequence we've played
|
||||
elapsed: f32,
|
||||
},
|
||||
Collapsing,
|
||||
|
||||
/// This ship is landed on a planet
|
||||
Landed {
|
||||
|
@ -84,18 +78,6 @@ impl ShipState {
|
|||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// If this ship is collapsing, return total collapse time and remaining collapse time.
|
||||
/// Otherwise, return None
|
||||
pub fn collapse_state(&self) -> Option<(f32, f32)> {
|
||||
match self {
|
||||
Self::Collapsing {
|
||||
total,
|
||||
elapsed: remaining,
|
||||
} => Some((*total, *remaining)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents all attributes of a single ship
|
||||
|
@ -257,6 +239,18 @@ impl ShipData {
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Called when collapse sequence is finished.
|
||||
/// Will panic if we're not collapsing
|
||||
pub fn finish_collapse(&mut self) {
|
||||
match self.state {
|
||||
ShipState::Collapsing => self.state = ShipState::Dead,
|
||||
_ => {
|
||||
unreachable!("Called `finish_collapse` on a ship that isn't collapsing!")
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Add an outfit to this ship
|
||||
pub fn add_outfit(&mut self, o: &Outfit) -> super::OutfitAddResult {
|
||||
let r = self.outfits.add(o);
|
||||
|
@ -292,7 +286,7 @@ impl ShipData {
|
|||
}
|
||||
|
||||
/// Hit this ship with the given amount of damage
|
||||
pub(crate) fn apply_damage(&mut self, ct: &Content, mut d: f32) {
|
||||
pub(crate) fn apply_damage(&mut self, mut d: f32) {
|
||||
match self.state {
|
||||
ShipState::Flying { .. } => {}
|
||||
_ => {
|
||||
|
@ -311,10 +305,7 @@ impl ShipData {
|
|||
|
||||
if self.hull <= 0.0 {
|
||||
// This ship has been destroyed, update state
|
||||
self.state = ShipState::Collapsing {
|
||||
total: ct.get_ship(self.ct_handle).collapse.length,
|
||||
elapsed: 0.0,
|
||||
}
|
||||
self.state = ShipState::Collapsing
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -360,17 +351,7 @@ impl ShipData {
|
|||
}
|
||||
}
|
||||
|
||||
ShipState::Collapsing {
|
||||
ref mut elapsed,
|
||||
total,
|
||||
} => {
|
||||
*elapsed += t;
|
||||
if *elapsed >= total {
|
||||
self.state = ShipState::Dead
|
||||
}
|
||||
}
|
||||
|
||||
ShipState::Dead => {}
|
||||
ShipState::Collapsing {} | ShipState::Dead => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use galactica_content::Relationship;
|
||||
use nalgebra::{Rotation2, Vector2};
|
||||
use galactica_util::clockwise_angle;
|
||||
use nalgebra::Vector2;
|
||||
use rapier2d::{dynamics::RigidBodySet, geometry::ColliderHandle};
|
||||
use std::collections::HashMap;
|
||||
|
||||
|
@ -73,12 +74,14 @@ impl ShipControllerStruct for PointShipController {
|
|||
}
|
||||
}
|
||||
|
||||
let angle = (closest_enemy_position - my_position).angle(&Vector2::new(1.0, 0.0));
|
||||
let angle_delta = my_rotation.angle_to(&Rotation2::new(angle).into());
|
||||
let angle = clockwise_angle(
|
||||
&(my_rotation * Vector2::new(1.0, 0.0)),
|
||||
&(closest_enemy_position - my_position),
|
||||
);
|
||||
|
||||
if angle_delta < 0.0 && my_angvel > -0.3 {
|
||||
if angle < 0.0 && my_angvel > -0.3 {
|
||||
controls.right = true;
|
||||
} else if angle_delta > 0.0 && my_angvel < 0.3 {
|
||||
} else if angle > 0.0 && my_angvel < 0.3 {
|
||||
controls.left = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,27 +10,35 @@ use crate::data::ShipData;
|
|||
pub(super) struct ShipCollapseSequence {
|
||||
rng: ThreadRng,
|
||||
|
||||
/// The elapsed collapse duration when step()
|
||||
/// was last called
|
||||
last_call: f32,
|
||||
/// The total length of this collapse sequence
|
||||
total_length: f32,
|
||||
|
||||
/// How many seconds we've spent playing this sequence
|
||||
elapsed: f32,
|
||||
}
|
||||
|
||||
impl ShipCollapseSequence {
|
||||
pub(super) fn new() -> Self {
|
||||
pub(super) fn new(total_length: f32) -> Self {
|
||||
Self {
|
||||
rng: rand::thread_rng(),
|
||||
last_call: 0.0,
|
||||
total_length,
|
||||
elapsed: 0.0,
|
||||
}
|
||||
}
|
||||
|
||||
/// Has this collapse sequence fully played out?
|
||||
pub fn is_done(&self) -> bool {
|
||||
self.elapsed >= self.total_length
|
||||
}
|
||||
|
||||
/// Pick a random points inside a ship's collider
|
||||
fn random_in_ship(&mut self, ship: &Ship, collider: &Collider) -> Vector2<f32> {
|
||||
let mut y = 0.0;
|
||||
let mut x = 0.0;
|
||||
let mut a = false;
|
||||
while !a {
|
||||
y = self.rng.gen_range(-1.0..=1.0) * ship.size / 2.0;
|
||||
x = self.rng.gen_range(-1.0..=1.0) * ship.size * ship.sprite.aspect / 2.0;
|
||||
x = self.rng.gen_range(-1.0..=1.0) * ship.size / 2.0;
|
||||
y = self.rng.gen_range(-1.0..=1.0) * ship.size * ship.sprite.aspect / 2.0;
|
||||
a = collider.shape().contains_local_point(&Point2::new(x, y));
|
||||
}
|
||||
Vector2::new(x, y)
|
||||
|
@ -48,12 +56,8 @@ impl ShipCollapseSequence {
|
|||
let ship_pos = rigid_body.translation();
|
||||
let ship_rot = rigid_body.rotation();
|
||||
|
||||
let (total, elapsed) = ship_data.get_state().collapse_state().unwrap();
|
||||
// How much time has passed since step() was last called
|
||||
let delta = elapsed - self.last_call;
|
||||
|
||||
// The fraction of this collapse sequence that has been played
|
||||
let frac_done = elapsed / total;
|
||||
let frac_done = self.elapsed / self.total_length;
|
||||
|
||||
// TODO: slight random offset for event particles
|
||||
|
||||
|
@ -61,8 +65,8 @@ impl ShipCollapseSequence {
|
|||
for event in &ship_content.collapse.events {
|
||||
match event {
|
||||
CollapseEvent::Effect(event) => {
|
||||
if (event.time > self.last_call && event.time <= elapsed)
|
||||
|| (event.time == 0.0 && self.last_call == 0.0)
|
||||
if (event.time > self.elapsed && event.time <= self.elapsed + res.t)
|
||||
|| (event.time == 0.0 && self.elapsed == 0.0)
|
||||
// ^^ Don't miss events scheduled at the very start of the sequence!
|
||||
{
|
||||
for spawner in &event.effects {
|
||||
|
@ -110,9 +114,7 @@ impl ShipCollapseSequence {
|
|||
return y;
|
||||
};
|
||||
|
||||
// Notice that we don't use res.t here, since ship state is updated earlier
|
||||
// ( through self.data.step() )
|
||||
let p_add = (delta / total) * pdf(frac_done) * spawner.count;
|
||||
let p_add = (res.t / self.total_length) * pdf(frac_done) * spawner.count;
|
||||
|
||||
if self.rng.gen_range(0.0..=1.0) <= p_add {
|
||||
let pos = if let Some(pos) = spawner.pos {
|
||||
|
@ -138,6 +140,6 @@ impl ShipCollapseSequence {
|
|||
}
|
||||
}
|
||||
|
||||
self.last_call = elapsed;
|
||||
self.elapsed += res.t;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,12 +70,13 @@ impl PhysSimShip {
|
|||
rigid_body: RigidBodyHandle,
|
||||
collider: ColliderHandle,
|
||||
) -> Self {
|
||||
let ship_ct = ct.get_ship(handle);
|
||||
PhysSimShip {
|
||||
rigid_body,
|
||||
collider,
|
||||
data: ShipData::new(ct, handle, faction, personality),
|
||||
controls: ShipControls::new(),
|
||||
collapse_sequence: Some(ShipCollapseSequence::new()),
|
||||
collapse_sequence: Some(ShipCollapseSequence::new(ship_ct.collapse.length)),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -94,6 +95,10 @@ impl PhysSimShip {
|
|||
let mut seq = self.collapse_sequence.take().unwrap();
|
||||
seq.step(res, &self.data, rigid_body, collider);
|
||||
self.collapse_sequence = Some(seq);
|
||||
|
||||
if self.collapse_sequence.as_ref().unwrap().is_done() {
|
||||
self.data.finish_collapse();
|
||||
}
|
||||
}
|
||||
ShipState::Flying { .. } => {
|
||||
self.step_physics(res, rigid_body, collider);
|
||||
|
@ -167,8 +172,8 @@ impl PhysSimShip {
|
|||
let mut x = 0.0;
|
||||
let mut a = false;
|
||||
while !a {
|
||||
y = rng.gen_range(-1.0..=1.0) * ship_content.size / 2.0;
|
||||
x = rng.gen_range(-1.0..=1.0)
|
||||
x = rng.gen_range(-1.0..=1.0) * ship_content.size / 2.0;
|
||||
y = rng.gen_range(-1.0..=1.0)
|
||||
* ship_content.size * ship_content.sprite.aspect
|
||||
/ 2.0;
|
||||
a = collider.shape().contains_local_point(&point![x, y]);
|
||||
|
|
|
@ -162,7 +162,7 @@ impl PhysSim {
|
|||
let destory_projectile = match r {
|
||||
Relationship::Hostile => match ship.data.get_state() {
|
||||
ShipState::Flying { .. } => {
|
||||
ship.data.apply_damage(res.ct, projectile.content.damage);
|
||||
ship.data.apply_damage(projectile.content.damage);
|
||||
true
|
||||
}
|
||||
ShipState::Collapsing { .. } => true,
|
||||
|
|
|
@ -13,7 +13,7 @@ pub fn to_radians(degrees: f32) -> f32 {
|
|||
}
|
||||
|
||||
/// Compute the clockwise angle between two vectors
|
||||
/// Returns a value in [0, 2pi]
|
||||
/// Returns a value in [-pi, pi]
|
||||
pub fn clockwise_angle(a: &Vector2<f32>, b: &Vector2<f32>) -> f32 {
|
||||
(a.x * b.y - b.x * a.y).atan2(a.dot(&b))
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue