veloren/server/src/sys/waypoint.rs

61 lines
1.9 KiB
Rust
Raw Normal View History

use crate::client::Client;
2020-05-14 16:56:10 +00:00
use common::{
comp::{Player, Pos, Waypoint, WaypointArea},
resources::Time,
2020-05-14 16:56:10 +00:00
};
use common_ecs::{Job, Origin, Phase, System};
use common_net::msg::{Notification, ServerGeneral};
use specs::{Entities, Join, Read, ReadStorage, WriteStorage};
/// Cooldown time (in seconds) for "Waypoint Saved" notifications
const NOTIFY_TIME: f64 = 10.0;
2020-05-14 16:56:10 +00:00
/// This system updates player waypoints
/// TODO: Make this faster by only considering local waypoints
#[derive(Default)]
pub struct Sys;
2021-03-08 11:13:59 +00:00
impl<'a> System<'a> for Sys {
#[allow(clippy::type_complexity)]
type SystemData = (
Entities<'a>,
ReadStorage<'a, Pos>,
ReadStorage<'a, Player>,
ReadStorage<'a, WaypointArea>,
WriteStorage<'a, Waypoint>,
ReadStorage<'a, Client>,
Read<'a, Time>,
);
const NAME: &'static str = "waypoint";
const ORIGIN: Origin = Origin::Server;
const PHASE: Phase = Phase::Create;
fn run(
2021-03-08 11:13:59 +00:00
_job: &mut Job<Self>,
(
entities,
positions,
players,
waypoint_areas,
mut waypoints,
clients,
time,
): Self::SystemData,
) {
for (entity, player_pos, _, client) in (&entities, &positions, &players, &clients).join() {
for (waypoint_pos, waypoint_area) in (&positions, &waypoint_areas).join() {
2020-05-14 16:56:10 +00:00
if player_pos.0.distance_squared(waypoint_pos.0) < waypoint_area.radius().powi(2) {
if let Ok(wp_old) = waypoints.insert(entity, Waypoint::new(player_pos.0, *time))
{
if wp_old.map_or(true, |w| w.elapsed(*time) > NOTIFY_TIME) {
client.send_fallible(ServerGeneral::Notification(
Notification::WaypointSaved,
));
2020-05-14 16:56:10 +00:00
}
}
}
}
}
}
}