veloren/common/systems/src/mount.rs

90 lines
2.9 KiB
Rust
Raw Normal View History

use common::{
2022-01-15 20:15:38 +00:00
comp::{Body, Controller, Ori, Pos, Vel, ForceUpdate},
uid::UidAllocator,
mounting::{Mount, Rider},
link::Is,
uid::Uid,
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, WriteExpect,
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>,
ReadStorage<'a, Uid>,
2019-11-04 00:57:36 +00:00
WriteStorage<'a, Controller>,
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>,
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,
uids,
2019-11-04 00:57:36 +00:00
mut controllers,
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,
bodies,
2019-11-04 00:57:36 +00:00
): Self::SystemData,
) {
// 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
// ...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
}
}
}
}