Describe directions relatively.
This commit is contained in:
parent
9b124e5640
commit
b2138d3e4c
49
src/core.rs
49
src/core.rs
|
@ -1,6 +1,7 @@
|
|||
use std::{
|
||||
cmp::{max, min},
|
||||
fmt::Display,
|
||||
ops::Sub,
|
||||
};
|
||||
|
||||
use bevy::{core::FloatOrd, prelude::*, transform::TransformSystem};
|
||||
|
@ -94,6 +95,23 @@ impl Angle {
|
|||
}
|
||||
}
|
||||
|
||||
impl Sub for Angle {
|
||||
type Output = Self;
|
||||
|
||||
fn sub(self, rhs: Self) -> Self::Output {
|
||||
match self {
|
||||
Angle::Degrees(v1) => match rhs {
|
||||
Angle::Degrees(v2) => Angle::Degrees(v1 - v2),
|
||||
Angle::Radians(v2) => Angle::Degrees(v1 - v2.to_degrees()),
|
||||
},
|
||||
Angle::Radians(v1) => match rhs {
|
||||
Angle::Degrees(v2) => Angle::Radians(v1 - v2.to_radians()),
|
||||
Angle::Radians(v2) => Angle::Radians(v1 - v2),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum MovementDirection {
|
||||
North,
|
||||
|
@ -282,23 +300,42 @@ pub trait PointLike {
|
|||
self.distance_squared(other).sqrt()
|
||||
}
|
||||
|
||||
fn bearing(&self, other: &dyn PointLike) -> f32 {
|
||||
fn bearing(&self, other: &dyn PointLike) -> Angle {
|
||||
let y = other.y() - self.y();
|
||||
let x = other.x() - self.x();
|
||||
y.atan2(x)
|
||||
Angle::Radians(y.atan2(x))
|
||||
}
|
||||
|
||||
fn direction(&self, other: &dyn PointLike) -> MovementDirection {
|
||||
let heading = self.bearing(other);
|
||||
MovementDirection::new(heading.to_degrees())
|
||||
self.bearing(other).into()
|
||||
}
|
||||
|
||||
fn direction_and_distance(&self, other: &dyn PointLike) -> String {
|
||||
fn direction_and_distance(&self, other: &dyn PointLike, yaw: Option<Angle>) -> String {
|
||||
let mut tokens: Vec<String> = vec![];
|
||||
let distance = self.distance(other).round() as i32;
|
||||
if distance > 0 {
|
||||
let tile_or_tiles = if distance == 1 { "tile" } else { "tiles" };
|
||||
let direction: String = self.direction(other).into();
|
||||
let direction: String = if let Some(yaw) = yaw {
|
||||
let bearing = self.bearing(other);
|
||||
let relative = (bearing - yaw).degrees();
|
||||
match relative {
|
||||
v if v <= 15. => "ahead".into(),
|
||||
v if v <= 45. => "ahead and left".into(),
|
||||
v if v <= 75. => "left and ahead".into(),
|
||||
v if v <= 105. => "left".into(),
|
||||
v if v <= 135. => "left and behind".into(),
|
||||
v if v <= 165. => "behind and left".into(),
|
||||
v if v <= 195. => "behind".into(),
|
||||
v if v <= 225. => "behind and right".into(),
|
||||
v if v <= 255. => "right and behind".into(),
|
||||
v if v <= 285. => "right".into(),
|
||||
v if v <= 315. => "right and ahead".into(),
|
||||
v if v <= 345. => "ahead and right".into(),
|
||||
_ => "ahead".into(),
|
||||
}
|
||||
} else {
|
||||
self.direction(other).into()
|
||||
};
|
||||
tokens.push(format!("{} {} {}", direction, distance, tile_or_tiles));
|
||||
}
|
||||
tokens.join(" ")
|
||||
|
|
|
@ -341,7 +341,7 @@ fn exploration_changed_announcement(
|
|||
} else {
|
||||
"Unknown".to_string()
|
||||
};
|
||||
let mut tokens: Vec<String> = vec![coordinates.direction_and_distance(exploring)];
|
||||
let mut tokens: Vec<String> = vec![coordinates.direction_and_distance(exploring, None)];
|
||||
if fog_of_war {
|
||||
tokens.push("in the fog of war".into());
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ use derive_more::{Deref, DerefMut};
|
|||
use shadowcast::{vision_distance, Context, InputGrid};
|
||||
|
||||
use crate::{
|
||||
core::{Coordinates, Player, PointLike},
|
||||
core::{Angle, Coordinates, Player, PointLike},
|
||||
log::Log,
|
||||
map::{ITileType, Map, MapConfig},
|
||||
};
|
||||
|
@ -222,7 +222,7 @@ fn log_visible(
|
|||
mut seen: Local<HashSet<Entity>>,
|
||||
mut recently_lost: Local<HashMap<Entity, Timer>>,
|
||||
mut log: Query<&mut Log>,
|
||||
viewers: Query<(&Viewshed, &Coordinates, &Player)>,
|
||||
viewers: Query<(&Viewshed, &Coordinates, &Transform), With<Player>>,
|
||||
map: Query<&Map>,
|
||||
names: Query<&Name>,
|
||||
players: Query<&Player>,
|
||||
|
@ -238,7 +238,7 @@ fn log_visible(
|
|||
}
|
||||
let mut new_seen = HashSet::new();
|
||||
if let Ok(mut log) = log.single_mut() {
|
||||
for (viewshed, coordinates, _) in viewers.iter() {
|
||||
for (viewshed, coordinates, transform) in viewers.iter() {
|
||||
for viewed_coordinates in &viewshed.visible {
|
||||
for map in map.iter() {
|
||||
let index = viewed_coordinates.to_index(map.width());
|
||||
|
@ -250,8 +250,10 @@ fn log_visible(
|
|||
if players.get(*entity).is_err() {
|
||||
if !seen.contains(&*entity) {
|
||||
let name = name.to_string();
|
||||
let location =
|
||||
coordinates.direction_and_distance(viewed_coordinates);
|
||||
let forward = transform.local_x();
|
||||
let yaw = Angle::Radians(forward.y.atan2(forward.x));
|
||||
let location = coordinates
|
||||
.direction_and_distance(viewed_coordinates, Some(yaw));
|
||||
log.push(format!("{}: {}", name, location));
|
||||
}
|
||||
new_seen.insert(*entity);
|
||||
|
|
Loading…
Reference in New Issue
Block a user