Browse Source

Restricted visibility of components

master
Bergmann89 4 years ago
parent
commit
d719a8cc10
27 changed files with 516 additions and 506 deletions
  1. +3
    -0
      .gitmodules
  2. +5
    -0
      Cargo.lock
  3. +1
    -0
      Cargo.toml
  4. +1
    -0
      auto_ops
  5. +1
    -0
      glc/Cargo.toml
  6. +28
    -68
      glc/src/angle.rs
  7. +7
    -41
      glc/src/matrix.rs
  8. +39
    -186
      glc/src/vector.rs
  9. +9
    -7
      space-crush-app/src/debug/fleets.rs
  10. +10
    -7
      space-crush-app/src/debug/ships.rs
  11. +27
    -59
      space-crush-app/src/main.rs
  12. +6
    -6
      space-crush-app/src/render/asteroids.rs
  13. +25
    -25
      space-crush-app/src/render/fleet_select.rs
  14. +5
    -5
      space-crush-app/src/render/planets.rs
  15. +7
    -7
      space-crush-app/src/render/ships.rs
  16. +9
    -8
      space-crush-app/src/systems/fleet_control.rs
  17. +14
    -2
      space-crush-common/src/components/asteroid.rs
  18. +41
    -3
      space-crush-common/src/components/fleet.rs
  19. +48
    -4
      space-crush-common/src/components/orbit.rs
  20. +41
    -3
      space-crush-common/src/components/player.rs
  21. +30
    -2
      space-crush-common/src/components/position.rs
  22. +53
    -6
      space-crush-common/src/components/ship.rs
  23. +20
    -2
      space-crush-common/src/components/velocity.rs
  24. +22
    -10
      space-crush-common/src/systems/fleet_owned_update.rs
  25. +1
    -1
      space-crush-common/src/systems/movement.rs
  26. +18
    -10
      space-crush-common/src/systems/orbit_owned_update.rs
  27. +45
    -44
      space-crush-common/src/systems/ships.rs

+ 3
- 0
.gitmodules View File

@@ -0,0 +1,3 @@
[submodule "auto_ops"]
path = auto_ops
url = https://github.com/carbotaniuman/auto_ops.git

+ 5
- 0
Cargo.lock View File

@@ -83,6 +83,10 @@ version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9ff149ed9780025acfdb36862d35b28856bb693ceb451259a7164442f22fdc3"

[[package]]
name = "auto_ops"
version = "0.1.0"

[[package]]
name = "autocfg"
version = "1.0.1"
@@ -548,6 +552,7 @@ dependencies = [
name = "glc"
version = "0.1.0"
dependencies = [
"auto_ops",
"gl",
"imagefmt",
"serde",


+ 1
- 0
Cargo.toml View File

@@ -11,6 +11,7 @@ default-members = [
]

[patch.crates-io]
auto_ops = { path = "./auto_ops" }
gl = { path = "./gl" }
glc = { path = "./glc" }
space-crush-app = { path = "./space-crush-app" }


+ 1
- 0
auto_ops

@@ -0,0 +1 @@
Subproject commit 59ebf01379d09c0707d257c20efb21a3b1dc877b

+ 1
- 0
glc/Cargo.toml View File

@@ -8,6 +8,7 @@ edition = "2018"
default = [ ]

[dependencies]
auto_ops = "0.1"
gl = { version = "0.1", features = [ "generate_global" ] }
imagefmt = "4.0"
serde = { version = "1.0", optional = true, features = [ "derive" ] }


+ 28
- 68
glc/src/angle.rs View File

@@ -1,7 +1,7 @@
use std::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
use std::f64::consts::PI;
use std::ops::{Add, Div, Mul, Neg, Sub};

use auto_ops::impl_op_ex;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

@@ -47,99 +47,59 @@ where
Self::Rad(value) => Self::Rad(value.abs()),
}
}
}

impl<T> Angle<T>
where
T: Float,
{
pub fn sin(self) -> T {
T::sin(self.into_rad().into_inner())
}

pub fn cos(self) -> T {
T::cos(self.into_rad().into_inner())
}

/// Normalizes the angle to (-pi, pi] / (-180.0, 180.0]
pub fn normalize(self) -> Self {
match self {
Self::Deg(value) => Self::Deg(normalize(value, T::new(-180.0), T::new(180.0))),
Self::Rad(value) => Self::Rad(normalize(value, T::new(-PI), T::new(PI))),
}
}
}

impl<T> Neg for Angle<T>
where
T: Neg + Numeric,
{
type Output = Angle<T>;

fn neg(self) -> Self::Output {
fn _neg(self) -> Self {
match self {
Self::Deg(value) => Self::Deg(-value),
Self::Rad(value) => Self::Rad(-value),
}
}
}

impl<T> Add for Angle<T>
where
T: Add<T, Output = T> + Numeric,
{
type Output = Angle<T>;

fn add(self, v: Self) -> Self::Output {
fn _add(self, other: &Self) -> Self {
match self {
Self::Deg(value) => Self::Deg(value + v.into_deg().into_inner()),
Self::Rad(value) => Self::Rad(value + v.into_rad().into_inner()),
Self::Deg(value) => Self::Deg(value + other.into_deg().into_inner()),
Self::Rad(value) => Self::Rad(value * other.into_rad().into_inner()),
}
}
}

impl<T> Sub for Angle<T>
where
T: Sub<T, Output = T> + Numeric,
{
type Output = Angle<T>;

fn sub(self, v: Self) -> Self::Output {
fn _mul(self, other: T) -> Self {
match self {
Self::Deg(value) => Self::Deg(value - v.into_deg().into_inner()),
Self::Rad(value) => Self::Rad(value - v.into_rad().into_inner()),
Self::Deg(value) => Self::Deg(value * other),
Self::Rad(value) => Self::Rad(value * other),
}
}
}

impl<T> Mul<T> for Angle<T>
impl<T> Angle<T>
where
T: Mul<T, Output = T> + Numeric,
T: Float,
{
type Output = Angle<T>;

fn mul(self, factor: T) -> Self::Output {
match self {
Self::Deg(value) => Self::Deg(value * factor),
Self::Rad(value) => Self::Rad(value * factor),
}
pub fn sin(self) -> T {
T::sin(self.into_rad().into_inner())
}
}

impl<T> Div<T> for Angle<T>
where
T: Div<T, Output = T> + Numeric,
{
type Output = Angle<T>;
pub fn cos(self) -> T {
T::cos(self.into_rad().into_inner())
}

fn div(self, factor: T) -> Self::Output {
/// Normalizes the angle to (-pi, pi] / (-180.0, 180.0]
pub fn normalize(self) -> Self {
match self {
Self::Deg(value) => Self::Deg(value / factor),
Self::Rad(value) => Self::Rad(value / factor),
Self::Deg(value) => Self::Deg(normalize(value, T::new(-180.0), T::new(180.0))),
Self::Rad(value) => Self::Rad(normalize(value, T::new(-PI), T::new(PI))),
}
}
}

impl_op_ex!(*|a: &f32, b: &Angle<f32>| -> Angle<f32> { b._mul(*a) });
impl_op_ex!(- <T: Numeric> |a: &Angle<T>| -> Angle<T> { a._neg() });
impl_op_ex!(+ <T: Numeric> |a: &Angle<T>, b: &Angle<T>| -> Angle<T> { a._add(b) });
impl_op_ex!(- <T: Numeric> |a: &Angle<T>, b: &Angle<T>| -> Angle<T> { a._add(&b._neg()) });
impl_op_ex!(* <T: Numeric> |a: &Angle<T>, b: &T| -> Angle<T> { a._mul(*b) });
impl_op_ex!(/ <T: Numeric> |a: &Angle<T>, b: &T| -> Angle<T> { a._mul(T::one() / *b) });
impl_op_ex!(+= <T: Numeric> |a: &mut Angle<T>, b: &Angle<T>| { *a = a._add(b); });
impl_op_ex!(-= <T: Numeric> |a: &mut Angle<T>, b: &Angle<T>| { *a = a._add(&b._neg()); });

impl<T, S> PartialEq<Angle<S>> for Angle<T>
where
T: Numeric + PartialEq<S>,


+ 7
- 41
glc/src/matrix.rs View File

@@ -3,8 +3,9 @@
use std::borrow::Borrow;
use std::convert::{AsMut, AsRef};
use std::fmt::{Debug, Formatter, Result as FmtResult};
use std::ops::{Deref, DerefMut, Mul};
use std::ops::{Deref, DerefMut};

use auto_ops::impl_op_ex;
#[cfg(feature = "serde")]
use serde::{
de::{Deserializer, Error, MapAccess, SeqAccess, Visitor},
@@ -356,17 +357,9 @@ where
}
}

impl<T, M> Mul<M> for Matrix3<T>
where
T: Float,
M: Borrow<Matrix3<T>>,
{
type Output = Self;

fn mul(self, rhs: M) -> Self::Output {
self.multiply(rhs.borrow())
}
}
impl_op_ex!(* <T: Float> |a: &Matrix3<T>, b: &Matrix3<T>| -> Matrix3<T> { a.multiply(b) });
impl_op_ex!(* <T: Float> |a: &Matrix3<T>, b: &Vector2<T>| -> Vector2<T> { a.transform(*b) });
impl_op_ex!(*= <T: Float> |a: &mut Vector2<T>, b: &Matrix3<T>| { *a = b.transform(*a); });

/* Matrix4 */

@@ -638,35 +631,8 @@ where
}
}

macro_rules! impl_mul_mat4 {
($input:ty, $output:ty, $func:ident) => {
impl<T> Mul<$input> for Matrix4<T>
where
T: Float,
{
type Output = $output;

fn mul(self, rhs: $input) -> Self::Output {
self.$func(rhs)
}
}

impl<T> Mul<$input> for &Matrix4<T>
where
T: Float,
{
type Output = $output;

fn mul(self, rhs: $input) -> Self::Output {
self.$func(rhs)
}
}
};
}

impl_mul_mat4!(Matrix4<T>, Matrix4<T>, multiply);
impl_mul_mat4!(&Matrix4<T>, Matrix4<T>, multiply);
impl_mul_mat4!(Vector4<T>, Vector4<T>, transform);
impl_op_ex!(* <T: Float> |a: &Matrix4<T>, b: &Matrix4<T>| -> Matrix4<T> { a.multiply(b) });
impl_op_ex!(* <T: Float> |a: &Matrix4<T>, b: &Vector4<T>| -> Vector4<T> { a.transform(*b) });

#[cfg(test)]
mod tests {


+ 39
- 186
glc/src/vector.rs View File

@@ -2,8 +2,9 @@

use std::convert::{AsMut, AsRef};
use std::fmt::{Debug, Formatter, Result as FmtResult};
use std::ops::{Add, Deref, DerefMut, Mul, Neg, Sub};
use std::ops::{Deref, DerefMut};

use auto_ops::impl_op_ex;
#[cfg(feature = "serde")]
use serde::{
de::{Deserialize, Deserializer, Error},
@@ -296,74 +297,15 @@ where
}
}

impl<T> Neg for Vector2<T>
where
T: Numeric,
{
type Output = Self;

#[inline]
fn neg(self) -> Self::Output {
Self {
x: -self.x,
y: -self.y,
}
}
}

impl<T> Add for Vector2<T>
where
T: Numeric,
{
type Output = Self;

#[inline]
fn add(mut self, other: Self) -> Self::Output {
self.x = self.x + other.x;
self.y = self.y + other.y;

self
}
}

impl<T> Sub for Vector2<T>
where
T: Numeric,
{
type Output = Self;

#[inline]
fn sub(mut self, other: Self) -> Self::Output {
self.x = self.x - other.x;
self.y = self.y - other.y;

self
}
}

impl<T> Mul for Vector2<T>
where
T: Numeric,
{
type Output = T;

#[inline]
fn mul(self, rhs: Self) -> Self::Output {
self.scalar(&rhs)
}
}

impl<T> Mul<T> for Vector2<T>
where
T: Numeric,
{
type Output = Self;

#[inline]
fn mul(self, rhs: T) -> Self::Output {
self.multiply(rhs)
}
}
impl_op_ex!(*|a: &f32, b: &Vector2f| -> Vector2f { b.multiply(*a) });
impl_op_ex!(- <T: Numeric> |a: &Vector2<T>| -> Vector2<T> { Vector2 { x: -a.x, y: -a.y } });
impl_op_ex!(+ <T: Numeric> |a: &Vector2<T>, b: &Vector2<T>| -> Vector2<T> { Vector2 { x: a.x + b.x, y: a.y + b.y } });
impl_op_ex!(- <T: Numeric> |a: &Vector2<T>, b: &Vector2<T>| -> Vector2<T> { Vector2 { x: a.x - b.x, y: a.y - b.y } });
impl_op_ex!(* <T: Numeric> |a: &Vector2<T>, b: &Vector2<T>| -> T { a.scalar(b) });
impl_op_ex!(* <T: Numeric> |a: &Vector2<T>, b: &T| -> Vector2<T> { a.multiply(*b) });
impl_op_ex!(/ <T: Numeric> |a: &Vector2<T>, b: &T| -> Vector2<T> { a.multiply(T::one() / *b) });
impl_op_ex!(+= <T: Numeric> |a: &mut Vector2<T>, b: &Vector2<T>| { a.x = a.x + b.x; a.y = a.y + b.y; });
impl_op_ex!(-= <T: Numeric> |a: &mut Vector2<T>, b: &Vector2<T>| { a.x = a.x - b.x; a.y = a.y - b.y; });

impl<T> From<Vector3<T>> for Vector2<T>
where
@@ -445,6 +387,16 @@ where
y: self.y,
}
}

#[inline]
pub fn into_vec4(self) -> Vector4<T> {
Vector4 {
x: self.x,
y: self.y,
z: self.z,
w: T::one(),
}
}
}

impl<T> Vector3<T>
@@ -461,77 +413,15 @@ where
}
}

impl<T> Neg for Vector3<T>
where
T: Numeric,
{
type Output = Self;

#[inline]
fn neg(self) -> Self::Output {
Self {
x: -self.x,
y: -self.y,
z: -self.z,
}
}
}

impl<T> Add for Vector3<T>
where
T: Numeric,
{
type Output = Self;

#[inline]
fn add(mut self, other: Self) -> Self::Output {
self.x = self.x + other.x;
self.y = self.y + other.y;
self.z = self.z + other.z;

self
}
}

impl<T> Sub for Vector3<T>
where
T: Numeric,
{
type Output = Self;

#[inline]
fn sub(mut self, other: Self) -> Self::Output {
self.x = self.x - other.x;
self.y = self.y - other.y;
self.z = self.z - other.z;

self
}
}

impl<T> Mul for Vector3<T>
where
T: Numeric,
{
type Output = T;

#[inline]
fn mul(self, rhs: Self) -> Self::Output {
self.scalar(&rhs)
}
}

impl<T> Mul<T> for Vector3<T>
where
T: Numeric,
{
type Output = Self;

#[inline]
fn mul(self, rhs: T) -> Self::Output {
self.multiply(rhs)
}
}
impl_op_ex!(*|a: &f32, b: &Vector3f| -> Vector3f { b.multiply(*a) });
impl_op_ex!(- <T: Numeric> |a: &Vector3<T>| -> Vector3<T> { Vector3 { x: -a.x, y: -a.y, z: -a.z } });
impl_op_ex!(+ <T: Numeric> |a: &Vector3<T>, b: &Vector3<T>| -> Vector3<T> { Vector3 { x: a.x + b.x, y: a.y + b.y, z: a.z + b.z } });
impl_op_ex!(- <T: Numeric> |a: &Vector3<T>, b: &Vector3<T>| -> Vector3<T> { Vector3 { x: a.x - b.x, y: a.y - b.y, z: a.z - b.z } });
impl_op_ex!(* <T: Numeric> |a: &Vector3<T>, b: &Vector3<T>| -> T { a.scalar(b) });
impl_op_ex!(* <T: Numeric> |a: &Vector3<T>, b: &T| -> Vector3<T> { a.multiply(*b) });
impl_op_ex!(/ <T: Numeric> |a: &Vector3<T>, b: &T| -> Vector3<T> { a.multiply(T::one() / *b) });
impl_op_ex!(+= <T: Numeric> |a: &mut Vector3<T>, b: &Vector3<T>| { a.x = a.x + b.x; a.y = a.y + b.y; a.z = a.z + b.z; });
impl_op_ex!(-= <T: Numeric> |a: &mut Vector3<T>, b: &Vector3<T>| { a.x = a.x - b.x; a.y = a.y - b.y; a.z = a.z - b.z; });

impl<T> From<Vector2<T>> for Vector3<T>
where
@@ -665,52 +555,15 @@ where
}
}

impl<T> Add for Vector4<T>
where
T: Numeric,
{
type Output = Self;

#[inline]
fn add(self, other: Self) -> Self::Output {
(self.into_vec3() + other.into_vec3(), T::one()).into()
}
}

impl<T> Sub for Vector4<T>
where
T: Numeric,
{
type Output = Self;

#[inline]
fn sub(self, other: Self) -> Self::Output {
(self.into_vec3() - other.into_vec3(), T::one()).into()
}
}

impl<T> Mul for Vector4<T>
where
T: Numeric,
{
type Output = T;

fn mul(self, rhs: Self) -> Self::Output {
self.scalar(&rhs)
}
}

impl<T> Mul<T> for Vector4<T>
where
T: Numeric,
{
type Output = Self;

#[inline]
fn mul(self, rhs: T) -> Self::Output {
self.multiply(rhs)
}
}
impl_op_ex!(*|a: &f32, b: &Vector4f| -> Vector4f { b.multiply(*a) });
impl_op_ex!(- <T: Numeric> |a: &Vector4<T>| -> Vector4<T> { Vector4 { x: -a.x, y: -a.y, z: -a.z, w: a.w } });
impl_op_ex!(+ <T: Numeric> |a: &Vector4<T>, b: &Vector4<T>| -> Vector4<T> { (a.into_vec3() + b.into_vec3()).into_vec4() });
impl_op_ex!(- <T: Numeric> |a: &Vector4<T>, b: &Vector4<T>| -> Vector4<T> { (a.into_vec3() - b.into_vec3()).into_vec4() });
impl_op_ex!(* <T: Numeric> |a: &Vector4<T>, b: &Vector4<T>| -> T { a.scalar(b) });
impl_op_ex!(* <T: Numeric> |a: &Vector4<T>, b: &T| -> Vector4<T> { a.multiply(*b) });
impl_op_ex!(/ <T: Numeric> |a: &Vector4<T>, b: &T| -> Vector4<T> { a.multiply(T::one() / *b) });
impl_op_ex!(+= <T: Numeric> |a: &mut Vector4<T>, b: &Vector4<T>| { *a = (a.into_vec3() + b.into_vec3()).into_vec4(); });
impl_op_ex!(-= <T: Numeric> |a: &mut Vector4<T>, b: &Vector4<T>| { *a = (a.into_vec3() - b.into_vec3()).into_vec4(); });

impl<T> From<Vector2<T>> for Vector4<T>
where


+ 9
- 7
space-crush-app/src/debug/fleets.rs View File

@@ -65,7 +65,7 @@ impl<'a> System<'a> for Fleets {
gl::enable(gl::BLEND);

for (position, orbit) in (&positions, &orbits).join() {
let fleet_id = continue_if_none!(orbit.fleets.get(player.index));
let fleet_id = continue_if_none!(orbit.fleets().get(player.index()));
let fleet_id = continue_if_none!(fleet_id);
let fleet = continue_if_none!(fleets.get(*fleet_id));

@@ -73,15 +73,15 @@ impl<'a> System<'a> for Fleets {
gl::blend_equation(gl::FUNC_ADD);
geometry.render_lines(
Vector4f::new(0.5, 0.5, 0.5, 0.05),
&create_circle(position.pos, orbit.min),
&create_circle(position.pos(), orbit.min()),
);
geometry.render_lines(
Vector4f::new(0.5, 0.5, 0.5, 0.05),
&create_circle(position.pos, orbit.max),
&create_circle(position.pos(), orbit.max()),
);
geometry.render_lines(
Vector4f::new(0.5, 0.5, 0.5, 0.05),
&create_circle(position.pos, SHIP_ORBIT_DISTANCE_MAX * orbit.max),
&create_circle(position.pos(), SHIP_ORBIT_DISTANCE_MAX * orbit.max()),
);

gl::blend_func(gl::SRC_ALPHA, gl::ONE_MINUS_SRC_ALPHA);
@@ -91,11 +91,13 @@ impl<'a> System<'a> for Fleets {
0,
format!(
"F:{}\nB:{}\nT:{}",
fleet.count.fighter, fleet.count.bomber, fleet.count.transporter
fleet.count().fighter,
fleet.count().bomber,
fleet.count().transporter
),
)
.panic("Unable to update text")
.render_offset(&camera.world_to_window(position.pos));
.render_offset(&camera.world_to_window(*position.pos()));
}

gl::blend_equation(gl::FUNC_ADD);
@@ -103,7 +105,7 @@ impl<'a> System<'a> for Fleets {
}
}

fn create_circle(p: Vector2f, r: f32) -> Vec<Vector2f> {
fn create_circle(p: &Vector2f, r: f32) -> Vec<Vector2f> {
let mut points = Vec::new();

for i in 0..=180 {


+ 10
- 7
space-crush-app/src/debug/ships.rs View File

@@ -33,25 +33,28 @@ impl<'a> System<'a> for Ships {
gl::blend_func(gl::SRC_ALPHA, gl::ONE);

for (position, velocity, ship) in (&positions, &velocities, &ships).join() {
let ship_pos = position.pos;
let ship_pos = position.pos();

geometry.render_lines(
Vector4f::new(0.0, 0.0, 1.0, 0.2),
&[ship_pos, ship_pos + velocity.dir * velocity.speed],
&[*ship_pos, ship_pos + velocity.dir() * velocity.speed()],
);
geometry.render_lines(
Vector4f::new(1.0, 0.0, 0.0, 0.2),
&[ship_pos, ship_pos + ship.target_dir * 100.0],
&[*ship_pos, ship_pos + ship.target_dir() * 100.0],
);
geometry.render_lines(
Vector4f::new(1.0, 1.0, 1.0, 0.2),
&[ship_pos, ship.target_pos],
&[*ship_pos, *ship.target_pos()],
);

if let ShipObstacle::Known(obstacle) = ship.obstacle {
let obstacle_pos = continue_if_none!(positions.get(obstacle)).pos;
if let ShipObstacle::Known(obstacle) = ship.obstacle() {
let obstacle_pos = continue_if_none!(positions.get(obstacle)).pos();

geometry.render_lines(Vector4f::new(0.0, 1.0, 0.0, 0.2), &[ship_pos, obstacle_pos]);
geometry.render_lines(
Vector4f::new(0.0, 1.0, 0.0, 0.2),
&[*ship_pos, *obstacle_pos],
);
}
}



+ 27
- 59
space-crush-app/src/main.rs View File

@@ -57,11 +57,10 @@ fn create_world(world: &mut World, player_id: Entity) {
matrix::Angle,
vector::{Vector2f, Vector4f},
};
use smallvec::smallvec;
use space_crush_common::{
components::{
Asteroid, AsteroidType, Fleet, FleetOwned, Obstacle, Orbit, OrbitOwned, Planet, Player,
PlayerOwned, Position, Shape, Ship, ShipType, Velocity,
PlayerOwned, Position, Ship, ShipType, Velocity,
},
misc::{PersistWorld, Persistence},
};
@@ -71,13 +70,7 @@ fn create_world(world: &mut World, player_id: Entity) {

world
.system_data::<WriteStorage<Player>>()
.insert(
player_id,
Player {
index: 0,
color: Vector4f::new(0.0, 0.5, 1.0, 0.1),
},
)
.insert(player_id, Player::new(Vector4f::new(0.0, 0.5, 1.0, 0.1)))
.unwrap();

let planets = (0..3)
@@ -88,16 +81,9 @@ fn create_world(world: &mut World, player_id: Entity) {
world
.create_entity()
.marked::<<PersistWorld as Persistence>::Marker>()
.with(PlayerOwned { owner: player_id })
.with(Position {
pos: Vector2f::new(x, y),
shape: Shape::Circle(250.0),
})
.with(Orbit {
min: 325.0,
max: 425.0,
fleets: smallvec![],
})
.with(PlayerOwned::new(player_id))
.with(Position::circle(Vector2f::new(x, y), 250.0))
.with(Orbit::new(325.0, 425.0))
.with(Obstacle {})
.with(Planet {})
.build()
@@ -114,31 +100,22 @@ fn create_world(world: &mut World, player_id: Entity) {
world
.create_entity()
.marked::<<PersistWorld as Persistence>::Marker>()
.with(Position {
pos: Vector2f::new(x, y),
shape: Shape::Circle(100.0),
})
.with(Orbit {
min: 125.0,
max: 175.0,
fleets: smallvec![],
})
.with(Position::circle(Vector2f::new(x, y), 100.0))
.with(Orbit::new(125.0, 175.0))
.with(Obstacle {})
.with(Asteroid {
type_: match i_x * i_y {
-1 => AsteroidType::Metal,
1 => AsteroidType::Crystal,
_ => unreachable!(),
},
})
.with(Asteroid::new(match i_x * i_y {
-1 => AsteroidType::Metal,
1 => AsteroidType::Crystal,
_ => unreachable!(),
}))
.build();
}

let fleet_id = world
.create_entity()
.marked::<<PersistWorld as Persistence>::Marker>()
.with(PlayerOwned { owner: player_id })
.with(OrbitOwned { owner: planets[1] })
.with(PlayerOwned::new(player_id))
.with(OrbitOwned::new(planets[1]))
.with(Fleet::default())
.build();

@@ -152,28 +129,19 @@ fn create_world(world: &mut World, player_id: Entity) {
world
.create_entity()
.marked::<<PersistWorld as Persistence>::Marker>()
.with(PlayerOwned { owner: player_id })
.with(FleetOwned { owner: fleet_id })
.with(Position {
pos: Vector2f::new(x, y),
shape: Shape::Dot,
})
.with(Velocity {
dir: Vector2f::new(random::<f32>() - 0.5, random::<f32>() - 0.5).normalize(),
speed: 100.0,
})
.with(Ship {
type_: match i % 3 {
0 => ShipType::Fighter,
1 => ShipType::Bomber,
2 => ShipType::Transporter,
_ => unreachable!(),
},
agility: Angle::Deg(360.0),
target_pos: Default::default(),
target_dir: Default::default(),
obstacle: Default::default(),
})
.with(PlayerOwned::new(player_id))
.with(FleetOwned::new(fleet_id))
.with(Position::dot(Vector2f::new(x, y)))
.with(Velocity::new(
Vector2f::new(random::<f32>() - 0.5, random::<f32>() - 0.5).normalize(),
100.0,
))
.with(Ship::new(match i % 3 {
0 => ShipType::Fighter,
1 => ShipType::Bomber,
2 => ShipType::Transporter,
_ => unreachable!(),
}))
.build();
}
}

+ 6
- 6
space-crush-app/src/render/asteroids.rs View File

@@ -86,17 +86,17 @@ impl<'a> System<'a> for Asteroids {
let _guard = BindGuard::new(&self.program);

for (position, asteroid, owned) in (&position, &asteroid, owned.maybe()).join() {
let p_x = position.pos.x;
let p_y = position.pos.y;
let s = position.shape.circle().unwrap_or(ASTEROID_SIZE);
let p_x = position.pos().x;
let p_y = position.pos().y;
let s = position.shape().circle().unwrap_or(ASTEROID_SIZE);

let _guard = match asteroid.type_ {
let _guard = match asteroid.type_() {
AsteroidType::Metal => BindGuard::new(&self.texture_metal),
AsteroidType::Crystal => BindGuard::new(&self.texture_crystal),
};

let c = match owned.and_then(|owned| player.get(owned.owner)) {
Some(pv) => &pv.color,
let c = match owned.and_then(|owned| player.get(owned.owner())) {
Some(pv) => pv.color(),
None => &PLAYER_COLOR_DEFAULT,
};



+ 25
- 25
space-crush-app/src/render/fleet_select.rs View File

@@ -194,12 +194,12 @@ impl FleetSelect {
let pos = d.camera.view_to_world(d.input_state.mouse_pos);
let selection = d.game_state.selection.take();
for (position, orbit) in (&d.positions, &d.orbits).join() {
let r = orbit.max * orbit.max;
if (position.pos - pos).length_sqr() <= r {
let r = orbit.max() * orbit.max();
if (position.pos() - pos).length_sqr() <= r {
let player_id = d.game_state.player_id;
let player = player!(&d, player_id);
let player_index = player.index;
let fleet_id = continue_if_none!(orbit.fleets.get(player_index));
let player_index = player.index();
let fleet_id = continue_if_none!(orbit.fleets().get(player_index));
let fleet_id = *continue_if_none!(fleet_id);

d.game_state.selection = match selection {
@@ -225,7 +225,7 @@ impl FleetSelect {
self.mouse_pos = d.input_state.mouse_pos;
self.select_mode = SelectMode::Init(timeout);
self.values_changed_once = false;
self.set_count(selection.count, &fleet.count);
self.set_count(selection.count, &fleet.count());

break;
}
@@ -282,12 +282,12 @@ impl FleetSelect {
/* calculate values */
let selection = selection!(&d);
let orbit_owned = orbit_owned!(&d, selection.fleet);
let position = position!(&d, orbit_owned.owner);
let position = position!(&d, orbit_owned.owner());
let fleet = fleet!(&d, selection.fleet);

self.marker = d.camera.view_to_world(self.mouse_pos) - position.pos;
self.marker = d.camera.view_to_world(self.mouse_pos) - position.pos();
self.zoom = d.camera.view().axis_x.as_vec3().length();
self.shape_size = position.shape.radius();
self.shape_size = position.shape().radius();
self.ring0 = self.shape_size + FLEET_SELECT_OFFSET / self.zoom;
self.ring1 = self.ring0 + FLEET_SELECT_WIDTH / self.zoom;

@@ -314,10 +314,10 @@ impl FleetSelect {
x @ 0..=2 => {
let mut count = selection.count;
count[x] = usize::MAX;
self.set_count(count, &fleet.count);
self.set_count(count, fleet.count());

self.values[x] = 1.0;
self.update_values(&fleet.count);
self.update_values(fleet.count());
}
_ => {
self.count = ShipCount::all();
@@ -332,14 +332,14 @@ impl FleetSelect {
match sector {
x @ 0..=2 => {
let mut count = selection.count;
count[x] = (fleet.count[x] as f32 * value).round() as usize;
self.set_count(count, &fleet.count);
count[x] = (fleet.count()[x] as f32 * value).round() as usize;
self.set_count(count, fleet.count());

self.values[x] = value;
self.update_values(&fleet.count);
self.update_values(fleet.count());
}
_ => {
self.count = fleet.count * value;
self.count = *fleet.count() * value;
self.values = value.into();
}
}
@@ -348,10 +348,10 @@ impl FleetSelect {
x @ 0..=2 => {
let mut count = selection.count;
count[x] = 0;
self.set_count(count, &fleet.count);
self.set_count(count, fleet.count());

self.values[x] = 0.0;
self.update_values(&fleet.count);
self.update_values(fleet.count());
}
_ => {
self.count = Default::default();
@@ -361,7 +361,7 @@ impl FleetSelect {
}

/* update texts */
let c = self.count.merge(&fleet.count);
let c = self.count.merge(fleet.count());
let _guard = self.cache.begin_update();
self.text_total
.update(0, c.total().to_string())
@@ -436,13 +436,13 @@ impl FleetSelect {
/* extract system data */
let selection = selection!(&d);
let orbit_owned = orbit_owned!(&d, selection.fleet);
let position = position!(&d, orbit_owned.owner);
let position = position!(&d, orbit_owned.owner());

/* calculate shared values */
let size = self.ring1 + 50.0;
let rings = Vector2f::new(self.ring0 / size, self.ring1 / size);
let px = position.pos.x;
let py = position.pos.y;
let px = position.pos().x;
let py = position.pos().y;
let m = Matrix4f::new(
Vector4f::new(size, 0.0, 0.0, 0.0),
Vector4f::new(0.0, size, 0.0, 0.0),
@@ -485,20 +485,20 @@ impl FleetSelect {
if is_simple {
self.text_total
.color(Vector4f::new(1.0, 1.0, 1.0, alpha))
.render_offset(&self.text_pos(self.marker, position.pos, d));
.render_offset(&self.text_pos(self.marker, *position.pos(), d));
} else {
self.text_total
.color(Vector4f::new(1.0, 1.0, 1.0, alpha))
.render_offset(&self.text_pos((0.0, 1.0), position.pos, d));
.render_offset(&self.text_pos((0.0, 1.0), *position.pos(), d));
self.text_fighter
.color(Vector4f::new(1.0, 1.0, 1.0, alpha))
.render_offset(&self.text_pos((1.0, 0.0), position.pos, d));
.render_offset(&self.text_pos((1.0, 0.0), *position.pos(), d));
self.text_bomber
.color(Vector4f::new(1.0, 1.0, 1.0, alpha))
.render_offset(&self.text_pos((0.0, -1.0), position.pos, d));
.render_offset(&self.text_pos((0.0, -1.0), *position.pos(), d));
self.text_transporter
.color(Vector4f::new(1.0, 1.0, 1.0, alpha))
.render_offset(&self.text_pos((-1.0, 0.0), position.pos, d));
.render_offset(&self.text_pos((-1.0, 0.0), *position.pos(), d));
}
}



+ 5
- 5
space-crush-app/src/render/planets.rs View File

@@ -84,12 +84,12 @@ impl<'a> System<'a> for Planets {
let _guard = BindGuard::new(&self.texture);

for (p, _, owned) in (&position, &planet, owned.maybe()).join() {
let p_x = p.pos.x;
let p_y = p.pos.y;
let s = p.shape.circle().unwrap_or(PLANET_SIZE);
let p_x = p.pos().x;
let p_y = p.pos().y;
let s = p.shape().circle().unwrap_or(PLANET_SIZE);

let c = match owned.and_then(|owned| player.get(owned.owner)) {
Some(pv) => &pv.color,
let c = match owned.and_then(|owned| player.get(owned.owner())) {
Some(pv) => &pv.color(),
None => &PLAYER_COLOR_DEFAULT,
};



+ 7
- 7
space-crush-app/src/render/ships.rs View File

@@ -90,21 +90,21 @@ impl<'a> System<'a> for Ships {
let _guard = BindGuard::new(&self.program);

for (p, v, ship, owned) in (&position, &velocity, &ship, owned.maybe()).join() {
let _guard = match ship.type_ {
let _guard = match ship.type_() {
ShipType::Fighter => BindGuard::new(&self.texture_fighter),
ShipType::Bomber => BindGuard::new(&self.texture_bomber),
ShipType::Transporter => BindGuard::new(&self.texture_transporter),
};

let c = match owned.and_then(|owned| player.get(owned.owner)) {
Some(pv) => &pv.color,
let c = match owned.and_then(|owned| player.get(owned.owner())) {
Some(pv) => pv.color(),
None => &PLAYER_COLOR_DEFAULT,
};

let p_x = p.pos.x;
let p_y = p.pos.y;
let d_x = v.dir.x;
let d_y = v.dir.y;
let p_x = p.pos().x;
let p_y = p.pos().y;
let d_x = v.dir().x;
let d_y = v.dir().y;
let s = SHIP_SIZE;

let m = Matrix4f::new(


+ 9
- 8
space-crush-app/src/systems/fleet_control.rs View File

@@ -69,11 +69,11 @@ impl<'a> System<'a> for FleetControl {
MouseEvent::ButtonDown(button) if button == &config.input.fleet_move_button => {
let pos = camera.view_to_world(input_state.mouse_pos);
for (position, orbit) in (&positions, &orbits).join() {
let r = orbit.max * orbit.max;
if (position.pos - pos).length_sqr() <= r {
let r = orbit.max() * orbit.max();
if (position.pos() - pos).length_sqr() <= r {
let player_id = game_state.player_id;
let player = continue_if_none!(players.get(player_id));
let fleet_id = continue_if_none!(orbit.fleets.get(player.index));
let fleet_id = continue_if_none!(orbit.fleets().get(player.index()));
let fleet_id = *continue_if_none!(fleet_id);

self.target_fleet = Some(fleet_id);
@@ -82,23 +82,24 @@ impl<'a> System<'a> for FleetControl {
}
}
}
#[allow(unused_variables)] // TODO
MouseEvent::ButtonUp(button) if button == &config.input.fleet_move_button => {
let selection = game_state.selection.take();
let target_fleet = continue_if_none!(self.target_fleet.take());
let mut selection = continue_if_none!(selection);
let fleet = continue_if_none!(fleets.get(selection.fleet));
for (ship, fleet_owned, _) in (&ships, &mut fleet_owned, &fleet.owned).join() {
match &ship.type_ {
for (ship, fleet_owned, _) in (&ships, &mut fleet_owned, fleet.owned()).join() {
match ship.type_() {
ShipType::Fighter if selection.count.fighter > 0 => {
fleet_owned.owner = target_fleet;
// TODO fleet_owned.set_owner(target_fleet);
selection.count.fighter -= 1;
}
ShipType::Bomber if selection.count.bomber > 0 => {
fleet_owned.owner = target_fleet;
// TODO fleet_owned.set_owner(target_fleet);
selection.count.bomber -= 1;
}
ShipType::Transporter if selection.count.transporter > 0 => {
fleet_owned.owner = target_fleet;
// TODO fleet_owned.set_owner(target_fleet);
selection.count.transporter -= 1;
}
_ => (),


+ 14
- 2
space-crush-common/src/components/asteroid.rs View File

@@ -3,15 +3,27 @@ use specs::{Component, HashMapStorage};

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Asteroid {
pub type_: Type,
type_: Type,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
#[derive(Copy, Clone, Debug, Serialize, Deserialize)]
pub enum Type {
Metal,
Crystal,
}

impl Asteroid {
#[inline]
pub fn new(type_: Type) -> Self {
Self { type_ }
}

#[inline]
pub fn type_(&self) -> Type {
self.type_
}
}

impl Component for Asteroid {
type Storage = HashMapStorage<Self>;
}

+ 41
- 3
space-crush-common/src/components/fleet.rs View File

@@ -1,3 +1,5 @@
#![allow(dead_code)]

use serde::{Deserialize, Serialize};
use specs::{
error::NoError,
@@ -10,13 +12,13 @@ use crate::{components::ShipCount, misc::FlaggedStorage};

#[derive(Default, Debug, Clone)]
pub struct Fleet {
pub owned: BitSet,
pub count: ShipCount,
owned: BitSet,
count: ShipCount,
}

#[derive(Copy, Clone, Debug)]
pub struct Owned {
pub owner: Entity,
owner: Entity,
}

#[derive(Serialize, Deserialize)]
@@ -24,10 +26,46 @@ pub struct OwnedData<M> {
pub owner: M,
}

impl Fleet {
#[inline]
pub fn owned(&self) -> &BitSet {
&self.owned
}

#[inline]
pub(crate) fn owned_mut(&mut self) -> &mut BitSet {
&mut self.owned
}

#[inline]
pub fn count(&self) -> &ShipCount {
&self.count
}

#[inline]
pub(crate) fn count_mut(&mut self) -> &mut ShipCount {
&mut self.count
}
}

impl Component for Fleet {
type Storage = HashMapStorage<Self>;
}

impl Owned {
pub fn new(owner: Entity) -> Self {
Self { owner }
}

pub fn owner(&self) -> Entity {
self.owner
}

pub(crate) fn set_owner(&mut self, owner: Entity) {
self.owner = owner;
}
}

impl Component for Owned {
type Storage = FlaggedStorage<Self, VecStorage<Self>>;
}


+ 48
- 4
space-crush-common/src/components/orbit.rs View File

@@ -1,4 +1,5 @@
use serde::{Deserialize, Serialize};
use smallvec::smallvec;
use smallvec::SmallVec;
use specs::{
error::NoError,
@@ -10,9 +11,9 @@ use crate::misc::FlaggedStorage;

#[derive(Clone, Debug, Default)]
pub struct Orbit {
pub min: f32,
pub max: f32,
pub fleets: SmallVec<[Option<Entity>; 8]>,
min: f32,
max: f32,
fleets: Fleets,
}

#[derive(Serialize, Deserialize)]
@@ -24,7 +25,7 @@ pub struct OrbitData<M> {

#[derive(Copy, Clone, Debug)]
pub struct Owned {
pub owner: Entity,
owner: Entity,
}

#[derive(Serialize, Deserialize)]
@@ -32,6 +33,39 @@ pub struct OwnedData<M> {
pub owner: M,
}

type Fleets = SmallVec<[Option<Entity>; 8]>;

impl Orbit {
#[inline]
pub fn new(min: f32, max: f32) -> Self {
Self {
min,
max,
fleets: smallvec![],
}
}

#[inline]
pub fn min(&self) -> f32 {
self.min
}

#[inline]
pub fn max(&self) -> f32 {
self.max
}

#[inline]
pub fn fleets(&self) -> &Fleets {
&self.fleets
}

#[inline]
pub(crate) fn fleets_mut(&mut self) -> &mut Fleets {
&mut self.fleets
}
}

impl Component for Orbit {
type Storage = HashMapStorage<Self>;
}
@@ -71,6 +105,16 @@ where
}
}

impl Owned {
pub fn new(owner: Entity) -> Self {
Self { owner }
}

pub fn owner(&self) -> Entity {
self.owner
}
}

impl Component for Owned {
type Storage = FlaggedStorage<Self, HashMapStorage<Self>>;
}


+ 41
- 3
space-crush-common/src/components/player.rs View File

@@ -8,13 +8,13 @@ use specs::{

#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct Player {
pub index: usize,
pub color: Vector4f,
index: usize,
color: Vector4f,
}

#[derive(Copy, Clone, Debug)]
pub struct Owned {
pub owner: Entity,
owner: Entity,
}

#[derive(Serialize, Deserialize)]
@@ -22,10 +22,40 @@ pub struct OwnedData<M> {
pub owner: M,
}

impl Player {
#[inline]
pub fn new(color: Vector4f) -> Self {
Self {
index: next_index(),
color,
}
}

#[inline]
pub fn index(&self) -> usize {
self.index
}

#[inline]
pub fn color(&self) -> &Vector4f {
&self.color
}
}

impl Component for Player {
type Storage = HashMapStorage<Self>;
}

impl Owned {
pub fn new(owner: Entity) -> Self {
Self { owner }
}

pub fn owner(&self) -> Entity {
self.owner
}
}

impl Component for Owned {
type Storage = HashMapStorage<Self>;
}
@@ -55,3 +85,11 @@ where
Ok(Owned { owner })
}
}

fn next_index() -> usize {
use std::sync::atomic::{AtomicUsize, Ordering};

static NEXT_INDEX: AtomicUsize = AtomicUsize::new(0);

NEXT_INDEX.fetch_add(1, Ordering::Relaxed)
}

+ 30
- 2
space-crush-common/src/components/position.rs View File

@@ -4,8 +4,8 @@ use specs::{Component, VecStorage};

#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct Position {
pub pos: Vector2f,
pub shape: Shape,
pos: Vector2f,
shape: Shape,
}

#[derive(Clone, Debug, Serialize, Deserialize)]
@@ -14,6 +14,34 @@ pub enum Shape {
Circle(f32),
}

impl Position {
pub fn dot(pos: Vector2f) -> Self {
Self {
pos,
shape: Shape::Dot,
}
}

pub fn circle(pos: Vector2f, radius: f32) -> Self {
Self {
pos,
shape: Shape::Circle(radius),
}
}

pub fn pos(&self) -> &Vector2f {
&self.pos
}

pub fn shape(&self) -> &Shape {
&self.shape
}

pub(crate) fn pos_mut(&mut self) -> &mut Vector2f {
&mut self.pos
}
}

impl Component for Position {
type Storage = VecStorage<Self>;
}


+ 53
- 6
space-crush-common/src/components/ship.rs View File

@@ -1,18 +1,22 @@
use std::cmp::min;
use std::ops::{Index, IndexMut, Mul};

use glc::{matrix::Angle, vector::Vector2f};
use glc::vector::Vector2f;
use serde::{Deserialize, Serialize};
use specs::{Component, Entity, VecStorage};

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Ship {
pub type_: Type,
pub agility: Angle<f32>,
pub target_pos: Vector2f,
pub target_dir: Vector2f,
type_: Type,

#[serde(skip)]
obstacle: Obstacle,

#[serde(skip)]
pub obstacle: Obstacle,
target_pos: Vector2f,

#[serde(skip)]
target_dir: Vector2f,
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
@@ -36,6 +40,49 @@ pub enum Type {
Transporter,
}

impl Ship {
#[inline]
pub fn new(type_: Type) -> Self {
Self {
type_,
obstacle: Default::default(),
target_pos: Default::default(),
target_dir: Default::default(),
}
}

#[inline]
pub fn type_(&self) -> Type {
self.type_
}

#[inline]
pub fn target_pos(&self) -> &Vector2f {
&self.target_pos
}

#[inline]
pub fn target_dir(&self) -> &Vector2f {
&self.target_dir
}

#[inline]
pub(crate) fn set_target(&mut self, pos: Vector2f, dir: Vector2f) {
self.target_pos = pos;
self.target_dir = dir;
}

#[inline]
pub fn obstacle(&self) -> Obstacle {
self.obstacle
}

#[inline]
pub(crate) fn set_obstacle(&mut self, value: Obstacle) {
self.obstacle = value;
}
}

impl Component for Ship {
type Storage = VecStorage<Self>;
}


+ 20
- 2
space-crush-common/src/components/velocity.rs View File

@@ -4,8 +4,26 @@ use specs::{Component, VecStorage};

#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct Velocity {
pub dir: Vector2f,
pub speed: f32,
dir: Vector2f,
speed: f32,
}

impl Velocity {
pub fn new(dir: Vector2f, speed: f32) -> Self {
Self { dir, speed }
}

pub fn dir(&self) -> &Vector2f {
&self.dir
}

pub fn dir_mut(&mut self) -> &mut Vector2f {
&mut self.dir
}

pub fn speed(&self) -> f32 {
self.speed
}
}

impl Component for Velocity {


+ 22
- 10
space-crush-common/src/systems/fleet_owned_update.rs View File

@@ -71,18 +71,24 @@ impl<'a> System<'a> for FleetOwnedUpdate {
for event in events {
match event {
ComponentEvent::Inserted(id, fleet_owned) => {
self.fleet_ids.add(fleet_owned.owner.id());
self.fleet_ids.add(fleet_owned.owner().id());
self.fleet_owned_ids.add(*id);
}
ComponentEvent::Modified(id, fleet_owned) => {
self.fleet_ids.add(fleet_owned.owner.id());
self.fleet_ids.add(fleet_owned.owner().id());
self.fleet_owned_ids.add(*id);
*self.old_fleet_ids.entry(*id).or_insert(fleet_owned.owner) = fleet_owned.owner;
*self
.old_fleet_ids
.entry(*id)
.or_insert_with(|| fleet_owned.owner()) = fleet_owned.owner();
}
ComponentEvent::Removed(id, fleet_owned) => {
self.fleet_ids.add(fleet_owned.owner.id());
self.fleet_ids.add(fleet_owned.owner().id());
self.fleet_owned_ids.add(*id);
*self.old_fleet_ids.entry(*id).or_insert(fleet_owned.owner) = fleet_owned.owner;
*self
.old_fleet_ids
.entry(*id)
.or_insert_with(|| fleet_owned.owner()) = fleet_owned.owner();
}
}
}
@@ -92,18 +98,24 @@ impl<'a> System<'a> for FleetOwnedUpdate {
let data = (&entities, &ships, &fleet_owned, &self.fleet_owned_ids);

for (ship_id, ship, fleet_owned, _) in data.join() {
let new_match = fleet_id == fleet_owned.owner;
let new_match = fleet_id == fleet_owned.owner();
let old_match = match self.old_fleet_ids.get(&ship_id.id()) {
Some(old_fleet_id) => fleet_id == *old_fleet_id,
None => false,
};

if old_match && !new_match {
fleet_info.owned.remove(ship_id.id());
fleet_info.count[ship.type_] = fleet_info.count[ship.type_].saturating_sub(1);
let count = fleet_info.count_mut();
let count = &mut count[ship.type_()];
*count = count.saturating_sub(1);

fleet_info.owned_mut().remove(ship_id.id());
} else if !old_match && new_match {
fleet_info.owned.add(ship_id.id());
fleet_info.count[ship.type_] += 1;
let count = fleet_info.count_mut();
let count = &mut count[ship.type_()];
*count += 1;

fleet_info.owned_mut().add(ship_id.id());
}
}
}


+ 1
- 1
space-crush-common/src/systems/movement.rs View File

@@ -32,7 +32,7 @@ impl<'a> System<'a> for Movement {
.for_each(|(position, velocity)| {
let delta = global.delta * global.world_speed;

position.pos = position.pos + velocity.dir * velocity.speed * delta;
*position.pos_mut() += velocity.dir() * velocity.speed() * delta;
});
}
}

+ 18
- 10
space-crush-common/src/systems/orbit_owned_update.rs View File

@@ -74,18 +74,24 @@ impl<'a> System<'a> for OrbitOwnedUpdate {
for event in events {
match event {
ComponentEvent::Inserted(id, orbit_owned) => {
self.orbit_ids.add(orbit_owned.owner.id());
self.orbit_ids.add(orbit_owned.owner().id());
self.orbit_owned_ids.add(*id);
}
ComponentEvent::Modified(id, orbit_owned) => {
self.orbit_ids.add(orbit_owned.owner.id());
self.orbit_ids.add(orbit_owned.owner().id());
self.orbit_owned_ids.add(*id);
*self.old_orbit_ids.entry(*id).or_insert(orbit_owned.owner) = orbit_owned.owner;
*self
.old_orbit_ids
.entry(*id)
.or_insert_with(|| orbit_owned.owner()) = orbit_owned.owner();
}
ComponentEvent::Removed(id, orbit_owned) => {
self.orbit_ids.add(orbit_owned.owner.id());
self.orbit_ids.add(orbit_owned.owner().id());
self.orbit_owned_ids.add(*id);
*self.old_orbit_ids.entry(*id).or_insert(orbit_owned.owner) = orbit_owned.owner;
*self
.old_orbit_ids
.entry(*id)
.or_insert_with(|| orbit_owned.owner()) = orbit_owned.owner();
}
}
}
@@ -100,20 +106,22 @@ impl<'a> System<'a> for OrbitOwnedUpdate {
);

for (fleet_id, orbit_owned, player_owned, _) in data.join() {
let new_match = orbit_id == orbit_owned.owner;
let new_match = orbit_id == orbit_owned.owner();
let old_match = match self.old_orbit_ids.get(&fleet_id.id()) {
Some(old_orbit_id) => orbit_id == *old_orbit_id,
None => false,
};

let player_id = player_owned.owner.id() as usize;
let player_id = player_owned.owner().id() as usize;
if old_match && !new_match {
if let Some(fleet) = orbit.fleets.get_mut(player_id) {
if let Some(fleet) = orbit.fleets_mut().get_mut(player_id) {
*fleet = None;
}
} else if !old_match && new_match {
orbit.fleets.resize_with(player_id + 1, Default::default);
orbit.fleets[player_id] = Some(fleet_id);
orbit
.fleets_mut()
.resize_with(player_id + 1, Default::default);
orbit.fleets_mut()[player_id] = Some(fleet_id);
}
}
}


+ 45
- 44
space-crush-common/src/systems/ships.rs View File

@@ -139,24 +139,27 @@ impl Processor<'_> {
position: &Position,
fleet_owned: &FleetOwned,
) {
let fleet_id = fleet_owned.owner;
let fleet_id = fleet_owned.owner();
let orbit_owned = return_if_none!(self.orbit_owned.get(fleet_id));
let orbit_id = orbit_owned.owner;
let orbit_id = orbit_owned.owner();
let orbit = return_if_none!(self.orbits.get(orbit_id));
let orbit_pos = return_if_none!(self.positions.get(orbit_id)).pos;
let ship_pos = position.pos;
let target_pos = ship.target_pos;
let target_dir = ship.target_dir;
let orbit_pos = return_if_none!(self.positions.get(orbit_id)).pos();
let ship_pos = position.pos();
let target_pos = ship.target_pos();
let target_dir = ship.target_dir();

let orbit_to_target = target_pos - orbit_pos;
let orbit_to_ship = ship_pos - orbit_pos;
let mut ship_to_target = target_pos - position.pos;
let mut ship_to_target = target_pos - ship_pos;

let r_ship = orbit_to_ship.length_sqr();
let r_target = orbit_to_target.length_sqr();

let target_in_orbit = (r_target <= sqr(orbit.max)) && (r_target >= sqr(orbit.min));
let ship_in_orbit = r_ship < sqr(SHIP_ORBIT_DISTANCE_MAX * orbit.max);
let orbit_min = orbit.min();
let orbit_max = orbit.max();

let target_in_orbit = (r_target <= sqr(orbit_max)) && (r_target >= sqr(orbit_min));
let ship_in_orbit = r_ship < sqr(SHIP_ORBIT_DISTANCE_MAX * orbit_max);

let need_update = self.need_update.contains(id);
let has_target = target_dir.length_sqr() != 0.0;
@@ -164,9 +167,9 @@ impl Processor<'_> {

/* check and update target posistion */
if need_update || !has_target || passed_target || ship_in_orbit != target_in_orbit {
let target_pos = if ship_in_orbit && orbit.max > 0.0 {
let target_pos = if ship_in_orbit && orbit_max > 0.0 {
let orbit_to_ship_vec3 = Vector3f::new(orbit_to_ship.x, orbit_to_ship.y, 0.0);
let ship_dir_vec3 = Vector3f::new(velocity.dir.x, velocity.dir.y, 0.0);
let ship_dir_vec3 = velocity.dir().into_vec3();

let dir = if orbit_to_ship_vec3.cross(&ship_dir_vec3).z > 0.0 {
1.0
@@ -174,34 +177,35 @@ impl Processor<'_> {
-1.0
};

let add = SHIP_ORBIT_ANGLE_DELTA_MIN + SHIP_ORBIT_ANGLE_DELTA_RND * random();
let angle = orbit_to_ship.angle2(&VECTOR_2F_POS_X);
let angle = angle + add * dir / orbit.max;
let radius = orbit.min + (orbit.max - orbit.min) * random::<f32>();
let orbit_min = orbit.min();
let orbit_max = orbit.max();

let add = SHIP_ORBIT_ANGLE_DELTA_MIN + SHIP_ORBIT_ANGLE_DELTA_RND * random::<f32>();
let angle = orbit_to_ship.angle2(&VECTOR_2F_POS_X) + add * dir / orbit_max;
let radius = orbit_min + (orbit_max - orbit_min) * random::<f32>();

Vector2f::new(
orbit_pos.x + radius * angle.cos(),
orbit_pos.y + radius * angle.sin(),
)
} else {
ship.obstacle = ShipObstacle::Search;
ship.set_obstacle(ShipObstacle::Search);

orbit_pos
*orbit_pos
};

ship.target_pos = target_pos;
ship.target_dir = (target_pos - ship_pos).normalize();
ship.set_target(target_pos, (target_pos - ship_pos).normalize());

ship_to_target = target_pos - ship_pos;
}

/* check if obstacle is still valid */
if ship_in_orbit {
ship.obstacle = ShipObstacle::Done;
} else if let ShipObstacle::Known(obstacle) = ship.obstacle {
ship.set_obstacle(ShipObstacle::Done);
} else if let ShipObstacle::Known(obstacle) = ship.obstacle() {
if let Some(position) = self.positions.get(obstacle) {
let obstacle_orbit = self.orbits.get(obstacle).unwrap();
let obstacle_pos = position.pos;
let obstacle_pos = position.pos();
let ship_to_obstacle = obstacle_pos - ship_pos;

let obstacle_angle = ship_to_target
@@ -210,22 +214,22 @@ impl Processor<'_> {
.into_inner()
.abs();

let orbit_sqr = obstacle_orbit.max * obstacle_orbit.max;
let orbit_sqr = obstacle_orbit.max() * obstacle_orbit.max();
if (obstacle_angle > 90.0 && ship_to_obstacle.length_sqr() > orbit_sqr)
|| obstacle_angle > 170.0
{
ship.obstacle = ShipObstacle::Search;
ship.set_obstacle(ShipObstacle::Search);
}
} else {
ship.obstacle = ShipObstacle::Search;
ship.set_obstacle(ShipObstacle::Search);
}
}

/* find obstacle */
if !ship_in_orbit && ship.obstacle == ShipObstacle::Search {
if !ship_in_orbit && ship.obstacle() == ShipObstacle::Search {
let mut dist_sqr = f32::MAX;
for (e, position, _) in (self.entities, self.positions, self.obstacles).join() {
let obstacle_pos = position.pos;
let obstacle_pos = position.pos();
let ship_to_obstacle = obstacle_pos - ship_pos;

if ship_to_target * ship_to_obstacle < 0.0 {
@@ -235,31 +239,32 @@ impl Processor<'_> {
let len_sqr = ship_to_obstacle.length_sqr();
if len_sqr < dist_sqr {
dist_sqr = len_sqr;
ship.obstacle = ShipObstacle::Known(e);
ship.set_obstacle(ShipObstacle::Known(e));
}
}

if let ShipObstacle::Known(e) = ship.obstacle {
if e == fleet_owned.owner {
ship.obstacle = ShipObstacle::Done;
if let ShipObstacle::Known(e) = ship.obstacle() {
if e == fleet_owned.owner() {
ship.set_obstacle(ShipObstacle::Done);
}
}
}

/* check the obstacle */
let mut expected_dir = ship_to_target;
if let ShipObstacle::Known(obstacle) = ship.obstacle {
if let ShipObstacle::Known(obstacle) = ship.obstacle() {
let obstacle_pos = self.positions.get(obstacle).unwrap();
let obstacle_orbit = self.orbits.get(obstacle).unwrap();
let ship_to_obstacle = obstacle_pos.pos - ship_pos;
let ship_to_obstacle = obstacle_pos.pos() - ship_pos;

let orbit_min = obstacle_orbit.min();
let orbit_max = obstacle_orbit.max();

let orbit = ship_to_obstacle.length();
if orbit < obstacle_orbit.max {
let orbit_min = obstacle_orbit.min;
let orbit_max = obstacle_orbit.max;
if orbit < orbit_max {
let mut tangent = Vector2f::new(-ship_to_obstacle.y, ship_to_obstacle.x);

let radius = obstacle_pos.shape.radius();
let radius = obstacle_pos.shape().radius();
let mut adjust_low = linear_step(orbit_min, radius, orbit);
let adjust_high = 1.0 - linear_step(orbit_max, orbit_min, orbit);

@@ -277,17 +282,13 @@ impl Processor<'_> {
}

/* update ship direction */
let angle = expected_dir.angle2(&velocity.dir);
let angle = expected_dir.angle2(&velocity.dir());
if angle.into_inner().abs() > 0.0001 {
let dir = angle.into_inner() / angle.abs().into_inner();
let agility = if ship_in_orbit {
SHIP_ORBIT_AGILITY
} else {
ship.agility
};
let agility = SHIP_ORBIT_AGILITY;
let rot_speed = agility * linear_step(0.0, 45.0, angle.abs().into_deg().into_inner());

velocity.dir = Matrix3f::rotate(rot_speed * -dir * self.delta).transform(velocity.dir);
*velocity.dir_mut() *= Matrix3f::rotate(rot_speed * -dir * self.delta);
}
}
}

Loading…
Cancel
Save