use async_std::channel::Sender; use async_std::sync::RwLock; use rapier2d_f64::na::Vector2; use rapier2d_f64::prelude::{ BroadPhase, CCDSolver, ColliderSet, ImpulseJointSet, IntegrationParameters, IslandManager, MultibodyJointSet, NarrowPhase, PhysicsPipeline, RigidBodyHandle, RigidBodySet, }; use starkingdoms_protocol::api::APISavedPlayerData; use std::collections::HashMap; use std::net::SocketAddr; use std::sync::Arc; use crate::entity::{Entity, EntityHandler, EntityId}; use crate::module::{AttachedModule, Attachment}; #[derive(Clone)] pub struct ClientManager { pub handlers: Arc>>, pub usernames: Arc>>, } #[derive(Clone, Debug)] pub struct Player { pub handle: RigidBodyHandle, pub input: PlayerInput, pub addr: SocketAddr, pub auth_token: Option, pub auth_user: Option, pub children: [Option; 4], } impl Player { #[allow(clippy::missing_const_for_fn)] // This will eventually do something, but for now it doesn't pub fn as_api_data(&self) -> APISavedPlayerData { APISavedPlayerData {} } pub fn load_api_data(&mut self, _data: &APISavedPlayerData) {} pub fn search_modules(&self, entities: &EntityHandler) -> Vec { let mut modules = Vec::new(); for attachment in self.children.iter().flatten() { if let Some(Entity::AttachedModule(child_module)) = entities.entities.get(&attachment.child) { modules.append(&mut child_module.search_modules(entities)); } } modules } pub fn find_parent( &self, module: &AttachedModule, entities: &EntityHandler, ) -> Option<(u8, EntityId)> { for (slot, attachment) in self.children.iter().enumerate() { if let Some(attachment) = attachment { if let Entity::AttachedModule(child_module) = entities.entities.get(&attachment.child)? { if *child_module == *module { return Some(( u8::try_from(slot).ok()?, entities.get_player_id(self.addr)?, )); } let parent = child_module.find_parent(module, entities); if parent.is_some() { return parent; } } } } None } } #[derive(Default, Clone, Debug)] #[allow(clippy::struct_excessive_bools)] pub struct PlayerInput { pub up: bool, pub left: bool, pub right: bool, pub down: bool, } #[derive(Clone)] pub struct ClientHandler { pub tx: Sender, } #[derive(Clone, Default)] pub struct PhysicsData { pub gravity: Vector2, pub integration_parameters: IntegrationParameters, pub island_manager: IslandManager, pub broad_phase: BroadPhase, pub narrow_phase: NarrowPhase, pub rigid_body_set: RigidBodySet, pub collider_set: ColliderSet, pub impulse_joint_set: ImpulseJointSet, pub multibody_joint_set: MultibodyJointSet, pub ccd_solver: CCDSolver, } impl PhysicsData { pub fn tick(&mut self, pipeline: &mut PhysicsPipeline) { pipeline.step( &self.gravity, &self.integration_parameters, &mut self.island_manager, &mut self.broad_phase, &mut self.narrow_phase, &mut self.rigid_body_set, &mut self.collider_set, &mut self.impulse_joint_set, &mut self.multibody_joint_set, &mut self.ccd_solver, None, &(), &(), ); } } #[derive(Debug, Clone)] pub enum ClientHandlerMessage { Tick, ChatMessage { from: String, message: String, }, PlayersUpdate { players: Vec, }, PlanetData { planets: Vec, }, ModulesUpdate { modules: Vec, }, ModuleTreeUpdate { modules: Vec, }, }