Crate unification (#88)
* move client/server/config into shared * move platforms into shared * move head drops into shared * move tb_entities to shared * reduce server to just a call into shared * get solo play working * fix server opening window * fix fmt * extracted a few more modules from client * near completely migrated client * fixed duplicate CharacterInputEnabled definition * simplify a few things related to builds * more simplifications * fix warnings/check * ci update * address comments * try fixing macos steam build * address comments * address comments * CI tweaks with default client feature --------- Co-authored-by: PROMETHIA-27 <electriccobras@gmail.com>
This commit is contained in:
231
crates/hedz_reloaded/src/protocol/mod.rs
Normal file
231
crates/hedz_reloaded/src/protocol/mod.rs
Normal file
@@ -0,0 +1,231 @@
|
||||
use crate::{
|
||||
GameState,
|
||||
abilities::{
|
||||
BuildExplosionSprite, curver::CurverProjectile, healing::Healing, thrown::ThrownProjectile,
|
||||
},
|
||||
animation::AnimationFlags,
|
||||
backpack::{Backpack, BackpackSwapEvent},
|
||||
camera::{CameraArmRotation, CameraTarget},
|
||||
cash::CashInventory,
|
||||
character::{AnimatedCharacter, HedzCharacter},
|
||||
control::{
|
||||
CashHealPressed, ClientInputs, ControllerSettings, Inputs, SelectLeftPressed,
|
||||
SelectRightPressed,
|
||||
controller_common::{MovementSpeedFactor, PlayerCharacterController},
|
||||
},
|
||||
cutscene::StartCutscene,
|
||||
global_observer,
|
||||
head::ActiveHead,
|
||||
heads::{ActiveHeads, heads_ui::UiActiveHeads},
|
||||
hitpoints::Hitpoints,
|
||||
npc::Npc,
|
||||
platforms::ActivePlatform,
|
||||
player::{Player, PlayerBodyMesh},
|
||||
tick::GameTick,
|
||||
utils::{
|
||||
auto_rotate::AutoRotation, billboards::Billboard, squish_animation::SquishAnimation,
|
||||
trail::SpawnTrail,
|
||||
},
|
||||
};
|
||||
use avian3d::prelude::{
|
||||
AngularInertia, AngularVelocity, CenterOfMass, Collider, ColliderDensity, CollisionLayers,
|
||||
LinearVelocity, LockedAxes, Mass, Position, RigidBody, Rotation,
|
||||
};
|
||||
use bevy::{ecs::system::SystemParam, platform::collections::HashMap, prelude::*};
|
||||
use bevy_replicon::prelude::{
|
||||
AppRuleExt, Channel, ClientEventAppExt, ClientMessageAppExt, ClientState, ServerEventAppExt,
|
||||
ServerMessageAppExt, SyncRelatedAppExt,
|
||||
};
|
||||
pub use components::*;
|
||||
pub use events::*;
|
||||
use happy_feet::{
|
||||
grounding::GroundingState,
|
||||
prelude::{
|
||||
CharacterDrag, CharacterGravity, CharacterMovement, GroundFriction, Grounding,
|
||||
GroundingConfig, KinematicVelocity, MoveInput, SteppingConfig,
|
||||
},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
pub mod components;
|
||||
pub mod events;
|
||||
pub mod messages;
|
||||
|
||||
pub fn plugin(app: &mut App) {
|
||||
app.add_client_message::<ClientInputs>(Channel::Unreliable)
|
||||
.add_client_message::<SelectLeftPressed>(Channel::Ordered)
|
||||
.add_client_message::<SelectRightPressed>(Channel::Ordered)
|
||||
.add_client_message::<CashHealPressed>(Channel::Ordered);
|
||||
|
||||
app.add_client_event::<ClientEnteredPlaying>(Channel::Ordered)
|
||||
.add_client_event::<BackpackSwapEvent>(Channel::Ordered);
|
||||
|
||||
app.add_server_message::<messages::DespawnTbMapEntity>(Channel::Unordered)
|
||||
.add_server_message::<messages::AssignClientPlayer>(Channel::Unordered);
|
||||
|
||||
app.add_server_event::<ClientHeadChanged>(Channel::Unordered)
|
||||
.add_server_event::<BuildExplosionSprite>(Channel::Unreliable)
|
||||
.add_server_event::<StartCutscene>(Channel::Ordered)
|
||||
.add_server_event::<events::PlaySound>(Channel::Unreliable)
|
||||
.add_server_event::<events::SetGameTick>(Channel::Ordered);
|
||||
|
||||
app.register_type::<PlayerId>();
|
||||
app.register_type::<TbMapEntityId>();
|
||||
app.register_type::<TbMapIdCounter>();
|
||||
app.register_type::<TbMapEntityMapping>();
|
||||
|
||||
app.init_resource::<PlayerIdMap>();
|
||||
app.init_resource::<TbMapIdCounter>();
|
||||
app.init_resource::<TbMapEntityMapping>();
|
||||
|
||||
app.replicate::<ChildOf>();
|
||||
app.sync_related_entities::<ChildOf>();
|
||||
|
||||
app.replicate_once::<components::GltfSceneRoot>()
|
||||
.replicate_once::<components::PlayerId>()
|
||||
.replicate::<components::TbMapEntityId>()
|
||||
.replicate::<ActiveHead>()
|
||||
.replicate::<ActiveHeads>()
|
||||
.replicate::<ActivePlatform>()
|
||||
.replicate::<AnimatedCharacter>()
|
||||
.replicate::<AnimationFlags>()
|
||||
.replicate_once::<AutoRotation>()
|
||||
.replicate::<Backpack>()
|
||||
.replicate::<Billboard>()
|
||||
.replicate_once::<CameraArmRotation>()
|
||||
.replicate_once::<CameraTarget>()
|
||||
.replicate::<CashInventory>()
|
||||
.replicate_once::<HedzCharacter>()
|
||||
.replicate_once::<Healing>()
|
||||
.replicate::<Hitpoints>()
|
||||
.replicate::<Inputs>()
|
||||
.replicate::<Name>()
|
||||
.replicate_once::<Player>()
|
||||
.replicate_once::<PlayerBodyMesh>()
|
||||
.replicate_once::<Npc>()
|
||||
.replicate::<SquishAnimation>()
|
||||
.replicate_once::<Transform>()
|
||||
.replicate_once::<SpawnTrail>()
|
||||
.replicate::<UiActiveHeads>()
|
||||
.replicate_as::<Visibility, SerVisibility>();
|
||||
|
||||
app.replicate_once::<ThrownProjectile>()
|
||||
.replicate_once::<CurverProjectile>();
|
||||
|
||||
// Physics components
|
||||
app.replicate::<AngularInertia>()
|
||||
.replicate::<AngularVelocity>()
|
||||
.replicate::<CenterOfMass>()
|
||||
.replicate_filtered_as::<Collider, NetworkedCollider, Without<SkipReplicateColliders>>()
|
||||
.replicate::<ColliderDensity>()
|
||||
.replicate::<CollisionLayers>()
|
||||
.replicate::<LinearVelocity>()
|
||||
.replicate::<LockedAxes>()
|
||||
.replicate::<Mass>()
|
||||
.replicate::<Position>()
|
||||
.replicate::<RigidBody>()
|
||||
.replicate::<Rotation>();
|
||||
|
||||
// Character controller components
|
||||
app.replicate::<CharacterDrag>()
|
||||
.replicate::<CharacterGravity>()
|
||||
.replicate::<CharacterMovement>()
|
||||
.replicate::<ControllerSettings>()
|
||||
.replicate::<GroundFriction>()
|
||||
.replicate::<Grounding>()
|
||||
.replicate::<GroundingConfig>()
|
||||
.replicate::<GroundingState>()
|
||||
.replicate::<KinematicVelocity>()
|
||||
.replicate::<MoveInput>()
|
||||
.replicate::<MovementSpeedFactor>()
|
||||
.replicate_once::<PlayerCharacterController>()
|
||||
.replicate::<SteppingConfig>();
|
||||
|
||||
app.add_systems(
|
||||
OnEnter(GameState::MapLoading),
|
||||
|mut counter: ResMut<TbMapIdCounter>| counter.reset(),
|
||||
);
|
||||
|
||||
global_observer!(app, set_game_tick);
|
||||
global_observer!(app, components::spawn_gltf_scene_roots);
|
||||
}
|
||||
|
||||
#[derive(SystemParam)]
|
||||
pub struct NetworkEnv<'w> {
|
||||
client_state: Res<'w, State<ClientState>>,
|
||||
}
|
||||
|
||||
impl NetworkEnv<'_> {
|
||||
/// Returns true if this process is currently responsible for being the server/host/"source of truth".
|
||||
/// May change over time.
|
||||
pub fn is_server(&self) -> bool {
|
||||
matches!(**self.client_state, ClientState::Disconnected)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_server(state: Res<State<ClientState>>) -> bool {
|
||||
matches!(**state, ClientState::Disconnected)
|
||||
}
|
||||
|
||||
fn set_game_tick(on: On<SetGameTick>, mut tick: ResMut<GameTick>) {
|
||||
tick.0 = on.event().0;
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
enum SerVisibility {
|
||||
Inherited,
|
||||
Hidden,
|
||||
Visible,
|
||||
}
|
||||
|
||||
impl From<Visibility> for SerVisibility {
|
||||
fn from(value: Visibility) -> Self {
|
||||
match value {
|
||||
Visibility::Inherited => Self::Inherited,
|
||||
Visibility::Hidden => Self::Hidden,
|
||||
Visibility::Visible => Self::Visible,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<SerVisibility> for Visibility {
|
||||
fn from(value: SerVisibility) -> Self {
|
||||
match value {
|
||||
SerVisibility::Inherited => Self::Inherited,
|
||||
SerVisibility::Hidden => Self::Hidden,
|
||||
SerVisibility::Visible => Self::Visible,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A global allocator for `TbMapEntityId` values. Should be reset when a map begins loading.
|
||||
#[derive(Resource, Reflect, Default)]
|
||||
#[reflect(Resource)]
|
||||
pub struct TbMapIdCounter(u64);
|
||||
|
||||
impl TbMapIdCounter {
|
||||
pub fn reset(&mut self) {
|
||||
self.0 = 0;
|
||||
}
|
||||
|
||||
pub fn alloc(&mut self) -> TbMapEntityId {
|
||||
let id = self.0;
|
||||
self.0 += 1;
|
||||
TbMapEntityId { id }
|
||||
}
|
||||
}
|
||||
|
||||
/// A mapping from TbMapEntityId to clientside map entity. When the serverside is spawned and the client's
|
||||
/// components migrated to it, or the clientside is despawned because the serverside is already despawned,
|
||||
/// the Id entry is removed from this mapping.
|
||||
#[derive(Resource, Reflect, Default, Deref, DerefMut)]
|
||||
#[reflect(Resource)]
|
||||
pub struct TbMapEntityMapping(pub HashMap<u64, Entity>);
|
||||
|
||||
#[derive(Component)]
|
||||
#[relationship(relationship_target = ClientOwns)]
|
||||
pub struct OwnedByClient(pub Entity);
|
||||
|
||||
#[derive(Component)]
|
||||
#[relationship_target(relationship = OwnedByClient, linked_spawn)]
|
||||
pub struct ClientOwns(Entity);
|
||||
Reference in New Issue
Block a user