119 lines
3.1 KiB
Rust
119 lines
3.1 KiB
Rust
use std::{fmt::Display, time::Duration};
|
|
|
|
use bevy::prelude::Reflect;
|
|
use serde::{Deserialize, Serialize};
|
|
use uuid::Uuid;
|
|
|
|
use super::prelude::*;
|
|
|
|
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Serialize, Deserialize, Reflect)]
|
|
pub struct TravelGroupId(Uuid);
|
|
|
|
impl TravelGroupId {
|
|
pub fn generate() -> Self {
|
|
Self(Uuid::new_v4())
|
|
}
|
|
}
|
|
|
|
impl Display for TravelGroupId {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
write!(f, "trav-{}", self.0)
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Copy, Eq, PartialEq, Debug, Serialize, Deserialize, Reflect)]
|
|
pub enum WorldPoint {
|
|
Coords(Coords),
|
|
Site(SiteId),
|
|
}
|
|
|
|
impl Display for WorldPoint {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
match *self {
|
|
Self::Site(site_id) => write!(f, "[{site_id}]"),
|
|
Self::Coords(coords) => write!(f, "{coords}"),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(PartialEq, Debug, Serialize, Deserialize, Reflect)]
|
|
pub struct TravelGroup {
|
|
id: TravelGroupId,
|
|
accumulated_movement: Kilometer,
|
|
pub creatures: Vec<Creature>,
|
|
pub position: Coords,
|
|
pub origin: Option<WorldPoint>,
|
|
pub destination: Option<WorldPoint>,
|
|
}
|
|
|
|
impl TravelGroup {
|
|
pub fn new(
|
|
creatures: Vec<Creature>,
|
|
position: Coords,
|
|
origin: Option<WorldPoint>,
|
|
destination: Option<WorldPoint>,
|
|
) -> Self {
|
|
Self {
|
|
id: TravelGroupId::generate(),
|
|
accumulated_movement: 0.,
|
|
creatures,
|
|
position,
|
|
origin,
|
|
destination,
|
|
}
|
|
}
|
|
|
|
pub fn id(&self) -> TravelGroupId {
|
|
self.id
|
|
}
|
|
|
|
/// The travel speed of the group in km/h
|
|
pub fn speed(&self) -> Kilometer {
|
|
// TODO: hard-coded, should depend on the creatures in the group
|
|
5.0
|
|
}
|
|
|
|
pub fn advance_time(&mut self, time: Duration) {
|
|
self.accumulated_movement += time.as_secs_f32() / 3600. * self.speed();
|
|
// while self.accumulated_movement >= Self::minimum_simulated_distance() {
|
|
// self.inner_tick();
|
|
// self.accumulated_movement -= Self::minimum_simulated_distance();
|
|
// }
|
|
}
|
|
|
|
pub fn insert(&mut self, creature: Creature) {
|
|
self.creatures.push(creature)
|
|
}
|
|
|
|
pub fn remove(&mut self, id: CreatureId) {
|
|
self.creatures.retain(|creature| creature.id() != id);
|
|
}
|
|
|
|
// fn inner_tick(&mut self) {
|
|
|
|
// }
|
|
}
|
|
|
|
impl Display for TravelGroup {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
write!(
|
|
f,
|
|
"travel group from {origin} to {destination} [{id}] [",
|
|
origin = self
|
|
.origin
|
|
.map_or("nowhere".to_string(), |point| format!("{point}")),
|
|
destination = self
|
|
.destination
|
|
.map_or("nowhere".to_string(), |point| format!("{point}")),
|
|
id = self.id
|
|
)?;
|
|
for creature in self.creatures.iter() {
|
|
write!(f, "\n\t{creature}")?;
|
|
}
|
|
if !self.creatures.is_empty() {
|
|
writeln!(f)?;
|
|
}
|
|
write!(f, "]")
|
|
}
|
|
}
|