diff --git a/kubi/src/client_physics.rs b/kubi/src/client_physics.rs new file mode 100644 index 0000000..cacbaf1 --- /dev/null +++ b/kubi/src/client_physics.rs @@ -0,0 +1,52 @@ +//TODO client-side physics +//TODO move this to shared +use glam::{Mat4, Vec3}; +use kubi_shared::transform::Transform; +use shipyard::{track, AllStoragesView, Component, IntoIter, Unique, UniqueView, View, ViewMut}; +use crate::delta_time::DeltaTime; + +#[derive(Unique)] +pub struct GlobalClPhysicsConfig { + pub gravity: Vec3, +} + +#[derive(Component)] +pub struct ClPhysicsActor { + pub forces: Vec3, + pub velocity: Vec3, + pub terminal_velocity: f32, + //TODO: this should be configurable per block + pub friction_agains_ground: f32, +} + +impl Default for ClPhysicsActor { + fn default() -> Self { + Self { + forces: Vec3::ZERO, + velocity: Vec3::ZERO, + terminal_velocity: 40., + friction_agains_ground: 0.5, + } + } +} + +pub fn init_client_physics( + storages: AllStoragesView, +) { + storages.add_unique(GlobalClPhysicsConfig { + gravity: Vec3::new(0., -9.8, 0.), + }); +} + +pub fn update_client_physics_late( + controllers: View, + mut transforms: ViewMut, + dt: UniqueView, + phy_conf: UniqueView, +) { + // for (_, mut transform) in (&controllers, &mut transforms).iter() { + // let (scale, rotation, mut translation) = transform.0.to_scale_rotation_translation(); + // translation.y -= dt.0.as_secs_f32() * 100.; + // transform.0 = Mat4::from_scale_rotation_translation(scale, rotation, translation); + // } +} diff --git a/kubi/src/cursor_lock.rs b/kubi/src/cursor_lock.rs index 05cf581..02aaf65 100644 --- a/kubi/src/cursor_lock.rs +++ b/kubi/src/cursor_lock.rs @@ -1,36 +1,36 @@ -use shipyard::{AllStoragesView, Unique, NonSendSync, UniqueView, UniqueViewMut}; -use crate::rendering::Renderer; -use winit::window::CursorGrabMode; - -#[derive(Unique)] -pub struct CursorLock(pub bool); - -pub fn update_cursor_lock_state( - lock: UniqueView, - display: NonSendSync> -) { - if cfg!(target_os = "android") { - return - } - if lock.is_inserted_or_modified() { - //TODO MIGRATION - let window = &display.window; - window.set_cursor_grab(match lock.0 { - true => CursorGrabMode::Confined, - false => CursorGrabMode::None, - }).expect("Failed to change cursor grab state"); - window.set_cursor_visible(!lock.0); - } -} - -pub fn insert_lock_state( - storages: AllStoragesView -) { - storages.add_unique(CursorLock(false)) -} - -pub fn lock_cursor_now( - mut lock: UniqueViewMut -) { - lock.0 = true -} +use shipyard::{AllStoragesView, Unique, NonSendSync, UniqueView, UniqueViewMut}; +use crate::rendering::Renderer; +use winit::window::CursorGrabMode; + +#[derive(Unique)] +pub struct CursorLock(pub bool); + +pub fn update_cursor_lock_state( + lock: UniqueView, + display: NonSendSync> +) { + if cfg!(target_os = "android") { + return + } + if lock.is_inserted_or_modified() { + //TODO MIGRATION + let window = &display.window; + window.set_cursor_grab(match lock.0 { + true => CursorGrabMode::Confined, + false => CursorGrabMode::None, + }).expect("Failed to change cursor grab state"); + window.set_cursor_visible(!lock.0); + } +} + +pub fn insert_lock_state( + storages: AllStoragesView +) { + storages.add_unique(CursorLock(false)) +} + +pub fn lock_cursor_now( + mut lock: UniqueViewMut +) { + lock.0 = true +} diff --git a/kubi/src/lib.rs b/kubi/src/lib.rs index eb0c821..0371b3e 100644 --- a/kubi/src/lib.rs +++ b/kubi/src/lib.rs @@ -37,6 +37,7 @@ pub(crate) mod loading_screen; pub(crate) mod connecting_screen; pub(crate) mod fixed_timestamp; pub(crate) mod filesystem; +pub(crate) mod client_physics; use world::{ init_game_world, @@ -81,6 +82,7 @@ use loading_screen::update_loading_screen; use connecting_screen::switch_to_loading_if_connected; use fixed_timestamp::init_fixed_timestamp_storage; use filesystem::AssetManager; +use client_physics::{init_client_physics, update_client_physics_late}; /// stuff required to init the renderer and other basic systems fn pre_startup() -> Workload { @@ -104,6 +106,7 @@ fn startup() -> Workload { init_input, insert_control_flow_unique, init_delta_time, + init_client_physics, ).into_sequential_workload() } @@ -131,6 +134,7 @@ fn update() -> Workload { ).into_sequential_workload().run_if(is_ingame_or_loading), ( update_controllers, + update_client_physics_late, generate_move_events, update_raycasts, update_block_placement, diff --git a/kubi/src/player.rs b/kubi/src/player.rs index f6aaaea..b500e53 100644 --- a/kubi/src/player.rs +++ b/kubi/src/player.rs @@ -1,87 +1,89 @@ -use glam::Mat4; -use shipyard::{Component, AllStoragesViewMut, UniqueViewMut}; -use kubi_shared::{ - entity::{Entity, Health}, - player::{Player, PLAYER_HEALTH, PlayerHolding}, - block::Block, - networking::{ - client::{Username, Client, ClientIdMap}, - messages::ClientInitData - } -}; -use crate::{ - transform::Transform, - camera::Camera, - fly_controller::FlyController, - world::raycast::LookingAtBlock, -}; - -#[derive(Component)] -pub struct MainPlayer; - -pub fn spawn_player ( - mut storages: AllStoragesViewMut, -) { - log::info!("spawning player"); - storages.add_entity(( - Player, - MainPlayer, - Entity, - Health::new(PLAYER_HEALTH), - Transform::default(), - Camera::default(), - FlyController, - LookingAtBlock::default(), - PlayerHolding(Some(Block::Cobblestone)), - Username("LocalPlayer".into()) - )); -} - -pub fn spawn_local_player_multiplayer ( - storages: &mut AllStoragesViewMut, - init: ClientInitData -) { - log::info!("spawning local multiplayer player"); - let entity_id = storages.add_entity(( - ( - Player, - Client(init.client_id), - MainPlayer, - Entity, - init.health, - Transform(Mat4::from_rotation_translation(init.direction, init.position)), - Camera::default(), - FlyController, - LookingAtBlock::default(), - PlayerHolding::default(), - ),( - Username(init.username) - ) - )); - - //Add ourself to the client id map - let mut client_id_map = storages.borrow::>().unwrap(); - client_id_map.0.insert(init.client_id, entity_id); -} - -pub fn spawn_remote_player_multiplayer( - storages: &mut AllStoragesViewMut, - init: ClientInitData -) { - log::info!("spawning remote multiplayer player"); - - //Spawn player locally - let entity_id = storages.add_entity(( - Username(init.username), - Client(init.client_id), - Player, - Entity, - init.health, - Transform(Mat4::from_rotation_translation(init.direction, init.position)), - PlayerHolding::default(), - )); - - //Add it to the client id map - let mut client_id_map = storages.borrow::>().unwrap(); - client_id_map.0.insert(init.client_id, entity_id); -} +use glam::Mat4; +use shipyard::{Component, AllStoragesViewMut, UniqueViewMut}; +use kubi_shared::{ + entity::{Entity, Health}, + player::{Player, PLAYER_HEALTH, PlayerHolding}, + block::Block, + networking::{ + client::{Username, Client, ClientIdMap}, + messages::ClientInitData + } +}; +use crate::{ + camera::Camera, + client_physics::ClPhysicsActor, + fly_controller::FlyController, + transform::Transform, + world::raycast::LookingAtBlock +}; + +#[derive(Component)] +pub struct MainPlayer; + +pub fn spawn_player ( + mut storages: AllStoragesViewMut, +) { + log::info!("spawning player"); + storages.add_entity((( + Player, + MainPlayer, + Entity, + Health::new(PLAYER_HEALTH), + Transform::default(), + Camera::default(), + FlyController, + LookingAtBlock::default(), + PlayerHolding(Some(Block::Cobblestone)), + Username("LocalPlayer".into()), + ),( + ClPhysicsActor::default(), + ))); +} + +pub fn spawn_local_player_multiplayer ( + storages: &mut AllStoragesViewMut, + init: ClientInitData +) { + log::info!("spawning local multiplayer player"); + let entity_id = storages.add_entity((( + Player, + Client(init.client_id), + MainPlayer, + Entity, + init.health, + Transform(Mat4::from_rotation_translation(init.direction, init.position)), + Camera::default(), + FlyController, + LookingAtBlock::default(), + PlayerHolding::default(), + ),( + Username(init.username), + ClPhysicsActor::default(), + ))); + + //Add ourself to the client id map + let mut client_id_map = storages.borrow::>().unwrap(); + client_id_map.0.insert(init.client_id, entity_id); +} + +pub fn spawn_remote_player_multiplayer( + storages: &mut AllStoragesViewMut, + init: ClientInitData +) { + log::info!("spawning remote multiplayer player"); + + //Spawn player locally + let entity_id = storages.add_entity(( + Username(init.username), + Client(init.client_id), + Player, + Entity, + init.health, + Transform(Mat4::from_rotation_translation(init.direction, init.position)), + PlayerHolding::default(), + )); + + //Add it to the client id map + let mut client_id_map = storages.borrow::>().unwrap(); + client_id_map.0.insert(init.client_id, entity_id); +}