2020-12-01 00:28:00 +00:00
|
|
|
use common::{
|
2021-03-15 00:07:54 +00:00
|
|
|
comp::{Body, Controller, MountState, Mounting, Ori, Pos, Vel},
|
2020-12-13 17:11:55 +00:00
|
|
|
uid::UidAllocator,
|
2019-11-24 20:12:03 +00:00
|
|
|
};
|
2021-03-08 22:40:02 +00:00
|
|
|
use common_ecs::{Job, Origin, Phase, System};
|
2019-11-04 00:57:36 +00:00
|
|
|
use specs::{
|
|
|
|
saveload::{Marker, MarkerAllocator},
|
2021-03-15 00:07:54 +00:00
|
|
|
Entities, Join, Read, ReadStorage, WriteStorage,
|
2019-11-04 00:57:36 +00:00
|
|
|
};
|
|
|
|
use vek::*;
|
|
|
|
|
|
|
|
/// This system is responsible for controlling mounts
|
2021-03-04 14:00:16 +00:00
|
|
|
#[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 {
|
2020-06-10 19:47:36 +00:00
|
|
|
#[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>,
|
2021-03-15 00:07:54 +00:00
|
|
|
ReadStorage<'a, Body>,
|
2019-11-04 00:57:36 +00:00
|
|
|
);
|
|
|
|
|
2021-03-04 14:00:16 +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,
|
2021-03-15 00:07:54 +00:00
|
|
|
bodies,
|
2019-11-04 00:57:36 +00:00
|
|
|
): Self::SystemData,
|
|
|
|
) {
|
|
|
|
// Mounted entities.
|
2021-03-15 00:07:54 +00:00
|
|
|
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() {
|
2020-02-01 20:39:39 +00:00
|
|
|
MountState::Unmounted => {},
|
2019-11-04 00:57:36 +00:00
|
|
|
MountState::MountedBy(mounter_uid) => {
|
2019-12-31 21:37:55 +00:00
|
|
|
// 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())
|
2019-12-31 21:37:55 +00:00
|
|
|
.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-12-31 21:37:55 +00:00
|
|
|
})
|
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) {
|
2021-03-15 00:07:54 +00:00
|
|
|
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);
|
|
|
|
}
|
2020-12-01 00:28:00 +00:00
|
|
|
if let Some(controller) = controllers.get_mut(entity) {
|
2020-01-02 09:46:15 +00:00
|
|
|
*controller = Controller {
|
2019-12-31 21:37:55 +00:00
|
|
|
inputs,
|
2021-03-15 04:26:19 +00:00
|
|
|
queued_inputs,
|
2019-12-31 21:37:55 +00:00
|
|
|
..Default::default()
|
2020-01-02 09:46:15 +00:00
|
|
|
}
|
2020-12-01 00:28:00 +00:00
|
|
|
}
|
2019-11-04 00:57:36 +00:00
|
|
|
} else {
|
|
|
|
*(mount_states.get_mut_unchecked()) = MountState::Unmounted;
|
|
|
|
}
|
2020-02-01 20:39:39 +00:00
|
|
|
},
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|