steel_core/entity/
ticking.rs1use rustc_hash::FxHashSet;
4
5use super::{Entity, SharedEntity};
6
7pub(crate) fn snapshot_old_pos_and_rot_for_tick(entity: &dyn Entity) {
9 entity.set_old_position_to_current();
10 entity.base().set_old_rotation_to_current();
11}
12
13pub(crate) fn tick_vehicle_passengers_with_ticked_if(
18 vehicle: &dyn Entity,
19 ticked_entities: &mut FxHashSet<i32>,
20 post_tick: &mut impl FnMut(&SharedEntity),
21 can_tick: &mut impl FnMut(&SharedEntity) -> bool,
22) {
23 let mut visited = FxHashSet::default();
24 visited.insert(vehicle.id());
25
26 for passenger in vehicle.passengers() {
27 tick_passenger(
28 vehicle,
29 &passenger,
30 ticked_entities,
31 post_tick,
32 can_tick,
33 &mut visited,
34 );
35 }
36}
37
38fn tick_passenger(
39 vehicle: &dyn Entity,
40 entity: &SharedEntity,
41 ticked_entities: &mut FxHashSet<i32>,
42 post_tick: &mut impl FnMut(&SharedEntity),
43 can_tick: &mut impl FnMut(&SharedEntity) -> bool,
44 visited: &mut FxHashSet<i32>,
45) {
46 assert!(
47 visited.insert(entity.id()),
48 "cyclic passenger relationship involving entity {}",
49 entity.id()
50 );
51
52 if entity.is_removed()
53 || entity
54 .vehicle()
55 .is_none_or(|current_vehicle| current_vehicle.id() != vehicle.id())
56 {
57 entity.stop_riding();
58 visited.remove(&entity.id());
59 return;
60 }
61
62 if can_tick(entity) && ticked_entities.insert(entity.id()) {
63 snapshot_old_pos_and_rot_for_tick(entity.as_ref());
64 entity.advance_tick_count();
65 entity.ride_tick();
66 post_tick(entity);
67
68 for passenger in entity.passengers() {
69 tick_passenger(
70 entity.as_ref(),
71 &passenger,
72 ticked_entities,
73 post_tick,
74 can_tick,
75 visited,
76 );
77 }
78 }
79
80 visited.remove(&entity.id());
81}