diff --git a/src/physics.rs b/src/physics.rs index b566a3a5..e0f28aeb 100644 --- a/src/physics.rs +++ b/src/physics.rs @@ -2,6 +2,7 @@ use std::collections::{HashMap,HashSet}; use crate::model_physics::{self,PhysicsMesh,PhysicsMeshTransform,TransformedMesh,MeshQuery,PhysicsMeshId,PhysicsSubmeshId}; use strafesnet_common::bvh; use strafesnet_common::map; +use strafesnet_common::run; use strafesnet_common::aabb; use strafesnet_common::model::{MeshId,ModelId}; use strafesnet_common::gameplay_attributes::{self,CollisionAttributesId}; @@ -906,6 +907,10 @@ pub struct PhysicsState{ //gameplay_state mode_state:ModeState, move_state:MoveState, + //run is non optional: when you spawn in a run is created + //the run cannot be finished unless you start it by visiting + //a start zone. If you change mode, a new run is created. + run:run::Run, } //random collection of contextual data that doesn't belong in PhysicsState pub struct PhysicsData{ @@ -925,11 +930,12 @@ impl Default for PhysicsState{ time:Time::ZERO, style:StyleModifiers::default(), touching:TouchingState::default(), - move_state: MoveState::Air, + move_state:MoveState::Air, camera:PhysicsCamera::default(), input_state:InputState::default(), world:WorldState{}, mode_state:ModeState::default(), + run:run::Run::new(), } } } @@ -1414,10 +1420,25 @@ fn run_teleport_behaviour(wormhole:&Option,models //doing input_and_body to refresh the walk state if you hit a wall while accelerating state.apply_enum_and_input_and_body(data); }, - (PhysicsCollisionAttributes::Intersect{intersecting: _,general},Collision::Intersect(intersect))=>{ + (PhysicsCollisionAttributes::Intersect{intersecting:_,general},Collision::Intersect(_intersect))=>{ //I think that setting the velocity to 0 was preventing surface contacts from entering an infinite loop state.touching.insert(collision); if let Some(mode)=data.modes.get_mode(state.mode_state.get_mode_id()){ + let zone=mode.get_zone(convex_mesh_id.model_id.into()); + match zone{ + Some(gameplay_modes::Zone::Start)=>{ + println!("@@@@ Starting new run!"); + state.run=run::Run::new(); + }, + Some(gameplay_modes::Zone::Finish)=>{ + match state.run.finish(state.time){ + Ok(())=>println!("@@@@ Finished run time={}",state.run.time(state.time)), + Err(e)=>println!("@@@@ Run Finish error:{e:?}"), + } + }, + Some(gameplay_modes::Zone::Anticheat)=>state.run.flag(run::FlagReason::Anticheat), + None=>(), + } run_teleport_behaviour(&general.wormhole,&data.models,mode,&state.style,&data.hitbox_mesh,&mut state.mode_state,&mut state.touching,&mut state.body,convex_mesh_id); } }, @@ -1441,6 +1462,18 @@ fn run_teleport_behaviour(wormhole:&Option,models }, (PhysicsCollisionAttributes::Intersect{intersecting: _,general:_},Collision::Intersect(_))=>{ state.touching.remove(&collision); + if let Some(mode)=data.modes.get_mode(state.mode_state.get_mode_id()){ + let zone=mode.get_zone(collision.convex_mesh_id().model_id.into()); + match zone{ + Some(gameplay_modes::Zone::Start)=>{ + match state.run.start(state.time){ + Ok(())=>println!("@@@@ Started run"), + Err(e)=>println!("@@@@ Run Start error:{e:?}"), + } + }, + _=>(), + } + } }, _=>panic!("invalid pair"), }