veloren/common/sys/src/mount.rs

104 lines
3.8 KiB
Rust
Raw Normal View History

use common::{
comp::{Body, Controller, MountState, Mounting, Ori, Pos, Vel},
uid::UidAllocator,
2019-11-24 20:12:03 +00:00
};
use common_ecs::{Job, Origin, Phase, System};
2019-11-04 00:57:36 +00:00
use specs::{
saveload::{Marker, MarkerAllocator},
Entities, Join, Read, ReadStorage, WriteStorage,
2019-11-04 00:57:36 +00:00
};
use vek::*;
/// This system is responsible for controlling mounts
#[derive(Default)]
2019-11-04 00:57:36 +00:00
pub struct Sys;
2021-03-08 11:13:59 +00:00
impl<'a> System<'a> for Sys {
#[allow(clippy::type_complexity)]
2019-11-04 00:57:36 +00:00
type SystemData = (
Read<'a, UidAllocator>,
Entities<'a>,
WriteStorage<'a, Controller>,
WriteStorage<'a, MountState>,
WriteStorage<'a, Mounting>,
WriteStorage<'a, Pos>,
WriteStorage<'a, Vel>,
WriteStorage<'a, Ori>,
ReadStorage<'a, Body>,
2019-11-04 00:57:36 +00:00
);
const NAME: &'static str = "mount";
const ORIGIN: Origin = Origin::Common;
const PHASE: Phase = Phase::Create;
2019-11-04 00:57:36 +00:00
fn run(
2021-03-08 11:13:59 +00:00
_job: &mut Job<Self>,
2019-11-04 00:57:36 +00:00
(
uid_allocator,
entities,
mut controllers,
mut mount_state,
mut mountings,
mut positions,
mut velocities,
mut orientations,
bodies,
2019-11-04 00:57:36 +00:00
): Self::SystemData,
) {
// Mounted entities.
for (entity, mut mount_states, body) in
(&entities, &mut mount_state.restrict_mut(), bodies.maybe()).join()
{
2019-11-04 00:57:36 +00:00
match mount_states.get_unchecked() {
MountState::Unmounted => {},
2019-11-04 00:57:36 +00:00
MountState::MountedBy(mounter_uid) => {
// Note: currently controller events are not passed through since none of them
// are currently relevant to controlling the mounted entity
2021-03-15 04:26:19 +00:00
if let Some((inputs, queued_inputs, mounter)) = uid_allocator
2019-11-04 00:57:36 +00:00
.retrieve_entity_internal(mounter_uid.id())
.and_then(|mounter| {
controllers
.get(mounter)
2021-03-15 04:26:19 +00:00
.map(|c| (c.inputs.clone(), c.queued_inputs.clone(), mounter))
})
2019-11-04 00:57:36 +00:00
{
// 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 mounting_offset =
body.map_or(Vec3::unit_z(), Body::mounting_offset);
let _ = positions.insert(mounter, Pos(pos.0 + mounting_offset));
2019-11-04 00:57:36 +00:00
let _ = orientations.insert(mounter, ori);
let _ = velocities.insert(mounter, vel);
}
if let Some(controller) = controllers.get_mut(entity) {
*controller = Controller {
inputs,
2021-03-15 04:26:19 +00:00
queued_inputs,
..Default::default()
}
}
2019-11-04 00:57:36 +00:00
} else {
*(mount_states.get_mut_unchecked()) = MountState::Unmounted;
}
},
2019-11-04 00:57:36 +00:00
}
}
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);
}
}
}