mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
101 lines
3.6 KiB
Rust
101 lines
3.6 KiB
Rust
use common::{
|
|
comp::{Controller, MountState, Mounting, Ori, Pos, Vel},
|
|
metrics::SysMetrics,
|
|
span,
|
|
uid::UidAllocator,
|
|
};
|
|
use specs::{
|
|
saveload::{Marker, MarkerAllocator},
|
|
Entities, Join, Read, ReadExpect, System, WriteStorage,
|
|
};
|
|
use vek::*;
|
|
|
|
/// This system is responsible for controlling mounts
|
|
pub struct Sys;
|
|
impl<'a> System<'a> for Sys {
|
|
#[allow(clippy::type_complexity)]
|
|
type SystemData = (
|
|
Read<'a, UidAllocator>,
|
|
ReadExpect<'a, SysMetrics>,
|
|
Entities<'a>,
|
|
WriteStorage<'a, Controller>,
|
|
WriteStorage<'a, MountState>,
|
|
WriteStorage<'a, Mounting>,
|
|
WriteStorage<'a, Pos>,
|
|
WriteStorage<'a, Vel>,
|
|
WriteStorage<'a, Ori>,
|
|
);
|
|
|
|
fn run(
|
|
&mut self,
|
|
(
|
|
uid_allocator,
|
|
sys_metrics,
|
|
entities,
|
|
mut controllers,
|
|
mut mount_state,
|
|
mut mountings,
|
|
mut positions,
|
|
mut velocities,
|
|
mut orientations,
|
|
): Self::SystemData,
|
|
) {
|
|
let start_time = std::time::Instant::now();
|
|
span!(_guard, "run", "mount::Sys::run");
|
|
// Mounted entities.
|
|
for (entity, mut mount_states) in (&entities, &mut mount_state.restrict_mut()).join() {
|
|
match mount_states.get_unchecked() {
|
|
MountState::Unmounted => {},
|
|
MountState::MountedBy(mounter_uid) => {
|
|
// Note: currently controller events are not passed through since none of them
|
|
// are currently relevant to controlling the mounted entity
|
|
if let Some((inputs, mounter)) = uid_allocator
|
|
.retrieve_entity_internal(mounter_uid.id())
|
|
.and_then(|mounter| {
|
|
controllers
|
|
.get(mounter)
|
|
.map(|c| (c.inputs.clone(), mounter))
|
|
})
|
|
{
|
|
// TODO: consider joining on these? (remember we can use .maybe())
|
|
let pos = positions.get(entity).copied();
|
|
let ori = orientations.get(entity).copied();
|
|
let vel = velocities.get(entity).copied();
|
|
if let (Some(pos), Some(ori), Some(vel)) = (pos, ori, vel) {
|
|
let _ = positions.insert(mounter, Pos(pos.0 + Vec3::unit_z() * 1.0));
|
|
let _ = orientations.insert(mounter, ori);
|
|
let _ = velocities.insert(mounter, vel);
|
|
}
|
|
if let Some(controller) = controllers.get_mut(entity) {
|
|
*controller = Controller {
|
|
inputs,
|
|
..Default::default()
|
|
}
|
|
}
|
|
} else {
|
|
*(mount_states.get_mut_unchecked()) = MountState::Unmounted;
|
|
}
|
|
},
|
|
}
|
|
}
|
|
|
|
let mut to_unmount = Vec::new();
|
|
for (entity, Mounting(mountee_uid)) in (&entities, &mountings).join() {
|
|
if uid_allocator
|
|
.retrieve_entity_internal(mountee_uid.id())
|
|
.filter(|mountee| entities.is_alive(*mountee))
|
|
.is_none()
|
|
{
|
|
to_unmount.push(entity);
|
|
}
|
|
}
|
|
for entity in to_unmount {
|
|
mountings.remove(entity);
|
|
}
|
|
sys_metrics.mount_ns.store(
|
|
start_time.elapsed().as_nanos() as u64,
|
|
std::sync::atomic::Ordering::Relaxed,
|
|
);
|
|
}
|
|
}
|