use async_std::channel::Sender;
use async_std::sync::RwLock;
use log::debug;
use nalgebra::{point, vector};
use rapier2d_f64::na::Vector2;
use rapier2d_f64::prelude::{
BroadPhase, CCDSolver, ColliderBuilder, ColliderSet, FixedJointBuilder, ImpulseJointHandle,
ImpulseJointSet, IntegrationParameters, IslandManager, Isometry, MassProperties,
MultibodyJointSet, NarrowPhase, PhysicsPipeline, Real, RigidBodyBuilder, RigidBodyHandle,
RigidBodySet,
};
use starkingdoms_protocol::api::APISavedPlayerData;
use starkingdoms_protocol::module::ModuleType;
use std::collections::HashMap;
use std::f64::consts::PI;
use std::net::SocketAddr;
use std::sync::Arc;
use crate::entity::{get_entity_id, Entity, EntityHandler, EntityId};
use crate::SCALE;
use crate::module::{Attachment, AttachedModule};
#[derive(Clone)]
pub struct ClientManager {
pub handlers: Arc<RwLock<HashMap<SocketAddr, ClientHandler>>>,
pub usernames: Arc<RwLock<HashMap<SocketAddr, String>>>,
}
#[derive(Clone, Debug)]
pub struct Player {
pub handle: RigidBodyHandle,
pub input: PlayerInput,
pub addr: SocketAddr,
pub auth_token: Option<String>,
pub auth_user: Option<String>,
pub children: [Option<Attachment>; 4],
}
impl Player {
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<AttachedModule> {
let mut modules = Vec::new();
for attachment in self.children.iter().flatten() {
if let Entity::AttachedModule(child_module) =
entities.entities.get(&attachment.child).unwrap()
{
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).unwrap()
{
debug!("player child: {:?}", *child_module);
debug!("player target: {:?}", module);
if *child_module == module {
return Some((slot as u8, entities.get_player_id(self.addr).unwrap()));
}
let parent = child_module.find_parent(module.clone(), entities);
if let Some(_) = parent {
return parent;
}
}
}
}
None
}
}
#[derive(Default, Clone, Debug)]
pub struct PlayerInput {
pub up: bool,
pub left: bool,
pub right: bool,
pub down: bool,
}
#[derive(Clone)]
pub struct ClientHandler {
pub tx: Sender<ClientHandlerMessage>,
}
#[derive(Clone, Default)]
pub struct PhysicsData {
pub gravity: Vector2<f64>,
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<starkingdoms_protocol::player::Player>,
},
PlanetData {
planets: Vec<starkingdoms_protocol::planet::Planet>,
},
ModulesUpdate {
modules: Vec<starkingdoms_protocol::module::Module>,
},
ModuleTreeUpdate {
modules: Vec<starkingdoms_protocol::module::AttachedModule>,
},
}