From e47d152af2d388809c192d4d5e5fdd37187dc7f5 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Thu, 1 Aug 2024 12:57:58 -0700 Subject: [PATCH] make a distinction between restart and spawning --- src/physics.rs | 35 ++++++++++++++++++++++++++++------- src/physics_worker.rs | 12 ++++++++++-- src/window.rs | 8 ++++++-- 3 files changed, 44 insertions(+), 11 deletions(-) diff --git a/src/physics.rs b/src/physics.rs index 872efae4..7f79614e 100644 --- a/src/physics.rs +++ b/src/physics.rs @@ -42,7 +42,8 @@ pub enum PhysicsInputInstruction{ SetMoveForward(bool), SetJump(bool), SetZoom(bool), - Reset, + Restart, + Spawn(gameplay_modes::ModeId,StageId), Idle, //Idle: there were no input events, but the simulation is safe to advance to this timestep //for interpolation / networking / playback reasons, most playback heads will always want @@ -963,6 +964,11 @@ impl PhysicsState{ fn clear(&mut self){ self.touching.clear(); } + fn reset_to_default(&mut self){ + let mut new_state=Self::default(); + new_state.camera.sensitivity=self.camera.sensitivity; + *self=new_state; + } fn next_move_instruction(&self)->Option>{ self.move_state.next_move_instruction(&self.style.strafe,self.time) } @@ -1059,10 +1065,16 @@ impl PhysicsContext{ instruction:PhysicsInputInstruction::SetSensitivity(user_settings.calculate_sensitivity()), }); } + pub fn restart(&mut self){ + self.run_input_instruction(TimedInstruction{ + time:self.state.time, + instruction:PhysicsInputInstruction::Restart, + }); + } pub fn spawn(&mut self){ self.run_input_instruction(TimedInstruction{ time:self.state.time, - instruction:PhysicsInputInstruction::Reset, + instruction:PhysicsInputInstruction::Spawn(gameplay_modes::ModeId::MAIN,StageId::FIRST), }); } pub const fn output(&self)->PhysicsOutputState{ @@ -1530,7 +1542,8 @@ fn atomic_input_instruction(state:&mut PhysicsState,data:&PhysicsData,ins:TimedI //the body may as well be a quantum wave function //as far as these instruction are concerned (they don't care where it is) PhysicsInputInstruction::SetSensitivity(..) - |PhysicsInputInstruction::Reset + |PhysicsInputInstruction::Restart + |PhysicsInputInstruction::Spawn(..) |PhysicsInputInstruction::SetZoom(..) |PhysicsInputInstruction::Idle=>false, //these controls only update the body if you are on the ground @@ -1593,18 +1606,26 @@ fn atomic_input_instruction(state:&mut PhysicsState,data:&PhysicsData,ins:TimedI state.input_state.set_control(Controls::Zoom,s); b_refresh_walk_target=false; }, - PhysicsInputInstruction::Reset=>{ - //it matters which of these runs first, but I have not thought it through yet as it doesn't matter yet - state.mode_state.clear(); - state.mode_state.set_stage_id(gameplay_modes::StageId::FIRST); + PhysicsInputInstruction::Restart=>{ + //totally reset physics state + state.reset_to_default(); + //spawn at start zone let spawn_point=data.modes.get_mode(state.mode_state.get_mode_id()).map(|mode| //TODO: spawn at the bottom of the start zone plus the hitbox size + //TODO: set camera andles to face the same way as the start zone data.models.model(mode.get_start().into()).transform.vertex.translation ).unwrap_or(Planar64Vec3::ZERO); set_position(&mut state.body,&mut state.touching,spawn_point); set_velocity(&mut state.body,&state.touching,&data.models,&data.hitbox_mesh,Planar64Vec3::ZERO); state.set_move_state(data,MoveState::Air); b_refresh_walk_target=false; + } + PhysicsInputInstruction::Spawn(mode_id,stage_id)=>{ + //spawn at a particular stage + if let Some(mode)=data.modes.get_mode(mode_id){ + teleport_to_spawn(&mut state.body,&mut state.touching,&state.style,&data.hitbox_mesh,mode,&data.models,stage_id); + } + b_refresh_walk_target=false; }, PhysicsInputInstruction::PracticeFly=>{ match &state.move_state{ diff --git a/src/physics_worker.rs b/src/physics_worker.rs index 78a12508..24587ae3 100644 --- a/src/physics_worker.rs +++ b/src/physics_worker.rs @@ -12,7 +12,8 @@ pub enum InputInstruction{ MoveForward(bool), Jump(bool), Zoom(bool), - Reset, + Restart, + Spawn(strafesnet_common::gameplay_modes::ModeId,strafesnet_common::gameplay_modes::StageId), PracticeFly, } pub enum Instruction{ @@ -68,7 +69,8 @@ impl MouseInterpolator{ &InputInstruction::MoveDown(s)=>Some(PhysicsInputInstruction::SetMoveDown(s)), &InputInstruction::Jump(s)=>Some(PhysicsInputInstruction::SetJump(s)), &InputInstruction::Zoom(s)=>Some(PhysicsInputInstruction::SetZoom(s)), - InputInstruction::Reset=>Some(PhysicsInputInstruction::Reset), + &InputInstruction::Spawn(mode_id,stage_id)=>Some(PhysicsInputInstruction::Spawn(mode_id,stage_id)), + InputInstruction::Restart=>Some(PhysicsInputInstruction::Restart), InputInstruction::PracticeFly=>Some(PhysicsInputInstruction::PracticeFly), }, Instruction::GenerateModels(_)=>Some(PhysicsInputInstruction::Idle), @@ -150,6 +152,12 @@ pub fn new(mut physics:crate::physics::PhysicsContext,mut graphics_worker:crate: }, Instruction::GenerateModels(map)=>{ physics.generate_models(&map); + //important! + //bots will not work properly without this exact restart + spawn setup + //reset the physics state to start a new run on the new map + physics.restart(); + //generate a spawn event so bots work properly on the first run + //no run started so does not invalidate the run physics.spawn(); graphics_worker.send(crate::graphics_worker::Instruction::GenerateModels(map)).unwrap(); }, diff --git a/src/window.rs b/src/window.rs index 08ed1024..54ff59a1 100644 --- a/src/window.rs +++ b/src/window.rs @@ -107,7 +107,11 @@ impl WindowContext<'_>{ "e"=>Some(InputInstruction::MoveUp(s)), "q"=>Some(InputInstruction::MoveDown(s)), "z"=>Some(InputInstruction::Zoom(s)), - "r"=>if s{Some(InputInstruction::Reset)}else{None}, + "r"=>if s{ + //mouse needs to be reset since the position is absolute + self.mouse=crate::physics::MouseState::default(); + Some(InputInstruction::Restart) + }else{None}, "f"=>if s{Some(InputInstruction::PracticeFly)}else{None}, _=>None, }, @@ -233,4 +237,4 @@ impl<'a> WindowContextSetup<'a>{ } }) } -} \ No newline at end of file +}