adventure-sim-rs/src/sim/travel_group.rs

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