//! Contains an "x macro" for all synced components as well as [NetSync] //! implementations for those components. //! //! //! An x macro accepts another macro as input and calls it with a list of //! inputs. This allows adding components to the list in the x macro declaration //! and then writing macros that will accept this list and generate code that //! handles every synced component without further repitition of the component //! set. //! //! This module also re-exports all the component types that are synced. //! //! A glob import from this can be used so that the component types are in scope //! when using the x macro defined here which requires this. /// This provides a lowercase name and the component type. //#[rustfmt::skip] #[macro_export] macro_rules! synced_components { ($macro:ident) => { $macro! { body: Body, stats: Stats, buffs: Buffs, auras: Auras, energy: Energy, health: Health, poise: Poise, light_emitter: LightEmitter, item: Item, scale: Scale, group: Group, is_mount: IsMount, is_rider: IsRider, mass: Mass, density: Density, collider: Collider, sticky: Sticky, character_state: CharacterState, shockwave: Shockwave, beam_segment: BeamSegment, alignment: Alignment, // TODO: evaluate if this can be `FromClient` combo: Combo, // TODO: evaluate if this is used on the client, // and if so what it is used for player: Player, // TODO: change this to FromClient and sync the bare minimum // from other entities (e.g. just keys needed to show appearance // based on their loadout). Also, it looks like this actually has // an alternative sync method implemented in entity_sync via // ServerGeneral::InventoryUpdate so we could use that instead // or remove the part where it clones the inventory. inventory: Inventory, // Synced to the client only for its own entity skill_set: SkillSet, active_abilities: ActiveAbilities, can_build: CanBuild, } }; } macro_rules! reexport_comps { ($($name:ident: $type:ident,)*) => { mod inner { pub use common::comp::*; use common::link::Is; use common::mounting::{Mount, Rider}; pub type IsMount = Is; pub type IsRider = Is; } $(pub use inner::$type;)* } } synced_components!(reexport_comps); // =============================== // === NetSync implementations === // =============================== use crate::sync::{NetSync, SyncFrom}; impl NetSync for Body { const SYNC_FROM: SyncFrom = SyncFrom::AllEntities; } impl NetSync for Stats { const SYNC_FROM: SyncFrom = SyncFrom::AllEntities; } impl NetSync for Buffs { const SYNC_FROM: SyncFrom = SyncFrom::AllEntities; } impl NetSync for Auras { const SYNC_FROM: SyncFrom = SyncFrom::AllEntities; } impl NetSync for Energy { const SYNC_FROM: SyncFrom = SyncFrom::AllEntities; } impl NetSync for Health { const SYNC_FROM: SyncFrom = SyncFrom::AllEntities; fn pre_insert(&mut self, world: &specs::World) { use common::resources::Time; use specs::WorldExt; // Time isn't synced between client and server so replace the Time from the // server with the Client's local Time to enable accurate comparison. self.last_change.time = *world.read_resource::