Newer
Older
use bevy::math::Vec3Swizzles;
use bevy::prelude::*;
use serde::{Deserialize, Serialize};
use crate::persistance::SaveFileEvent;
use crate::states::Player;
use crate::system::utilities::format_distance;
use crate::world::encounters::EncounterState;
use crate::world::towns::{CurrentResidence, TravelPath, TravelTarget};
use crate::world::PathingResult;
#[derive(Component, Serialize, Deserialize, Debug, Copy, Clone, Default)]
pub struct DistanceTravelled(pub f32);
impl Deref for DistanceTravelled {
type Target = f32;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for DistanceTravelled {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
pub fn tick_travelling_merchant(
mut commands: Commands,
time: Res<Time>,
mut merchant_query: Query<(
Entity,
&mut Transform,
&mut TravelPath,
&mut TravelTarget,
&mut CurrentResidence,
mut autosave: EventWriter<SaveFileEvent>,
if encounter_state.is_in_encounter() {
return;
}
let delta = time.delta_seconds();
for (entity, mut transform, mut path, mut target, mut residence, mut high_score) in
&mut merchant_query
{
let step = path.get_step(transform.translation.xy(), 16.0) * delta;
high_score.0 += step.length();
transform.translation.sub_assign(step.extend(0.0));
match path.check_position(transform.translation.xy()) {
PathingResult::PathComplete => {
commands
.entity(entity)
.remove::<(TravelPath, TravelTarget)>();
*residence = CurrentResidence::RestingAt(target.0.clone());
autosave.send(SaveFileEvent::autosave());
}
PathingResult::NextNode => {
path.increment_indexes();
}
PathingResult::TravelTo(new_point) => {
transform.translation = new_point.extend(transform.translation.z);
}
PathingResult::Travelling => {}
}
}
}
pub struct WorldTickEvent;
pub fn track_travel(
mut tracked: Local<DistanceTravelled>,
player_query: Query<&DistanceTravelled, With<Player>>,
mut events: EventWriter<WorldTickEvent>,
) {
let before = **tracked.deref();
let after = {
if let Ok(player_dist) = player_query.get_single() {
*tracked = *player_dist;
*player_dist.deref()
} else {
before
}
};
if format_distance(before) % 5.0 > format_distance(after) % 5.0 {
log::info!("Ticking World Objects");