Cleanup UidAllocator and Uid a bit:

* Remove unnecessary Marker/MarkAllocator trait implementations.
* Delete excess functions
* Change some methods to take Uid instead of u64
This commit is contained in:
Imbris 2023-04-23 01:58:29 -04:00
parent d90926e4a3
commit ea725fffde
37 changed files with 194 additions and 256 deletions

View File

@ -10,9 +10,7 @@ pub use crate::error::Error;
pub use authc::AuthClientError; pub use authc::AuthClientError;
pub use common_net::msg::ServerInfo; pub use common_net::msg::ServerInfo;
pub use specs::{ pub use specs::{
join::Join, join::Join, Builder, DispatcherBuilder, Entity as EcsEntity, ReadStorage, World, WorldExt,
saveload::{Marker, MarkerAllocator},
Builder, DispatcherBuilder, Entity as EcsEntity, ReadStorage, World, WorldExt,
}; };
use crate::addr::ConnectionArgs; use crate::addr::ConnectionArgs;
@ -2203,7 +2201,7 @@ impl Client {
self.chat_mode = m; self.chat_mode = m;
}, },
ServerGeneral::SetPlayerEntity(uid) => { ServerGeneral::SetPlayerEntity(uid) => {
if let Some(entity) = self.state.ecs().entity_from_uid(uid.0) { if let Some(entity) = self.state.ecs().entity_from_uid(uid) {
let old_player_entity = mem::replace( let old_player_entity = mem::replace(
&mut *self.state.ecs_mut().write_resource(), &mut *self.state.ecs_mut().write_resource(),
PlayerEntity(Some(entity)), PlayerEntity(Some(entity)),
@ -2265,11 +2263,11 @@ impl Client {
ServerGeneral::CreateEntity(entity_package) => { ServerGeneral::CreateEntity(entity_package) => {
self.state.ecs_mut().apply_entity_package(entity_package); self.state.ecs_mut().apply_entity_package(entity_package);
}, },
ServerGeneral::DeleteEntity(entity) => { ServerGeneral::DeleteEntity(entity_uid) => {
if self.uid() != Some(entity) { if self.uid() != Some(entity_uid) {
self.state self.state
.ecs_mut() .ecs_mut()
.delete_entity_and_clear_from_uid_allocator(entity.0); .delete_entity_and_clear_from_uid_allocator(entity_uid);
} }
}, },
ServerGeneral::Notification(n) => { ServerGeneral::Notification(n) => {

View File

@ -6,11 +6,7 @@ use common::{
resources::PlayerEntity, resources::PlayerEntity,
uid::{Uid, UidAllocator}, uid::{Uid, UidAllocator},
}; };
use specs::{ use specs::{world::Builder, WorldExt};
saveload::{MarkedBuilder, MarkerAllocator},
world::Builder,
WorldExt,
};
use tracing::error; use tracing::error;
pub trait WorldSyncExt { pub trait WorldSyncExt {
@ -22,9 +18,9 @@ pub trait WorldSyncExt {
where where
C::Storage: Default + specs::storage::Tracked; C::Storage: Default + specs::storage::Tracked;
fn create_entity_synced(&mut self) -> specs::EntityBuilder; fn create_entity_synced(&mut self) -> specs::EntityBuilder;
fn delete_entity_and_clear_from_uid_allocator(&mut self, uid: u64); fn delete_entity_and_clear_from_uid_allocator(&mut self, uid: Uid);
fn uid_from_entity(&self, entity: specs::Entity) -> Option<Uid>; fn uid_from_entity(&self, entity: specs::Entity) -> Option<Uid>;
fn entity_from_uid(&self, uid: u64) -> Option<specs::Entity>; fn entity_from_uid(&self, uid: Uid) -> Option<specs::Entity>;
fn apply_entity_package<P: CompPacket>( fn apply_entity_package<P: CompPacket>(
&mut self, &mut self,
entity_package: EntityPackage<P>, entity_package: EntityPackage<P>,
@ -56,10 +52,15 @@ impl WorldSyncExt for specs::World {
} }
fn create_entity_synced(&mut self) -> specs::EntityBuilder { fn create_entity_synced(&mut self) -> specs::EntityBuilder {
self.create_entity().marked::<Uid>() let builder = self.create_entity();
let uid = builder
.world
.write_resource::<UidAllocator>()
.allocate(builder.entity, None);
builder.with(uid)
} }
fn delete_entity_and_clear_from_uid_allocator(&mut self, uid: u64) { fn delete_entity_and_clear_from_uid_allocator(&mut self, uid: Uid) {
// Clear from uid allocator // Clear from uid allocator
let maybe_entity = self.write_resource::<UidAllocator>().remove_entity(uid); let maybe_entity = self.write_resource::<UidAllocator>().remove_entity(uid);
if let Some(entity) = maybe_entity { if let Some(entity) = maybe_entity {
@ -75,7 +76,7 @@ impl WorldSyncExt for specs::World {
} }
/// Get an entity from a UID /// Get an entity from a UID
fn entity_from_uid(&self, uid: u64) -> Option<specs::Entity> { fn entity_from_uid(&self, uid: Uid) -> Option<specs::Entity> {
self.read_resource::<UidAllocator>() self.read_resource::<UidAllocator>()
.retrieve_entity_internal(uid) .retrieve_entity_internal(uid)
} }
@ -108,7 +109,7 @@ impl WorldSyncExt for specs::World {
// Attempt to delete entities that were marked for deletion // Attempt to delete entities that were marked for deletion
deleted_entities.into_iter().for_each(|uid| { deleted_entities.into_iter().for_each(|uid| {
self.delete_entity_and_clear_from_uid_allocator(uid); self.delete_entity_and_clear_from_uid_allocator(uid.into());
}); });
} }
@ -118,7 +119,7 @@ impl WorldSyncExt for specs::World {
package.comp_updates.into_iter().for_each(|(uid, update)| { package.comp_updates.into_iter().for_each(|(uid, update)| {
if let Some(entity) = self if let Some(entity) = self
.read_resource::<UidAllocator>() .read_resource::<UidAllocator>()
.retrieve_entity_internal(uid) .retrieve_entity_internal(uid.into())
{ {
let force_update = player_entity == Some(entity); let force_update = player_entity == Some(entity);
match update { match update {
@ -139,6 +140,7 @@ impl WorldSyncExt for specs::World {
// Private utilities // Private utilities
fn create_entity_with_uid(specs_world: &mut specs::World, entity_uid: u64) -> specs::Entity { fn create_entity_with_uid(specs_world: &mut specs::World, entity_uid: u64) -> specs::Entity {
let entity_uid = Uid::from(entity_uid);
let existing_entity = specs_world let existing_entity = specs_world
.read_resource::<UidAllocator>() .read_resource::<UidAllocator>()
.retrieve_entity_internal(entity_uid); .retrieve_entity_internal(entity_uid);

View File

@ -29,7 +29,7 @@ use crate::{comp::Group, resources::Time};
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
use { use {
rand::Rng, rand::Rng,
specs::{saveload::MarkerAllocator, Entity as EcsEntity, ReadStorage}, specs::{Entity as EcsEntity, ReadStorage},
std::ops::{Mul, MulAssign}, std::ops::{Mul, MulAssign},
vek::*, vek::*,
}; };
@ -726,7 +726,7 @@ pub fn may_harm(
// return original entity // return original entity
// if can't get owner // if can't get owner
uid_allocator uid_allocator
.retrieve_entity_internal(uid.into()) .retrieve_entity_internal(uid)
.unwrap_or(entity) .unwrap_or(entity)
} else { } else {
entity entity

View File

@ -8,8 +8,8 @@ use crate::{
use hashbrown::HashSet; use hashbrown::HashSet;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use specs::{ use specs::{
saveload::MarkerAllocator, storage::GenericWriteStorage, Component, DenseVecStorage, Entities, storage::GenericWriteStorage, Component, DenseVecStorage, Entities, Entity, Read, ReadExpect,
Entity, Read, ReadExpect, ReadStorage, Write, WriteStorage, ReadStorage, Write, WriteStorage,
}; };
use vek::*; use vek::*;
@ -69,7 +69,7 @@ impl Link for Mounting {
this: &LinkHandle<Self>, this: &LinkHandle<Self>,
(uid_allocator, is_mounts, is_riders, is_volume_rider): &mut Self::CreateData<'_>, (uid_allocator, is_mounts, is_riders, is_volume_rider): &mut Self::CreateData<'_>,
) -> Result<(), Self::Error> { ) -> Result<(), Self::Error> {
let entity = |uid: Uid| uid_allocator.retrieve_entity_internal(uid.into()); let entity = |uid: Uid| uid_allocator.retrieve_entity_internal(uid);
if this.mount == this.rider { if this.mount == this.rider {
// Forbid self-mounting // Forbid self-mounting
@ -99,7 +99,7 @@ impl Link for Mounting {
this: &LinkHandle<Self>, this: &LinkHandle<Self>,
(uid_allocator, entities, healths, bodies, is_mounts, is_riders, character_states): &mut Self::PersistData<'_>, (uid_allocator, entities, healths, bodies, is_mounts, is_riders, character_states): &mut Self::PersistData<'_>,
) -> bool { ) -> bool {
let entity = |uid: Uid| uid_allocator.retrieve_entity_internal(uid.into()); let entity = |uid: Uid| uid_allocator.retrieve_entity_internal(uid);
if let Some((mount, rider)) = entity(this.mount).zip(entity(this.rider)) { if let Some((mount, rider)) = entity(this.mount).zip(entity(this.rider)) {
let is_alive = |entity| { let is_alive = |entity| {
@ -128,7 +128,7 @@ impl Link for Mounting {
this: &LinkHandle<Self>, this: &LinkHandle<Self>,
(uid_allocator, is_mounts, is_riders, positions, force_update, terrain): &mut Self::DeleteData<'_>, (uid_allocator, is_mounts, is_riders, positions, force_update, terrain): &mut Self::DeleteData<'_>,
) { ) {
let entity = |uid: Uid| uid_allocator.retrieve_entity_internal(uid.into()); let entity = |uid: Uid| uid_allocator.retrieve_entity_internal(uid);
let mount = entity(this.mount); let mount = entity(this.mount);
let rider = entity(this.rider); let rider = entity(this.rider);
@ -228,9 +228,8 @@ impl VolumePos {
comp::Ori::default(), comp::Ori::default(),
*terrain.get(self.pos).ok()?, *terrain.get(self.pos).ok()?,
)), )),
Volume::Entity(uid) => { Volume::Entity(uid) => uid_allocator
uid_allocator .retrieve_entity_internal(uid)
.retrieve_entity_internal(uid.0)
.and_then(|entity| { .and_then(|entity| {
let collider = colliders.get(entity)?; let collider = colliders.get(entity)?;
let (pos, ori) = read_pos_and_ori(entity)?; let (pos, ori) = read_pos_and_ori(entity)?;
@ -246,8 +245,7 @@ impl VolumePos {
* Mat4::<f32>::translation_3d(local_translation); * Mat4::<f32>::translation_3d(local_translation);
Some((trans, ori, block)) Some((trans, ori, block))
}) }),
},
} }
} }
@ -260,9 +258,8 @@ impl VolumePos {
) -> Option<Block> { ) -> Option<Block> {
match self.kind { match self.kind {
Volume::Terrain => Some(*terrain.get(self.pos).ok()?), Volume::Terrain => Some(*terrain.get(self.pos).ok()?),
Volume::Entity(uid) => { Volume::Entity(uid) => uid_allocator
uid_allocator .retrieve_entity_internal(uid)
.retrieve_entity_internal(uid.0)
.and_then(|entity| { .and_then(|entity| {
let collider = colliders.get(entity)?; let collider = colliders.get(entity)?;
@ -272,8 +269,7 @@ impl VolumePos {
let block = *voxel_collider.volume().get(self.pos).ok()?; let block = *voxel_collider.volume().get(self.pos).ok()?;
Some(block) Some(block)
}) }),
},
} }
} }
} }

View File

@ -2,11 +2,7 @@
use hashbrown::HashMap; use hashbrown::HashMap;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
use specs::{ use specs::{Component, Entity, FlaggedStorage, VecStorage};
saveload::{Marker, MarkerAllocator},
world::EntitiesRes,
Component, Entity, FlaggedStorage, Join, ReadStorage, VecStorage,
};
use std::{fmt, u64}; use std::{fmt, u64};
#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)] #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
@ -29,62 +25,42 @@ impl Component for Uid {
type Storage = FlaggedStorage<Self, VecStorage<Self>>; type Storage = FlaggedStorage<Self, VecStorage<Self>>;
} }
#[cfg(not(target_arch = "wasm32"))]
impl Marker for Uid {
type Allocator = UidAllocator;
type Identifier = u64;
fn id(&self) -> u64 { self.0 }
fn update(&mut self, update: Self) {
assert_eq!(self.0, update.0);
}
}
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
#[derive(Debug)] #[derive(Debug)]
pub struct UidAllocator { pub struct UidAllocator {
index: u64, next_id: u64,
mapping: HashMap<u64, Entity>, mapping: HashMap<Uid, Entity>,
} }
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
impl UidAllocator { impl UidAllocator {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
index: 0, next_id: 0,
mapping: HashMap::new(), mapping: HashMap::new(),
} }
} }
// Useful for when a single entity is deleted because it doesn't reconstruct the // Useful for when a single entity is deleted because it doesn't reconstruct the
// entire hashmap // entire hashmap
pub fn remove_entity(&mut self, id: u64) -> Option<Entity> { self.mapping.remove(&id) } pub fn remove_entity(&mut self, id: Uid) -> Option<Entity> { self.mapping.remove(&id) }
pub fn allocate(&mut self, entity: Entity, id: Option<Uid>) -> Uid {
let id = id.unwrap_or_else(|| {
let id = self.next_id;
self.next_id += 1;
Uid(id)
});
self.mapping.insert(id, entity);
id
}
pub fn retrieve_entity_internal(&self, id: Uid) -> Option<Entity> {
self.mapping.get(&id).copied()
}
} }
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
impl Default for UidAllocator { impl Default for UidAllocator {
fn default() -> Self { Self::new() } fn default() -> Self { Self::new() }
} }
#[cfg(not(target_arch = "wasm32"))]
impl MarkerAllocator<Uid> for UidAllocator {
fn allocate(&mut self, entity: Entity, id: Option<u64>) -> Uid {
let id = id.unwrap_or_else(|| {
let id = self.index;
self.index += 1;
id
});
self.mapping.insert(id, entity);
Uid(id)
}
fn retrieve_entity_internal(&self, id: u64) -> Option<Entity> { self.mapping.get(&id).copied() }
fn maintain(&mut self, entities: &EntitiesRes, storage: &ReadStorage<Uid>) {
self.mapping = (entities, storage)
.join()
.map(|(e, m)| (m.id(), e))
.collect();
}
}

View File

@ -5,7 +5,6 @@ use std::{
sync::{Arc, Mutex}, sync::{Arc, Mutex},
}; };
use specs::saveload::MarkerAllocator;
use wasmer::{imports, Cranelift, Function, Instance, Memory, Module, Store, Universal, Value}; use wasmer::{imports, Cranelift, Function, Instance, Memory, Module, Store, Universal, Value};
use super::{ use super::{
@ -239,7 +238,7 @@ fn retrieve_action(
EcsAccessError::EcsPointerNotAvailable, EcsAccessError::EcsPointerNotAvailable,
))? ))?
}; };
let player = world.uid_allocator.retrieve_entity_internal(e.0).ok_or( let player = world.uid_allocator.retrieve_entity_internal(e).ok_or(
RetrieveError::EcsAccessError(EcsAccessError::EcsEntityNotFound(e)), RetrieveError::EcsAccessError(EcsAccessError::EcsEntityNotFound(e)),
)?; )?;
@ -264,7 +263,7 @@ fn retrieve_action(
EcsAccessError::EcsPointerNotAvailable, EcsAccessError::EcsPointerNotAvailable,
))? ))?
}; };
let player = world.uid_allocator.retrieve_entity_internal(e.0).ok_or( let player = world.uid_allocator.retrieve_entity_internal(e).ok_or(
RetrieveError::EcsAccessError(EcsAccessError::EcsEntityNotFound(e)), RetrieveError::EcsAccessError(EcsAccessError::EcsEntityNotFound(e)),
)?; )?;
Ok(RetrieveResult::GetEntityHealth( Ok(RetrieveResult::GetEntityHealth(

View File

@ -12,8 +12,7 @@ use common::{
}; };
use common_ecs::{Job, Origin, Phase, System}; use common_ecs::{Job, Origin, Phase, System};
use specs::{ use specs::{
saveload::MarkerAllocator, shred::ResourceId, Entities, Entity as EcsEntity, Join, Read, shred::ResourceId, Entities, Entity as EcsEntity, Join, Read, ReadStorage, SystemData, World,
ReadStorage, SystemData, World,
}; };
#[derive(SystemData)] #[derive(SystemData)]
@ -97,7 +96,7 @@ impl<'a> System<'a> for Sys {
let same_group = |uid: Uid| { let same_group = |uid: Uid| {
read_data read_data
.uid_allocator .uid_allocator
.retrieve_entity_internal(uid.into()) .retrieve_entity_internal(uid)
.and_then(|e| read_data.groups.get(e)) .and_then(|e| read_data.groups.get(e))
.map_or(false, |owner_group| { .map_or(false, |owner_group| {
Some(owner_group) == read_data.groups.get(target) Some(owner_group) == read_data.groups.get(target)
@ -168,9 +167,7 @@ fn activate_aura(
_ => None, _ => None,
}) })
.and_then(|uid| { .and_then(|uid| {
read_data read_data.uid_allocator.retrieve_entity_internal(*uid)
.uid_allocator
.retrieve_entity_internal((*uid).into())
}) })
.and_then(|owner| read_data.char_states.get(owner)) .and_then(|owner| read_data.char_states.get(owner))
.map_or(false, CharacterState::is_sitting)) .map_or(false, CharacterState::is_sitting))
@ -189,7 +186,7 @@ fn activate_aura(
let may_harm = || { let may_harm = || {
let owner = match source { let owner = match source {
BuffSource::Character { by } => { BuffSource::Character { by } => {
read_data.uid_allocator.retrieve_entity_internal(by.into()) read_data.uid_allocator.retrieve_entity_internal(by)
}, },
_ => None, _ => None,
}; };

View File

@ -17,8 +17,8 @@ use common_ecs::{Job, Origin, ParMode, Phase, System};
use rand::Rng; use rand::Rng;
use rayon::iter::ParallelIterator; use rayon::iter::ParallelIterator;
use specs::{ use specs::{
saveload::MarkerAllocator, shred::ResourceId, Entities, Join, ParJoin, Read, ReadExpect, shred::ResourceId, Entities, Join, ParJoin, Read, ReadExpect, ReadStorage, SystemData, World,
ReadStorage, SystemData, World, WriteStorage, WriteStorage,
}; };
use std::time::Duration; use std::time::Duration;
use vek::*; use vek::*;
@ -95,9 +95,9 @@ impl<'a> System<'a> for Sys {
}; };
let end_time = creation_time + beam_segment.duration.as_secs_f64(); let end_time = creation_time + beam_segment.duration.as_secs_f64();
let beam_owner = beam_segment.owner.and_then(|uid| { let beam_owner = beam_segment
read_data.uid_allocator.retrieve_entity_internal(uid.into()) .owner
}); .and_then(|uid| read_data.uid_allocator.retrieve_entity_internal(uid));
// Note: rayon makes it difficult to hold onto a thread-local RNG, if grabbing // Note: rayon makes it difficult to hold onto a thread-local RNG, if grabbing
// this becomes a bottleneck we can look into alternatives. // this becomes a bottleneck we can look into alternatives.

View File

@ -22,8 +22,8 @@ use common_base::prof_span;
use common_ecs::{Job, Origin, ParMode, Phase, System}; use common_ecs::{Job, Origin, ParMode, Phase, System};
use rayon::iter::ParallelIterator; use rayon::iter::ParallelIterator;
use specs::{ use specs::{
saveload::MarkerAllocator, shred::ResourceId, Entities, Entity, Join, ParJoin, Read, shred::ResourceId, Entities, Entity, Join, ParJoin, Read, ReadExpect, ReadStorage, SystemData,
ReadExpect, ReadStorage, SystemData, World, WriteStorage, World, WriteStorage,
}; };
#[derive(SystemData)] #[derive(SystemData)]
@ -506,7 +506,7 @@ fn execute_effect(
let damage_contributor = by.and_then(|uid| { let damage_contributor = by.and_then(|uid| {
read_data read_data
.uid_allocator .uid_allocator
.retrieve_entity_internal(uid.0) .retrieve_entity_internal(uid)
.map(|entity| { .map(|entity| {
DamageContributor::new(uid, read_data.groups.get(entity).cloned()) DamageContributor::new(uid, read_data.groups.get(entity).cloned())
}) })

View File

@ -10,9 +10,8 @@ use common::{
}; };
use common_ecs::{Job, Origin, Phase, System}; use common_ecs::{Job, Origin, Phase, System};
use specs::{ use specs::{
saveload::{Marker, MarkerAllocator}, shred::ResourceId, Entities, Join, Read, ReadExpect, ReadStorage, SystemData, World,
shred::ResourceId, WriteStorage,
Entities, Join, Read, ReadExpect, ReadStorage, SystemData, World, WriteStorage,
}; };
use vek::*; use vek::*;
@ -51,7 +50,7 @@ impl<'a> System<'a> for Sys {
ControlEvent::Mount(mountee_uid) => { ControlEvent::Mount(mountee_uid) => {
if let Some(mountee_entity) = read_data if let Some(mountee_entity) = read_data
.uid_allocator .uid_allocator
.retrieve_entity_internal(mountee_uid.id()) .retrieve_entity_internal(mountee_uid)
{ {
server_emitter.emit(ServerEvent::Mount(entity, mountee_entity)); server_emitter.emit(ServerEvent::Mount(entity, mountee_entity));
} }
@ -81,9 +80,8 @@ impl<'a> System<'a> for Sys {
server_emitter.emit(ServerEvent::DisableLantern(entity)) server_emitter.emit(ServerEvent::DisableLantern(entity))
}, },
ControlEvent::Interact(npc_uid, subject) => { ControlEvent::Interact(npc_uid, subject) => {
if let Some(npc_entity) = read_data if let Some(npc_entity) =
.uid_allocator read_data.uid_allocator.retrieve_entity_internal(npc_uid)
.retrieve_entity_internal(npc_uid.id())
{ {
server_emitter server_emitter
.emit(ServerEvent::NpcInteract(entity, npc_entity, subject)); .emit(ServerEvent::NpcInteract(entity, npc_entity, subject));

View File

@ -6,10 +6,7 @@ use common::{
uid::UidAllocator, uid::UidAllocator,
}; };
use common_ecs::{Job, Origin, Phase, System}; use common_ecs::{Job, Origin, Phase, System};
use specs::{ use specs::{Entities, Join, Read, ReadExpect, ReadStorage, WriteStorage};
saveload::{Marker, MarkerAllocator},
Entities, Join, Read, ReadExpect, ReadStorage, WriteStorage,
};
use tracing::error; use tracing::error;
use vek::*; use vek::*;
@ -57,7 +54,7 @@ impl<'a> System<'a> for Sys {
for (entity, is_mount, body) in (&entities, &is_mounts, bodies.maybe()).join() { for (entity, is_mount, body) in (&entities, &is_mounts, bodies.maybe()).join() {
// ...find the rider... // ...find the rider...
let Some((inputs_and_actions, rider)) = uid_allocator let Some((inputs_and_actions, rider)) = uid_allocator
.retrieve_entity_internal(is_mount.rider.id()) .retrieve_entity_internal(is_mount.rider)
.and_then(|rider| { .and_then(|rider| {
controllers controllers
.get_mut(rider) .get_mut(rider)

View File

@ -17,8 +17,8 @@ use common::vol::ReadVol;
use common_ecs::{Job, Origin, Phase, System}; use common_ecs::{Job, Origin, Phase, System};
use rand::Rng; use rand::Rng;
use specs::{ use specs::{
saveload::MarkerAllocator, shred::ResourceId, Entities, Entity as EcsEntity, Join, Read, shred::ResourceId, Entities, Entity as EcsEntity, Join, Read, ReadExpect, ReadStorage,
ReadExpect, ReadStorage, SystemData, World, WriteStorage, SystemData, World, WriteStorage,
}; };
use std::time::Duration; use std::time::Duration;
use vek::*; use vek::*;
@ -85,7 +85,7 @@ impl<'a> System<'a> for Sys {
{ {
let projectile_owner = projectile let projectile_owner = projectile
.owner .owner
.and_then(|uid| read_data.uid_allocator.retrieve_entity_internal(uid.into())); .and_then(|uid| read_data.uid_allocator.retrieve_entity_internal(uid));
if physics.on_surface().is_none() && rng.gen_bool(0.05) { if physics.on_surface().is_none() && rng.gen_bool(0.05) {
server_emitter.emit(ServerEvent::Sound { server_emitter.emit(ServerEvent::Sound {
@ -104,7 +104,7 @@ impl<'a> System<'a> for Sys {
.and_then(|e| read_data.groups.get(e)) .and_then(|e| read_data.groups.get(e))
.map_or(false, |owner_group| .map_or(false, |owner_group|
Some(owner_group) == read_data.uid_allocator Some(owner_group) == read_data.uid_allocator
.retrieve_entity_internal(other.into()) .retrieve_entity_internal(other)
.and_then(|e| read_data.groups.get(e)) .and_then(|e| read_data.groups.get(e))
); );
@ -125,8 +125,7 @@ impl<'a> System<'a> for Sys {
let projectile = &mut *projectile; let projectile = &mut *projectile;
let entity_of = let entity_of = |uid: Uid| read_data.uid_allocator.retrieve_entity_internal(uid);
|uid: Uid| read_data.uid_allocator.retrieve_entity_internal(uid.into());
// Don't hit if there is terrain between the projectile and where the entity was // Don't hit if there is terrain between the projectile and where the entity was
// supposed to be hit by it. // supposed to be hit by it.

View File

@ -15,8 +15,7 @@ use common::{
use common_ecs::{Job, Origin, Phase, System}; use common_ecs::{Job, Origin, Phase, System};
use rand::Rng; use rand::Rng;
use specs::{ use specs::{
saveload::MarkerAllocator, shred::ResourceId, Entities, Join, Read, ReadStorage, SystemData, shred::ResourceId, Entities, Join, Read, ReadStorage, SystemData, World, WriteStorage,
World, WriteStorage,
}; };
use vek::*; use vek::*;
@ -92,7 +91,7 @@ impl<'a> System<'a> for Sys {
let shockwave_owner = shockwave let shockwave_owner = shockwave
.owner .owner
.and_then(|uid| read_data.uid_allocator.retrieve_entity_internal(uid.into())); .and_then(|uid| read_data.uid_allocator.retrieve_entity_internal(uid));
if rng.gen_bool(0.05) { if rng.gen_bool(0.05) {
server_emitter.emit(ServerEvent::Sound { server_emitter.emit(ServerEvent::Sound {

View File

@ -39,7 +39,7 @@ use common::{
}; };
use itertools::Itertools; use itertools::Itertools;
use rand::{thread_rng, Rng}; use rand::{thread_rng, Rng};
use specs::{saveload::Marker, Entity as EcsEntity}; use specs::Entity as EcsEntity;
use vek::*; use vek::*;
#[cfg(feature = "use-dyn-lib")] #[cfg(feature = "use-dyn-lib")]
@ -397,7 +397,7 @@ impl<'a> AgentData<'a> {
break 'activity; break 'activity;
} }
} else if let Some(Alignment::Owned(owner_uid)) = self.alignment } else if let Some(Alignment::Owned(owner_uid)) = self.alignment
&& let Some(owner) = get_entity_by_id(owner_uid.id(), read_data) && let Some(owner) = get_entity_by_id(*owner_uid, read_data)
&& let Some(pos) = read_data.positions.get(owner) && let Some(pos) = read_data.positions.get(owner)
&& pos.0.distance_squared(self.pos.0) < MAX_MOUNT_RANGE.powi(2) && pos.0.distance_squared(self.pos.0) < MAX_MOUNT_RANGE.powi(2)
&& rng.gen_bool(0.01) && rng.gen_bool(0.01)
@ -455,7 +455,7 @@ impl<'a> AgentData<'a> {
if let Some(patrol_origin) = agent.patrol_origin if let Some(patrol_origin) = agent.patrol_origin
// Use owner as patrol origin otherwise // Use owner as patrol origin otherwise
.or_else(|| if let Some(Alignment::Owned(owner_uid)) = self.alignment .or_else(|| if let Some(Alignment::Owned(owner_uid)) = self.alignment
&& let Some(owner) = get_entity_by_id(owner_uid.id(), read_data) && let Some(owner) = get_entity_by_id(*owner_uid, read_data)
&& let Some(pos) = read_data.positions.get(owner) && let Some(pos) = read_data.positions.get(owner)
{ {
Some(pos.0) Some(pos.0)
@ -1613,7 +1613,7 @@ impl<'a> AgentData<'a> {
if let Some(Target { target, .. }) = agent.target { if let Some(Target { target, .. }) = agent.target {
if let Some(tgt_health) = read_data.healths.get(target) { if let Some(tgt_health) = read_data.healths.get(target) {
if let Some(by) = tgt_health.last_change.damage_by() { if let Some(by) = tgt_health.last_change.damage_by() {
if let Some(attacker) = get_entity_by_id(by.uid().0, read_data) { if let Some(attacker) = get_entity_by_id(by.uid(), read_data) {
if agent.target.is_none() { if agent.target.is_none() {
controller.push_utterance(UtteranceKind::Angry); controller.push_utterance(UtteranceKind::Angry);
} }

View File

@ -9,15 +9,13 @@ use common::{
}, },
consts::GRAVITY, consts::GRAVITY,
terrain::Block, terrain::Block,
uid::Uid,
util::Dir, util::Dir,
vol::ReadVol, vol::ReadVol,
}; };
use core::f32::consts::PI; use core::f32::consts::PI;
use rand::Rng; use rand::Rng;
use specs::{ use specs::Entity as EcsEntity;
saveload::{Marker, MarkerAllocator},
Entity as EcsEntity,
};
use vek::*; use vek::*;
pub fn is_dead_or_invulnerable(entity: EcsEntity, read_data: &ReadData) -> bool { pub fn is_dead_or_invulnerable(entity: EcsEntity, read_data: &ReadData) -> bool {
@ -43,8 +41,8 @@ pub fn try_owner_alignment<'a>(
alignment: Option<&'a Alignment>, alignment: Option<&'a Alignment>,
read_data: &'a ReadData, read_data: &'a ReadData,
) -> Option<&'a Alignment> { ) -> Option<&'a Alignment> {
if let Some(Alignment::Owned(owner_uid)) = alignment { if let Some(&Alignment::Owned(owner_uid)) = alignment {
if let Some(owner) = get_entity_by_id(owner_uid.id(), read_data) { if let Some(owner) = get_entity_by_id(owner_uid, read_data) {
return read_data.alignments.get(owner); return read_data.alignments.get(owner);
} }
} }
@ -66,8 +64,8 @@ pub fn aim_projectile(speed: f32, pos: Vec3<f32>, tgt: Vec3<f32>) -> Option<Dir>
Dir::from_unnormalized(to_tgt) Dir::from_unnormalized(to_tgt)
} }
pub fn get_entity_by_id(id: u64, read_data: &ReadData) -> Option<EcsEntity> { pub fn get_entity_by_id(uid: Uid, read_data: &ReadData) -> Option<EcsEntity> {
read_data.uid_allocator.retrieve_entity_internal(id) read_data.uid_allocator.retrieve_entity_internal(uid)
} }
/// Calculates whether the agent should continue chase or let the target escape. /// Calculates whether the agent should continue chase or let the target escape.
@ -198,7 +196,7 @@ pub fn get_attacker(entity: EcsEntity, read_data: &ReadData) -> Option<EcsEntity
.get(entity) .get(entity)
.filter(|health| health.last_change.amount < 0.0) .filter(|health| health.last_change.amount < 0.0)
.and_then(|health| health.last_change.damage_by()) .and_then(|health| health.last_change.damage_by())
.and_then(|damage_contributor| get_entity_by_id(damage_contributor.uid().0, read_data)) .and_then(|damage_contributor| get_entity_by_id(damage_contributor.uid(), read_data))
} }
impl<'a> AgentData<'a> { impl<'a> AgentData<'a> {

View File

@ -60,9 +60,7 @@ use core::{cmp::Ordering, convert::TryFrom};
use hashbrown::{HashMap, HashSet}; use hashbrown::{HashMap, HashSet};
use humantime::Duration as HumanDuration; use humantime::Duration as HumanDuration;
use rand::{thread_rng, Rng}; use rand::{thread_rng, Rng};
use specs::{ use specs::{storage::StorageEntry, Builder, Entity as EcsEntity, Join, WorldExt};
saveload::MarkerAllocator, storage::StorageEntry, Builder, Entity as EcsEntity, Join, WorldExt,
};
use std::{fmt::Write, ops::DerefMut, str::FromStr, sync::Arc}; use std::{fmt::Write, ops::DerefMut, str::FromStr, sync::Arc};
use vek::*; use vek::*;
use wiring::{Circuit, Wire, WireNode, WiringAction, WiringActionEffect, WiringElement}; use wiring::{Circuit, Wire, WireNode, WiringAction, WiringActionEffect, WiringElement};
@ -248,7 +246,7 @@ fn position_mut<T>(
.state .state
.ecs() .ecs()
.read_resource::<UidAllocator>() .read_resource::<UidAllocator>()
.retrieve_entity_internal(is_rider.mount.into()) .retrieve_entity_internal(is_rider.mount)
}) })
.map(Ok) .map(Ok)
.or_else(|| { .or_else(|| {
@ -2279,7 +2277,7 @@ fn handle_kill_npcs(
.filter_map(|(entity, _health, (), alignment, pos)| { .filter_map(|(entity, _health, (), alignment, pos)| {
let should_kill = kill_pets let should_kill = kill_pets
|| if let Some(Alignment::Owned(owned)) = alignment { || if let Some(Alignment::Owned(owned)) = alignment {
ecs.entity_from_uid(owned.0) ecs.entity_from_uid(*owned)
.map_or(true, |owner| !players.contains(owner)) .map_or(true, |owner| !players.contains(owner))
} else { } else {
true true

View File

@ -154,7 +154,7 @@ pub fn handle_create_npc(server: &mut Server, pos: Pos, mut npc: NpcBuilder) ->
let clients = state.ecs().read_storage::<Client>(); let clients = state.ecs().read_storage::<Client>();
let uids = state.ecs().read_storage::<Uid>(); let uids = state.ecs().read_storage::<Uid>();
let mut group_manager = state.ecs().write_resource::<comp::group::GroupManager>(); let mut group_manager = state.ecs().write_resource::<comp::group::GroupManager>();
if let Some(owner) = state.ecs().entity_from_uid(owner_uid.into()) { if let Some(owner) = state.ecs().entity_from_uid(owner_uid) {
let map_markers = state.ecs().read_storage::<comp::MapMarker>(); let map_markers = state.ecs().read_storage::<comp::MapMarker>();
group_manager.new_pet( group_manager.new_pet(
new_entity, new_entity,

View File

@ -41,9 +41,7 @@ use common_net::{msg::ServerGeneral, sync::WorldSyncExt};
use common_state::{AreasContainer, BlockChange, NoDurabilityArea}; use common_state::{AreasContainer, BlockChange, NoDurabilityArea};
use hashbrown::HashSet; use hashbrown::HashSet;
use rand::Rng; use rand::Rng;
use specs::{ use specs::{join::Join, Builder, Entity as EcsEntity, Entity, WorldExt};
join::Join, saveload::MarkerAllocator, Builder, Entity as EcsEntity, Entity, WorldExt,
};
use std::{collections::HashMap, iter, sync::Arc, time::Duration}; use std::{collections::HashMap, iter, sync::Arc, time::Duration};
use tracing::{debug, error}; use tracing::{debug, error};
use vek::{Vec2, Vec3}; use vek::{Vec2, Vec3};
@ -143,7 +141,7 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, last_change: Healt
let get_attacker_name = |cause_of_death: KillType, by: Uid| -> KillSource { let get_attacker_name = |cause_of_death: KillType, by: Uid| -> KillSource {
// Get attacker entity // Get attacker entity
if let Some(char_entity) = state.ecs().entity_from_uid(by.into()) { if let Some(char_entity) = state.ecs().entity_from_uid(by) {
// Check if attacker is another player or entity with stats (npc) // Check if attacker is another player or entity with stats (npc)
if state if state
.ecs() .ecs()
@ -259,7 +257,7 @@ pub fn handle_destroy(server: &mut Server, entity: EcsEntity, last_change: Healt
for (damage_contributor, damage) in entity_health.damage_contributions() { for (damage_contributor, damage) in entity_health.damage_contributions() {
match damage_contributor { match damage_contributor {
DamageContributor::Solo(uid) => { DamageContributor::Solo(uid) => {
if let Some(attacker) = state.ecs().entity_from_uid(uid.0) { if let Some(attacker) = state.ecs().entity_from_uid(*uid) {
damage_contributors.insert(DamageContrib::Solo(attacker), (*damage, 0.0)); damage_contributors.insert(DamageContrib::Solo(attacker), (*damage, 0.0));
} else { } else {
// An entity who was not in a group contributed damage but is now either // An entity who was not in a group contributed damage but is now either
@ -746,7 +744,7 @@ pub fn handle_explosion(server: &Server, pos: Vec3<f32>, explosion: Explosion, o
let time = ecs.read_resource::<Time>(); let time = ecs.read_resource::<Time>();
let owner_entity = owner.and_then(|uid| { let owner_entity = owner.and_then(|uid| {
ecs.read_resource::<UidAllocator>() ecs.read_resource::<UidAllocator>()
.retrieve_entity_internal(uid.into()) .retrieve_entity_internal(uid)
}); });
let explosion_volume = 6.25 * explosion.radius; let explosion_volume = 6.25 * explosion.radius;
@ -1421,7 +1419,7 @@ pub fn handle_teleport_to(server: &Server, entity: EcsEntity, target: Uid, max_r
let mut positions = ecs.write_storage::<Pos>(); let mut positions = ecs.write_storage::<Pos>();
let target_pos = ecs let target_pos = ecs
.entity_from_uid(target.into()) .entity_from_uid(target)
.and_then(|e| positions.get(e)) .and_then(|e| positions.get(e))
.copied(); .copied();
@ -1493,7 +1491,7 @@ pub fn handle_entity_attacked_hook(server: &Server, entity: EcsEntity) {
if let Some(trade) = trades.entity_trades.get(uid).copied() { if let Some(trade) = trades.entity_trades.get(uid).copied() {
trades trades
.decline_trade(trade, *uid) .decline_trade(trade, *uid)
.and_then(|uid| ecs.entity_from_uid(uid.0)) .and_then(|uid| ecs.entity_from_uid(uid))
.map(|entity_b| { .map(|entity_b| {
// Notify both parties that the trade ended // Notify both parties that the trade ended
let clients = ecs.read_storage::<Client>(); let clients = ecs.read_storage::<Client>();

View File

@ -148,7 +148,7 @@ pub fn handle_group(server: &mut Server, entity: Entity, manip: GroupManip) {
let uids = state.ecs().read_storage::<Uid>(); let uids = state.ecs().read_storage::<Uid>();
let alignments = state.ecs().read_storage::<comp::Alignment>(); let alignments = state.ecs().read_storage::<comp::Alignment>();
let target = match state.ecs().entity_from_uid(uid.into()) { let target = match state.ecs().entity_from_uid(uid) {
Some(t) => t, Some(t) => t,
None => { None => {
// Inform of failure // Inform of failure
@ -254,7 +254,7 @@ pub fn handle_group(server: &mut Server, entity: Entity, manip: GroupManip) {
let state = server.state_mut(); let state = server.state_mut();
let clients = state.ecs().read_storage::<Client>(); let clients = state.ecs().read_storage::<Client>();
let uids = state.ecs().read_storage::<Uid>(); let uids = state.ecs().read_storage::<Uid>();
let target = match state.ecs().entity_from_uid(uid.into()) { let target = match state.ecs().entity_from_uid(uid) {
Some(t) => t, Some(t) => t,
None => { None => {
// Inform of failure // Inform of failure

View File

@ -120,8 +120,7 @@ pub fn handle_inventory(server: &mut Server, entity: EcsEntity, manip: comp::Inv
match manip { match manip {
comp::InventoryManip::Pickup(pickup_uid) => { comp::InventoryManip::Pickup(pickup_uid) => {
let item_entity = let item_entity = if let Some(item_entity) = state.ecs().entity_from_uid(pickup_uid) {
if let Some(item_entity) = state.ecs().entity_from_uid(pickup_uid.into()) {
item_entity item_entity
} else { } else {
// Item entity could not be found - most likely because the entity // Item entity could not be found - most likely because the entity

View File

@ -30,7 +30,7 @@ pub fn handle_invite(server: &mut Server, inviter: Entity, invitee_uid: Uid, kin
let max_group_size = server.settings().max_player_group_size; let max_group_size = server.settings().max_player_group_size;
let state = server.state_mut(); let state = server.state_mut();
let clients = state.ecs().read_storage::<Client>(); let clients = state.ecs().read_storage::<Client>();
let invitee = match state.ecs().entity_from_uid(invitee_uid.into()) { let invitee = match state.ecs().entity_from_uid(invitee_uid) {
Some(t) => t, Some(t) => t,
None => { None => {
// Inform of failure // Inform of failure
@ -85,7 +85,7 @@ pub fn handle_invite(server: &mut Server, inviter: Entity, invitee_uid: Uid, kin
if let Some(active_trade) = trades.entity_trades.get(&inviter_uid).copied() { if let Some(active_trade) = trades.entity_trades.get(&inviter_uid).copied() {
trades trades
.decline_trade(active_trade, inviter_uid) .decline_trade(active_trade, inviter_uid)
.and_then(|u| state.ecs().entity_from_uid(u.0)) .and_then(|u| state.ecs().entity_from_uid(u))
.map(|e| { .map(|e| {
if let Some(client) = clients.get(e) { if let Some(client) = clients.get(e) {
client client
@ -309,7 +309,7 @@ fn handle_invite_answer(
if let Some(active_trade) = trades.entity_trades.get(&invitee_uid).copied() { if let Some(active_trade) = trades.entity_trades.get(&invitee_uid).copied() {
trades trades
.decline_trade(active_trade, invitee_uid) .decline_trade(active_trade, invitee_uid)
.and_then(|u| state.ecs().entity_from_uid(u.0)) .and_then(|u| state.ecs().entity_from_uid(u))
.map(|e| { .map(|e| {
if let Some(client) = clients.get(e) { if let Some(client) = clients.get(e) {
client client

View File

@ -13,7 +13,7 @@ use common::{
use common_base::span; use common_base::span;
use common_net::msg::{PlayerListUpdate, ServerGeneral}; use common_net::msg::{PlayerListUpdate, ServerGeneral};
use common_state::State; use common_state::State;
use specs::{saveload::MarkerAllocator, Builder, Entity as EcsEntity, Join, WorldExt}; use specs::{Builder, Entity as EcsEntity, Join, WorldExt};
use tracing::{debug, error, trace, warn, Instrument}; use tracing::{debug, error, trace, warn, Instrument};
pub fn handle_character_delete( pub fn handle_character_delete(
@ -331,8 +331,8 @@ pub fn handle_possess(server: &mut Server, possessor_uid: Uid, possessee_uid: Ui
let mut delete_entity = None; let mut delete_entity = None;
if let (Some(possessor), Some(possessee)) = ( if let (Some(possessor), Some(possessee)) = (
state.ecs().entity_from_uid(possessor_uid.into()), state.ecs().entity_from_uid(possessor_uid),
state.ecs().entity_from_uid(possessee_uid.into()), state.ecs().entity_from_uid(possessee_uid),
) { ) {
// In this section we check various invariants and can return early if any of // In this section we check various invariants and can return early if any of
// them are not met. // them are not met.

View File

@ -64,7 +64,7 @@ pub(super) fn handle_process_trade_action(
if let TradeAction::Decline = action { if let TradeAction::Decline = action {
let to_notify = trades.decline_trade(trade_id, uid); let to_notify = trades.decline_trade(trade_id, uid);
to_notify to_notify
.and_then(|u| server.state.ecs().entity_from_uid(u.0)) .and_then(|u| server.state.ecs().entity_from_uid(u))
.map(|e| { .map(|e| {
server.notify_client(e, ServerGeneral::FinishedTrade(TradeResult::Declined)); server.notify_client(e, ServerGeneral::FinishedTrade(TradeResult::Declined));
notify_agent_simple( notify_agent_simple(
@ -78,7 +78,7 @@ pub(super) fn handle_process_trade_action(
let ecs = server.state.ecs(); let ecs = server.state.ecs();
let inventories = ecs.read_component::<Inventory>(); let inventories = ecs.read_component::<Inventory>();
let get_inventory = |uid: Uid| { let get_inventory = |uid: Uid| {
if let Some(entity) = ecs.entity_from_uid(uid.0) { if let Some(entity) = ecs.entity_from_uid(uid) {
inventories.get(entity) inventories.get(entity)
} else { } else {
None None
@ -92,7 +92,7 @@ pub(super) fn handle_process_trade_action(
let result = commit_trade(server.state.ecs(), entry.get()); let result = commit_trade(server.state.ecs(), entry.get());
entry.remove(); entry.remove();
for party in parties.iter() { for party in parties.iter() {
if let Some(e) = server.state.ecs().entity_from_uid(party.0) { if let Some(e) = server.state.ecs().entity_from_uid(*party) {
server.notify_client(e, ServerGeneral::FinishedTrade(result.clone())); server.notify_client(e, ServerGeneral::FinishedTrade(result.clone()));
notify_agent_simple( notify_agent_simple(
server.state.ecs().write_storage::<Agent>(), server.state.ecs().write_storage::<Agent>(),
@ -110,7 +110,7 @@ pub(super) fn handle_process_trade_action(
// sadly there is no map and collect on arrays // sadly there is no map and collect on arrays
for i in 0..2 { for i in 0..2 {
// parties.len()) { // parties.len()) {
entities[i] = server.state.ecs().entity_from_uid(parties[i].0); entities[i] = server.state.ecs().entity_from_uid(parties[i]);
if let Some(e) = entities[i] { if let Some(e) = entities[i] {
inventories[i] = server inventories[i] = server
.state .state
@ -180,7 +180,7 @@ pub(crate) fn cancel_trades_for(state: &mut common_state::State, entity: EcsEnti
}; };
let to_notify = trades.decline_trade(active_trade, uid); let to_notify = trades.decline_trade(active_trade, uid);
to_notify.and_then(|u| ecs.entity_from_uid(u.0)).map(|e| { to_notify.and_then(|u| ecs.entity_from_uid(u)).map(|e| {
if let Some(c) = ecs.read_storage::<crate::Client>().get(e) { if let Some(c) = ecs.read_storage::<crate::Client>().get(e) {
c.send_fallible(ServerGeneral::FinishedTrade(TradeResult::Declined)); c.send_fallible(ServerGeneral::FinishedTrade(TradeResult::Declined));
} }
@ -198,7 +198,7 @@ pub(crate) fn cancel_trades_for(state: &mut common_state::State, entity: EcsEnti
fn commit_trade(ecs: &specs::World, trade: &PendingTrade) -> TradeResult { fn commit_trade(ecs: &specs::World, trade: &PendingTrade) -> TradeResult {
let mut entities = Vec::new(); let mut entities = Vec::new();
for party in trade.parties.iter() { for party in trade.parties.iter() {
match ecs.entity_from_uid(party.0) { match ecs.entity_from_uid(*party) {
Some(entity) => entities.push(entity), Some(entity) => entities.push(entity),
None => return TradeResult::Declined, None => return TradeResult::Declined,
} }

View File

@ -36,10 +36,7 @@ use common_net::{
}; };
use common_state::State; use common_state::State;
use rand::prelude::*; use rand::prelude::*;
use specs::{ use specs::{Builder, Entity as EcsEntity, EntityBuilder as EcsEntityBuilder, Join, WorldExt};
saveload::MarkerAllocator, Builder, Entity as EcsEntity, EntityBuilder as EcsEntityBuilder,
Join, WorldExt,
};
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use tracing::{trace, warn}; use tracing::{trace, warn};
use vek::*; use vek::*;
@ -169,7 +166,7 @@ impl StateExt for State {
let groups = self.ecs().read_storage::<Group>(); let groups = self.ecs().read_storage::<Group>();
let damage_contributor = source.and_then(|uid| { let damage_contributor = source.and_then(|uid| {
self.ecs().entity_from_uid(uid.0).map(|attacker_entity| { self.ecs().entity_from_uid(uid).map(|attacker_entity| {
DamageContributor::new(uid, groups.get(attacker_entity).cloned()) DamageContributor::new(uid, groups.get(attacker_entity).cloned())
}) })
}); });
@ -214,7 +211,7 @@ impl StateExt for State {
if !character_state.is_stunned() { if !character_state.is_stunned() {
let groups = self.ecs().read_storage::<Group>(); let groups = self.ecs().read_storage::<Group>();
let damage_contributor = source.and_then(|uid| { let damage_contributor = source.and_then(|uid| {
self.ecs().entity_from_uid(uid.0).map(|attacker_entity| { self.ecs().entity_from_uid(uid).map(|attacker_entity| {
DamageContributor::new(uid, groups.get(attacker_entity).cloned()) DamageContributor::new(uid, groups.get(attacker_entity).cloned())
}) })
}); });
@ -862,10 +859,11 @@ impl StateExt for State {
.clone() .clone()
.map_group(|_| group_info.map_or_else(|| "???".to_string(), |i| i.name.clone())); .map_group(|_| group_info.map_or_else(|| "???".to_string(), |i| i.name.clone()));
let uid_allocator = ecs.read_resource::<UidAllocator>();
let entity_from_uid = |uid| uid_allocator.retrieve_entity_internal(uid);
if msg.chat_type.uid().map_or(true, |sender| { if msg.chat_type.uid().map_or(true, |sender| {
(*ecs.read_resource::<UidAllocator>()) entity_from_uid(sender).map_or(false, |e| {
.retrieve_entity_internal(sender.0)
.map_or(false, |e| {
self.validate_chat_msg( self.validate_chat_msg(
e, e,
&msg.chat_type, &msg.chat_type,
@ -911,8 +909,7 @@ impl StateExt for State {
.unwrap_or_default() .unwrap_or_default()
{ {
// Send kill message to the dead player's group // Send kill message to the dead player's group
let killed_entity = let killed_entity = entity_from_uid(*uid);
(*ecs.read_resource::<UidAllocator>()).retrieve_entity_internal(uid.0);
let groups = ecs.read_storage::<Group>(); let groups = ecs.read_storage::<Group>();
let killed_group = killed_entity.and_then(|e| groups.get(e)); let killed_group = killed_entity.and_then(|e| groups.get(e));
if let Some(g) = &killed_group { if let Some(g) = &killed_group {
@ -947,8 +944,7 @@ impl StateExt for State {
} }
}, },
comp::ChatType::Say(uid) => { comp::ChatType::Say(uid) => {
let entity_opt = let entity_opt = entity_from_uid(*uid);
(*ecs.read_resource::<UidAllocator>()).retrieve_entity_internal(uid.0);
let positions = ecs.read_storage::<comp::Pos>(); let positions = ecs.read_storage::<comp::Pos>();
if let Some(speaker_pos) = entity_opt.and_then(|e| positions.get(e)) { if let Some(speaker_pos) = entity_opt.and_then(|e| positions.get(e)) {
@ -960,8 +956,7 @@ impl StateExt for State {
} }
}, },
comp::ChatType::Region(uid) => { comp::ChatType::Region(uid) => {
let entity_opt = let entity_opt = entity_from_uid(*uid);
(*ecs.read_resource::<UidAllocator>()).retrieve_entity_internal(uid.0);
let positions = ecs.read_storage::<comp::Pos>(); let positions = ecs.read_storage::<comp::Pos>();
if let Some(speaker_pos) = entity_opt.and_then(|e| positions.get(e)) { if let Some(speaker_pos) = entity_opt.and_then(|e| positions.get(e)) {
@ -973,8 +968,7 @@ impl StateExt for State {
} }
}, },
comp::ChatType::Npc(uid) => { comp::ChatType::Npc(uid) => {
let entity_opt = let entity_opt = entity_from_uid(*uid);
(*ecs.read_resource::<UidAllocator>()).retrieve_entity_internal(uid.0);
let positions = ecs.read_storage::<comp::Pos>(); let positions = ecs.read_storage::<comp::Pos>();
if let Some(speaker_pos) = entity_opt.and_then(|e| positions.get(e)) { if let Some(speaker_pos) = entity_opt.and_then(|e| positions.get(e)) {
@ -986,8 +980,7 @@ impl StateExt for State {
} }
}, },
comp::ChatType::NpcSay(uid) => { comp::ChatType::NpcSay(uid) => {
let entity_opt = let entity_opt = entity_from_uid(*uid);
(*ecs.read_resource::<UidAllocator>()).retrieve_entity_internal(uid.0);
let positions = ecs.read_storage::<comp::Pos>(); let positions = ecs.read_storage::<comp::Pos>();
if let Some(speaker_pos) = entity_opt.and_then(|e| positions.get(e)) { if let Some(speaker_pos) = entity_opt.and_then(|e| positions.get(e)) {

View File

@ -19,7 +19,7 @@ use common_base::prof_span;
use common_ecs::{Job, Origin, ParMode, Phase, System}; use common_ecs::{Job, Origin, ParMode, Phase, System};
use rand::thread_rng; use rand::thread_rng;
use rayon::iter::ParallelIterator; use rayon::iter::ParallelIterator;
use specs::{saveload::MarkerAllocator, Join, ParJoin, Read, WriteStorage}; use specs::{Join, ParJoin, Read, WriteStorage};
/// This system will allow NPCs to modify their controller /// This system will allow NPCs to modify their controller
#[derive(Default)] #[derive(Default)]
@ -105,7 +105,7 @@ impl<'a> System<'a> for Sys {
.and_then(|is_rider| { .and_then(|is_rider| {
read_data read_data
.uid_allocator .uid_allocator
.retrieve_entity_internal(is_rider.mount.into()) .retrieve_entity_internal(is_rider.mount)
}) })
.or_else(|| { .or_else(|| {
is_volume_rider.and_then(|is_volume_rider| { is_volume_rider.and_then(|is_volume_rider| {

View File

@ -13,10 +13,7 @@ use common::{
rtsim::{NpcAction, RtSimEntity}, rtsim::{NpcAction, RtSimEntity},
}; };
use rand::{prelude::ThreadRng, thread_rng, Rng}; use rand::{prelude::ThreadRng, thread_rng, Rng};
use specs::{ use specs::Entity as EcsEntity;
saveload::{Marker, MarkerAllocator},
Entity as EcsEntity,
};
use vek::{Vec2, Vec3}; use vek::{Vec2, Vec3};
use self::interaction::{ use self::interaction::{
@ -250,7 +247,7 @@ fn target_if_attacked(bdata: &mut BehaviorData) -> bool {
if let Some(attacker) = bdata if let Some(attacker) = bdata
.read_data .read_data
.uid_allocator .uid_allocator
.retrieve_entity_internal(by.uid().0) .retrieve_entity_internal(by.uid())
{ {
// If target is dead or invulnerable (for now, this only // If target is dead or invulnerable (for now, this only
// means safezone), untarget them and idle. // means safezone), untarget them and idle.
@ -460,7 +457,7 @@ fn set_owner_if_no_target(bdata: &mut BehaviorData) -> bool {
if bdata.agent.target.is_none() && small_chance { if bdata.agent.target.is_none() && small_chance {
if let Some(Alignment::Owned(owner)) = bdata.agent_data.alignment { if let Some(Alignment::Owned(owner)) = bdata.agent_data.alignment {
if let Some(owner) = get_entity_by_id(owner.id(), bdata.read_data) { if let Some(owner) = get_entity_by_id(*owner, bdata.read_data) {
let owner_pos = bdata.read_data.positions.get(owner).map(|pos| pos.0); let owner_pos = bdata.read_data.positions.get(owner).map(|pos| pos.0);
bdata.agent.target = Some(Target::new( bdata.agent.target = Some(Target::new(

View File

@ -14,7 +14,6 @@ use common::{
trade::{TradeAction, TradePhase, TradeResult}, trade::{TradeAction, TradePhase, TradeResult},
}; };
use rand::{thread_rng, Rng}; use rand::{thread_rng, Rng};
use specs::saveload::Marker;
use crate::sys::agent::util::get_entity_by_id; use crate::sys::agent::util::get_entity_by_id;
@ -87,7 +86,7 @@ pub fn handle_inbox_talk(bdata: &mut BehaviorData) -> bool {
} }
if let Some(AgentEvent::Talk(by, subject)) = agent.inbox.pop_front() { if let Some(AgentEvent::Talk(by, subject)) = agent.inbox.pop_front() {
let by_entity = get_entity_by_id(by.id(), read_data); let by_entity = get_entity_by_id(by, read_data);
if let Some(rtsim_outbox) = &mut agent.rtsim_outbox { if let Some(rtsim_outbox) = &mut agent.rtsim_outbox {
if let Subject::Regular if let Subject::Regular
@ -297,7 +296,7 @@ pub fn handle_inbox_trade_invite(bdata: &mut BehaviorData) -> bool {
// stand still and looking towards the trading player // stand still and looking towards the trading player
controller.push_action(ControlAction::Stand); controller.push_action(ControlAction::Stand);
controller.push_action(ControlAction::Talk); controller.push_action(ControlAction::Talk);
if let Some(target) = get_entity_by_id(with.id(), read_data) { if let Some(target) = get_entity_by_id(with, read_data) {
let target_pos = read_data.positions.get(target).map(|pos| pos.0); let target_pos = read_data.positions.get(target).map(|pos| pos.0);
agent.target = Some(Target::new( agent.target = Some(Target::new(
@ -344,7 +343,7 @@ pub fn handle_inbox_trade_accepted(bdata: &mut BehaviorData) -> bool {
if let Some(AgentEvent::TradeAccepted(with)) = agent.inbox.pop_front() { if let Some(AgentEvent::TradeAccepted(with)) = agent.inbox.pop_front() {
if !agent.behavior.is(BehaviorState::TRADING) { if !agent.behavior.is(BehaviorState::TRADING) {
if let Some(target) = get_entity_by_id(with.id(), read_data) { if let Some(target) = get_entity_by_id(with, read_data) {
let target_pos = read_data.positions.get(target).map(|pos| pos.0); let target_pos = read_data.positions.get(target).map(|pos| pos.0);
agent.target = Some(Target::new( agent.target = Some(Target::new(
@ -561,7 +560,7 @@ pub fn handle_inbox_cancel_interactions(bdata: &mut BehaviorData) -> bool {
let used = match msg { let used = match msg {
AgentEvent::Talk(by, _) | AgentEvent::TradeAccepted(by) => { AgentEvent::Talk(by, _) | AgentEvent::TradeAccepted(by) => {
if let (Some(target), Some(speaker)) = if let (Some(target), Some(speaker)) =
(agent.target, get_entity_by_id(by.id(), bdata.read_data)) (agent.target, get_entity_by_id(*by, bdata.read_data))
{ {
// in combat, speak to players that aren't the current target // in combat, speak to players that aren't the current target
if !target.hostile || target.target != speaker { if !target.hostile || target.target != speaker {
@ -578,7 +577,7 @@ pub fn handle_inbox_cancel_interactions(bdata: &mut BehaviorData) -> bool {
AgentEvent::TradeInvite(by) => { AgentEvent::TradeInvite(by) => {
controller.push_invite_response(InviteResponse::Decline); controller.push_invite_response(InviteResponse::Decline);
if let (Some(target), Some(speaker)) = if let (Some(target), Some(speaker)) =
(agent.target, get_entity_by_id(by.id(), bdata.read_data)) (agent.target, get_entity_by_id(*by, bdata.read_data))
{ {
// in combat, speak to players that aren't the current target // in combat, speak to players that aren't the current target
if !target.hostile || target.target != speaker { if !target.hostile || target.target != speaker {

View File

@ -3,7 +3,7 @@ use common::{
uid::UidAllocator, uid::UidAllocator,
}; };
use common_ecs::{Job, Origin, Phase, System}; use common_ecs::{Job, Origin, Phase, System};
use specs::{saveload::MarkerAllocator, Entities, Entity, Join, Read, WriteStorage}; use specs::{Entities, Entity, Join, Read, WriteStorage};
use tracing::debug; use tracing::debug;
// This system manages loot that exists in the world // This system manages loot that exists in the world
@ -33,7 +33,7 @@ impl<'a> System<'a> for Sys {
loot_owner.expired() loot_owner.expired()
|| match loot_owner.owner() { || match loot_owner.owner() {
LootOwnerKind::Player(uid) => uid_allocator LootOwnerKind::Player(uid) => uid_allocator
.retrieve_entity_internal(uid.into()) .retrieve_entity_internal(uid)
.map_or(true, |entity| !entities.is_alive(entity)), .map_or(true, |entity| !entities.is_alive(entity)),
LootOwnerKind::Group(group) => group_manager.group_info(group).is_none(), LootOwnerKind::Group(group) => group_manager.group_info(group).is_none(),
} }

View File

@ -4,9 +4,7 @@ use common::{
uid::UidAllocator, uid::UidAllocator,
}; };
use common_ecs::{Job, Origin, Phase, System}; use common_ecs::{Job, Origin, Phase, System};
use specs::{ use specs::{Entities, Entity, Join, Read, ReadExpect, ReadStorage, WriteStorage};
saveload::MarkerAllocator, Entities, Entity, Join, Read, ReadExpect, ReadStorage, WriteStorage,
};
/// This system is responsible for handling pets /// This system is responsible for handling pets
#[derive(Default)] #[derive(Default)]
@ -36,12 +34,12 @@ impl<'a> System<'a> for Sys {
let lost_pets: Vec<(Entity, Pos)> = (&entities, &positions, &alignments, &pets) let lost_pets: Vec<(Entity, Pos)> = (&entities, &positions, &alignments, &pets)
.join() .join()
.filter_map(|(entity, pos, alignment, _)| match alignment { .filter_map(|(entity, pos, alignment, _)| match alignment {
Alignment::Owned(owner_uid) => Some((entity, pos, owner_uid)), Alignment::Owned(owner_uid) => Some((entity, pos, *owner_uid)),
_ => None, _ => None,
}) })
.filter_map(|(pet_entity, pet_pos, owner_uid)| { .filter_map(|(pet_entity, pet_pos, owner_uid)| {
uid_allocator uid_allocator
.retrieve_entity_internal(owner_uid.0) .retrieve_entity_internal(owner_uid)
.and_then(|owner_entity| { .and_then(|owner_entity| {
match (positions.get(owner_entity), physics.get(owner_entity)) { match (positions.get(owner_entity), physics.get(owner_entity)) {
(Some(position), Some(physics)) => { (Some(position), Some(physics)) => {

View File

@ -28,7 +28,7 @@ use conrod_core::{
widget_ids, Color, Colorable, Labelable, Positionable, Sizeable, Widget, WidgetCommon, widget_ids, Color, Colorable, Labelable, Positionable, Sizeable, Widget, WidgetCommon,
}; };
use i18n::Localization; use i18n::Localization;
use specs::{saveload::MarkerAllocator, WorldExt}; use specs::WorldExt;
widget_ids! { widget_ids! {
pub struct Ids { pub struct Ids {
@ -202,7 +202,7 @@ impl<'a> Widget for Group<'a> {
None => client None => client
.state() .state()
.ecs() .ecs()
.entity_from_uid(uid.0) .entity_from_uid(uid)
.and_then(|entity| { .and_then(|entity| {
client client
.state() .state()
@ -382,7 +382,7 @@ impl<'a> Widget for Group<'a> {
let mut total_buff_count = 0; let mut total_buff_count = 0;
for (i, &uid) in group_members.iter().copied().enumerate() { for (i, &uid) in group_members.iter().copied().enumerate() {
self.show.group = true; self.show.group = true;
let entity = uid_allocator.retrieve_entity_internal(uid.into()); let entity = uid_allocator.retrieve_entity_internal(uid);
let stats = entity.and_then(|entity| stats.get(entity)); let stats = entity.and_then(|entity| stats.get(entity));
let skill_set = entity.and_then(|entity| skill_sets.get(entity)); let skill_set = entity.and_then(|entity| skill_sets.get(entity));
let health = entity.and_then(|entity| healths.get(entity)); let health = entity.and_then(|entity| healths.get(entity));

View File

@ -27,7 +27,7 @@ use conrod_core::{
widget_ids, Color, Colorable, Labelable, Positionable, Sizeable, UiCell, Widget, WidgetCommon, widget_ids, Color, Colorable, Labelable, Positionable, Sizeable, UiCell, Widget, WidgetCommon,
}; };
use i18n::Localization; use i18n::Localization;
use specs::{saveload::MarkerAllocator, WorldExt}; use specs::WorldExt;
use std::borrow::Cow; use std::borrow::Cow;
use vek::*; use vek::*;
use winit::event::MouseButton; use winit::event::MouseButton;
@ -1251,7 +1251,7 @@ impl<'a> Widget for Map<'a> {
}) })
}; };
for (i, &uid) in group_members.iter().copied().enumerate() { for (i, &uid) in group_members.iter().copied().enumerate() {
let entity = uid_allocator.retrieve_entity_internal(uid.into()); let entity = uid_allocator.retrieve_entity_internal(uid);
let member_pos = entity.and_then(|entity| member_pos.get(entity)); let member_pos = entity.and_then(|entity| member_pos.get(entity));
let stats = entity.and_then(|entity| stats.get(entity)); let stats = entity.and_then(|entity| stats.get(entity));
let name = if let Some(stats) = stats { let name = if let Some(stats) = stats {
@ -1324,7 +1324,7 @@ impl<'a> Widget for Map<'a> {
.map(|info| info.player_alias.as_str()) .map(|info| info.player_alias.as_str())
.or_else(|| { .or_else(|| {
uid_allocator uid_allocator
.retrieve_entity_internal(uid.into()) .retrieve_entity_internal(uid)
.and_then(|entity| stats.get(entity)) .and_then(|entity| stats.get(entity))
.map(|stats| stats.name.as_str()) .map(|stats| stats.name.as_str())
}) })

View File

@ -28,7 +28,7 @@ use conrod_core::{
}; };
use hashbrown::HashMap; use hashbrown::HashMap;
use image::{DynamicImage, RgbaImage}; use image::{DynamicImage, RgbaImage};
use specs::{saveload::MarkerAllocator, WorldExt}; use specs::WorldExt;
use std::sync::Arc; use std::sync::Arc;
use vek::*; use vek::*;
@ -773,7 +773,7 @@ impl<'a> Widget for MiniMap<'a> {
}) })
}; };
for (i, &uid) in group_members.iter().copied().enumerate() { for (i, &uid) in group_members.iter().copied().enumerate() {
let entity = uid_allocator.retrieve_entity_internal(uid.into()); let entity = uid_allocator.retrieve_entity_internal(uid);
let member_pos = entity.and_then(|entity| member_pos.get(entity)); let member_pos = entity.and_then(|entity| member_pos.get(entity));
if let Some(member_pos) = member_pos { if let Some(member_pos) = member_pos {

View File

@ -1247,8 +1247,7 @@ impl HudCollectFailedReason {
CollectFailedReason::LootOwned { owner, expiry_secs } => { CollectFailedReason::LootOwned { owner, expiry_secs } => {
let owner = match owner { let owner = match owner {
LootOwnerKind::Player(owner_uid) => { LootOwnerKind::Player(owner_uid) => {
let maybe_owner_name = let maybe_owner_name = ecs.entity_from_uid(*owner_uid).and_then(|entity| {
ecs.entity_from_uid((*owner_uid).into()).and_then(|entity| {
ecs.read_storage::<comp::Stats>() ecs.read_storage::<comp::Stats>()
.get(entity) .get(entity)
.map(|stats| stats.name.clone()) .map(|stats| stats.name.clone())
@ -4056,7 +4055,7 @@ impl Hud {
let ecs = client.state().ecs(); let ecs = client.state().ecs();
let inventories = ecs.read_component::<comp::Inventory>(); let inventories = ecs.read_component::<comp::Inventory>();
let get_inventory = |uid: Uid| { let get_inventory = |uid: Uid| {
if let Some(entity) = ecs.entity_from_uid(uid.0) { if let Some(entity) = ecs.entity_from_uid(uid) {
inventories.get(entity) inventories.get(entity)
} else { } else {
None None
@ -4914,7 +4913,7 @@ impl Hud {
let me = client.entity(); let me = client.entity();
let my_uid = uids.get(me); let my_uid = uids.get(me);
if let Some(entity) = ecs.entity_from_uid(info.target.0) { if let Some(entity) = ecs.entity_from_uid(info.target) {
if let Some(floater_list) = hp_floater_lists.get_mut(entity) { if let Some(floater_list) = hp_floater_lists.get_mut(entity) {
let hit_me = my_uid.map_or(false, |&uid| { let hit_me = my_uid.map_or(false, |&uid| {
(info.target == uid) && global_state.settings.interface.sct_inc_dmg (info.target == uid) && global_state.settings.interface.sct_inc_dmg

View File

@ -204,7 +204,7 @@ impl<'a> Trade<'a> {
let inventories = self.client.inventories(); let inventories = self.client.inventories();
let check_if_us = |who: usize| -> Option<_> { let check_if_us = |who: usize| -> Option<_> {
let uid = trade.parties[who]; let uid = trade.parties[who];
let entity = self.client.state().ecs().entity_from_uid(uid.0)?; let entity = self.client.state().ecs().entity_from_uid(uid)?;
let is_ours = entity == self.client.entity(); let is_ours = entity == self.client.entity();
Some(((who, uid, entity), is_ours)) Some(((who, uid, entity), is_ours))
}; };

View File

@ -62,7 +62,7 @@ use core::{
}; };
use guillotiere::AtlasAllocator; use guillotiere::AtlasAllocator;
use hashbrown::HashMap; use hashbrown::HashMap;
use specs::{saveload::MarkerAllocator, Entity as EcsEntity, Join, LazyUpdate, WorldExt}; use specs::{Entity as EcsEntity, Join, LazyUpdate, WorldExt};
use std::sync::Arc; use std::sync::Arc;
use treeculler::{BVol, BoundingSphere}; use treeculler::{BVol, BoundingSphere};
use vek::*; use vek::*;
@ -1055,7 +1055,7 @@ impl FigureMgr {
let mount_transform_pos = (|| -> Option<_> { let mount_transform_pos = (|| -> Option<_> {
if let Some(is_rider) = is_rider { if let Some(is_rider) = is_rider {
let mount = is_rider.mount; let mount = is_rider.mount;
let mount = uid_allocator.retrieve_entity_internal(mount.into())?; let mount = uid_allocator.retrieve_entity_internal(mount)?;
let body = *bodies.get(mount)?; let body = *bodies.get(mount)?;
let meta = self.states.get_mut(&body, &mount)?; let meta = self.states.get_mut(&body, &mount)?;
Some((meta.mount_transform, meta.mount_world_pos)) Some((meta.mount_transform, meta.mount_world_pos))

View File

@ -26,7 +26,7 @@ use common::{
use common_base::span; use common_base::span;
use hashbrown::HashMap; use hashbrown::HashMap;
use rand::prelude::*; use rand::prelude::*;
use specs::{saveload::MarkerAllocator, Join, WorldExt}; use specs::{Join, WorldExt};
use std::{ use std::{
f32::consts::{PI, TAU}, f32::consts::{PI, TAU},
time::Duration, time::Duration,
@ -289,7 +289,7 @@ impl ParticleMgr {
if target if target
.and_then(|target| { .and_then(|target| {
ecs.read_resource::<UidAllocator>() ecs.read_resource::<UidAllocator>()
.retrieve_entity_internal(target.0) .retrieve_entity_internal(target)
}) })
.and_then(|entity| { .and_then(|entity| {
ecs.read_storage::<Body>() ecs.read_storage::<Body>()

View File

@ -294,7 +294,7 @@ impl SessionState {
}; };
let target_name = match client.player_list().get(&target) { let target_name = match client.player_list().get(&target) {
Some(info) => info.player_alias.clone(), Some(info) => info.player_alias.clone(),
None => match client.state().ecs().entity_from_uid(target.0) { None => match client.state().ecs().entity_from_uid(target) {
Some(entity) => { Some(entity) => {
let stats = client.state().read_storage::<Stats>(); let stats = client.state().read_storage::<Stats>();
stats stats
@ -362,9 +362,7 @@ impl SessionState {
entity: uid, entity: uid,
reason, reason,
} => { } => {
if let Some(entity) = if let Some(entity) = client.state().ecs().entity_from_uid(uid) {
client.state().ecs().entity_from_uid(uid.into())
{
self.hud.add_failed_entity_pickup( self.hud.add_failed_entity_pickup(
entity, entity,
HudCollectFailedReason::from_server_reason( HudCollectFailedReason::from_server_reason(