2020-12-01 00:28:00 +00:00
|
|
|
use common::{
|
2022-01-15 20:15:38 +00:00
|
|
|
comp::{Body, Controller, Ori, Pos, Vel, ForceUpdate},
|
2020-12-13 17:11:55 +00:00
|
|
|
uid::UidAllocator,
|
2022-01-15 18:22:28 +00:00
|
|
|
mounting::{Mount, Rider},
|
|
|
|
link::Is,
|
|
|
|
uid::Uid,
|
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},
|
2022-01-15 18:22:28 +00:00
|
|
|
Entities, Join, Read, ReadStorage, WriteStorage, WriteExpect,
|
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>,
|
2022-01-15 18:22:28 +00:00
|
|
|
ReadStorage<'a, Uid>,
|
2019-11-04 00:57:36 +00:00
|
|
|
WriteStorage<'a, Controller>,
|
2022-01-15 18:22:28 +00:00
|
|
|
ReadStorage<'a, Is<Rider>>,
|
|
|
|
ReadStorage<'a, Is<Mount>>,
|
2019-11-04 00:57:36 +00:00
|
|
|
WriteStorage<'a, Pos>,
|
|
|
|
WriteStorage<'a, Vel>,
|
|
|
|
WriteStorage<'a, Ori>,
|
2022-01-15 20:15:38 +00:00
|
|
|
ReadStorage<'a, ForceUpdate>,
|
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,
|
2022-01-15 18:22:28 +00:00
|
|
|
uids,
|
2019-11-04 00:57:36 +00:00
|
|
|
mut controllers,
|
2022-01-15 18:22:28 +00:00
|
|
|
is_riders,
|
|
|
|
is_mounts,
|
2019-11-04 00:57:36 +00:00
|
|
|
mut positions,
|
|
|
|
mut velocities,
|
|
|
|
mut orientations,
|
2022-01-15 20:15:38 +00:00
|
|
|
force_updates,
|
2021-03-15 00:07:54 +00:00
|
|
|
bodies,
|
2019-11-04 00:57:36 +00:00
|
|
|
): Self::SystemData,
|
|
|
|
) {
|
2022-01-15 18:22:28 +00:00
|
|
|
// For each mount...
|
|
|
|
for (entity, is_mount, body) in (&entities, &is_mounts, bodies.maybe()).join() {
|
|
|
|
// ...find the rider...
|
|
|
|
let Some((inputs, queued_inputs, rider)) = uid_allocator
|
|
|
|
.retrieve_entity_internal(is_mount.rider.id())
|
|
|
|
.and_then(|rider| {
|
|
|
|
controllers
|
|
|
|
.get(rider)
|
|
|
|
.map(|c| (c.inputs.clone(), c.queued_inputs.clone(), rider))
|
|
|
|
})
|
|
|
|
else { continue };
|
2019-11-04 00:57:36 +00:00
|
|
|
|
2022-01-15 18:22:28 +00:00
|
|
|
// ...apply the mount's position/ori/velocity to the rider...
|
|
|
|
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 mounter_body = bodies.get(rider);
|
|
|
|
let mounting_offset = body.map_or(Vec3::unit_z(), Body::mount_offset)
|
|
|
|
+ mounter_body.map_or(Vec3::zero(), Body::rider_offset);
|
|
|
|
let _ = positions
|
|
|
|
.insert(rider, Pos(pos.0 + ori.to_quat() * mounting_offset));
|
|
|
|
let _ = orientations.insert(rider, ori);
|
|
|
|
let _ = velocities.insert(rider, vel);
|
|
|
|
}
|
|
|
|
// ...and apply the rider's inputs to the mount's controller.
|
|
|
|
if let Some(controller) = controllers.get_mut(entity) {
|
|
|
|
*controller = Controller {
|
|
|
|
inputs,
|
|
|
|
queued_inputs,
|
|
|
|
..Default::default()
|
|
|
|
}
|
2019-11-04 00:57:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|