mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Add sync_me
parameter to Presence
that must be set to true
for
entities with the `Presence` component to be synced to other clients.
This commit is contained in:
parent
c6e9d3a202
commit
a01f75b38d
@ -13,16 +13,23 @@ pub struct Presence {
|
||||
/// updated!
|
||||
pub kind: PresenceKind,
|
||||
pub lossy_terrain_compression: bool,
|
||||
/// Controls whether this entity is synced to other clients.
|
||||
///
|
||||
/// Note, if it ends up being useful this could be generalized to an
|
||||
/// independent component that is required for any entity to be synced
|
||||
/// (as an independent component it could use NullStorage).
|
||||
pub sync_me: bool,
|
||||
}
|
||||
|
||||
impl Presence {
|
||||
pub fn new(view_distances: ViewDistances, kind: PresenceKind) -> Self {
|
||||
pub fn new(view_distances: ViewDistances, kind: PresenceKind, sync_me: bool) -> Self {
|
||||
let now = Instant::now();
|
||||
Self {
|
||||
terrain_view_distance: ViewDistance::new(view_distances.terrain, now),
|
||||
entity_view_distance: ViewDistance::new(view_distances.entity, now),
|
||||
kind,
|
||||
lossy_terrain_compression: false,
|
||||
sync_me,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::comp::{Pos, Vel};
|
||||
use crate::comp::{Pos, Presence, Vel};
|
||||
use common_base::span;
|
||||
use hashbrown::{hash_map::DefaultHashBuilder, HashSet};
|
||||
use indexmap::IndexMap;
|
||||
@ -69,7 +69,12 @@ const NEIGHBOR_OFFSETS: [Vec2<i32>; 8] = [
|
||||
#[derive(Default)]
|
||||
// TODO generic region size (16x16 for now)
|
||||
// TODO compare to sweep and prune approach
|
||||
/// A region system that tracks where entities are
|
||||
/// A region system that tracks where entities are.
|
||||
///
|
||||
/// Note, this structure is primarily intended for tracking which entities need
|
||||
/// to be synchronized to which clients (and as part of that what entities are
|
||||
/// already synchronized). If an entity is marked to not be synchronized to
|
||||
/// other clients it may not appear here.
|
||||
pub struct RegionMap {
|
||||
// Tree?
|
||||
// Sorted Vec? (binary search lookup)
|
||||
@ -92,7 +97,13 @@ impl RegionMap {
|
||||
|
||||
// TODO maintain within a system?
|
||||
// TODO special case large entities
|
||||
pub fn tick(&mut self, pos: ReadStorage<Pos>, vel: ReadStorage<Vel>, entities: Entities) {
|
||||
pub fn tick(
|
||||
&mut self,
|
||||
pos: ReadStorage<Pos>,
|
||||
vel: ReadStorage<Vel>,
|
||||
presence: ReadStorage<Presence>,
|
||||
entities: Entities,
|
||||
) {
|
||||
span!(_guard, "tick", "Region::tick");
|
||||
self.tick += 1;
|
||||
// Clear events within each region
|
||||
@ -101,9 +112,10 @@ impl RegionMap {
|
||||
});
|
||||
|
||||
// Add any untracked entities
|
||||
for (pos, id) in (&pos, &entities, !&self.tracked_entities)
|
||||
for (pos, id) in (&pos, &entities, presence.maybe(), !&self.tracked_entities)
|
||||
.join()
|
||||
.map(|(pos, e, _)| (pos, e.id()))
|
||||
.filter(|(_, _, presence, _)| presence.map_or(true, |p| p.sync_me))
|
||||
.map(|(pos, e, _, _)| (pos, e.id()))
|
||||
.collect::<Vec<_>>()
|
||||
{
|
||||
// Add entity
|
||||
@ -123,15 +135,21 @@ impl RegionMap {
|
||||
.iter()
|
||||
.enumerate()
|
||||
.for_each(|(i, (¤t_region, region_data))| {
|
||||
for (maybe_pos, _maybe_vel, id) in
|
||||
(pos.maybe(), vel.maybe(), ®ion_data.bitset).join()
|
||||
for (maybe_pos, _maybe_vel, maybe_presence, id) in (
|
||||
pos.maybe(),
|
||||
vel.maybe(),
|
||||
presence.maybe(),
|
||||
®ion_data.bitset,
|
||||
)
|
||||
.join()
|
||||
{
|
||||
let should_sync = maybe_presence.map_or(true, |p| p.sync_me);
|
||||
match maybe_pos {
|
||||
// Switch regions for entities which need switching
|
||||
// TODO don't check every tick (use velocity) (and use id to stagger)
|
||||
// Starting parameters at v = 0 check every 100 ticks
|
||||
// tether_length^2 / vel^2 (with a max of every tick)
|
||||
Some(pos) => {
|
||||
Some(pos) if should_sync => {
|
||||
let pos = pos.0.map(|e| e as i32);
|
||||
let key = Self::pos_key(pos);
|
||||
// Consider switching
|
||||
@ -148,7 +166,7 @@ impl RegionMap {
|
||||
},
|
||||
// Remove any non-existant entities (or just ones that lost their position
|
||||
// component) TODO: distribute this between ticks
|
||||
None => {
|
||||
None | Some(_) => {
|
||||
// TODO: shouldn't there be a way to extract the bitset of entities with
|
||||
// positions directly from specs? Yes, with `.mask()` on the component
|
||||
// storage.
|
||||
|
@ -534,6 +534,7 @@ impl State {
|
||||
self.ecs.write_resource::<RegionMap>().tick(
|
||||
self.ecs.read_storage::<comp::Pos>(),
|
||||
self.ecs.read_storage::<comp::Vel>(),
|
||||
self.ecs.read_storage::<comp::Presence>(),
|
||||
self.ecs.entities(),
|
||||
);
|
||||
}
|
||||
|
@ -418,6 +418,7 @@ pub fn handle_possess(server: &mut Server, possessor_uid: Uid, possessee_uid: Ui
|
||||
// from overwriting original character info with stuff from the new character.
|
||||
kind: PresenceKind::Possessor,
|
||||
lossy_terrain_compression: presence.lossy_terrain_compression,
|
||||
sync_me: presence.sync_me,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
|
@ -604,6 +604,7 @@ impl StateExt for State {
|
||||
entity: view_distance,
|
||||
},
|
||||
PresenceKind::Spectator,
|
||||
false,
|
||||
))
|
||||
}
|
||||
|
||||
@ -644,7 +645,11 @@ impl StateExt for State {
|
||||
|
||||
self.write_component_ignore_entity_dead(
|
||||
entity,
|
||||
Presence::new(view_distances, PresenceKind::LoadingCharacter(character_id)),
|
||||
Presence::new(
|
||||
view_distances,
|
||||
PresenceKind::LoadingCharacter(character_id),
|
||||
false,
|
||||
),
|
||||
);
|
||||
|
||||
// Tell the client its request was successful.
|
||||
@ -669,7 +674,7 @@ impl StateExt for State {
|
||||
|
||||
self.write_component_ignore_entity_dead(
|
||||
entity,
|
||||
Presence::new(view_distances, PresenceKind::Spectator),
|
||||
Presence::new(view_distances, PresenceKind::Spectator, false),
|
||||
);
|
||||
|
||||
// Tell the client its request was successful.
|
||||
@ -704,6 +709,7 @@ impl StateExt for State {
|
||||
self.ecs()
|
||||
.write_resource::<IdMaps>()
|
||||
.add_character(id, entity);
|
||||
presence.sync_me = true;
|
||||
Ok(())
|
||||
} else {
|
||||
Err("PresenceKind is not LoadingCharacter")
|
||||
|
Loading…
Reference in New Issue
Block a user