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(WorldCoords), 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, pub position: WorldCoords, pub origin: Option, pub destination: Option, } impl TravelGroup { pub fn new( creatures: Vec, position: WorldCoords, origin: Option, destination: Option, ) -> 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, "]") } }