diff --git a/src/physics.rs b/src/physics.rs index 4966f90..b1c79c2 100644 --- a/src/physics.rs +++ b/src/physics.rs @@ -634,7 +634,7 @@ pub struct ContactCollision{ face_id:model_physics::MinkowskiFace, convex_mesh_id:ConvexMeshId, } -#[derive(Debug,Clone,Eq,Hash,PartialEq)] +#[derive(Debug,Clone,Copy,Eq,Hash,PartialEq)] pub struct IntersectCollision{ convex_mesh_id:ConvexMeshId, } @@ -1271,25 +1271,16 @@ fn run_teleport_behaviour(wormhole:&Option,models } } -fn atomic_internal_instruction(state:&mut PhysicsState,data:&PhysicsData,ins:TimedInstruction){ - state.time=ins.time; - let should_advance_body=match ins.instruction{ - PhysicsInternalInstruction::CollisionStart(_) - |PhysicsInternalInstruction::CollisionEnd(_) - |PhysicsInternalInstruction::StrafeTick - |PhysicsInternalInstruction::ReachWalkTargetVelocity=>true, - }; - if should_advance_body{ - state.body.advance_time(state.time); - } - match ins.instruction{ - PhysicsInternalInstruction::CollisionStart(collision)=>{ - let convex_mesh_id=collision.convex_mesh_id(); - match (data.models.attr(convex_mesh_id.model_id),&collision){ - (PhysicsCollisionAttributes::Contact{contacting,general},&Collision::Contact(contact))=>{ +fn collision_start_contact( + state:&mut PhysicsState, + data:&PhysicsData, + contacting:&gameplay_attributes::ContactingAttributes, + general:&gameplay_attributes::GeneralAttributes, + contact:ContactCollision, +){ let incident_velocity=state.body.velocity; //add to touching - state.touching.insert(collision); + state.touching.insert(Collision::Contact(contact)); //clip v set_velocity(&mut state.body,&state.touching,&data.models,&data.hitbox_mesh,incident_velocity); match &contacting.contact_behaviour{ @@ -1324,7 +1315,7 @@ fn atomic_internal_instruction(state:&mut PhysicsState,data:&PhysicsData,ins:Tim } //I love making functions with 10 arguments to dodge the borrow checker if let Some(mode)=data.modes.get_mode(state.mode_state.get_mode_id()){ - 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); + run_teleport_behaviour(&general.wormhole,&data.models,mode,&state.style,&data.hitbox_mesh,&mut state.mode_state,&mut state.touching,&mut state.body,contact.convex_mesh_id); } if state.style.get_control(Controls::Jump,state.input_state.controls){ if let (Some(jump_settings),Some(walk_state))=(&state.style.jump,state.move_state.get_walk_state()){ @@ -1351,16 +1342,23 @@ fn atomic_internal_instruction(state:&mut PhysicsState,data:&PhysicsData,ins:Tim //doing enum to set the acceleration when surfing //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))=>{ +} + +fn collision_start_intersect( + state:&mut PhysicsState, + data:&PhysicsData, + intersecting:&gameplay_attributes::IntersectingAttributes, + general:&gameplay_attributes::GeneralAttributes, + intersect:IntersectCollision, +){ //I think that setting the velocity to 0 was preventing surface contacts from entering an infinite loop - state.touching.insert(collision); + state.touching.insert(Collision::Intersect(intersect)); //insta booster! if let Some(booster)=&general.booster{ state.cull_velocity(data,booster.boost(state.body.velocity)); } 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()); + let zone=mode.get_zone(intersect.convex_mesh_id.model_id.into()); match zone{ Some(gameplay_modes::Zone::Start)=>{ println!("@@@@ Starting new run!"); @@ -1375,16 +1373,18 @@ fn atomic_internal_instruction(state:&mut PhysicsState,data:&PhysicsData,ins:Tim 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); + run_teleport_behaviour(&general.wormhole,&data.models,mode,&state.style,&data.hitbox_mesh,&mut state.mode_state,&mut state.touching,&mut state.body,intersect.convex_mesh_id); } - }, - _=>panic!("invalid pair"), - } - }, - PhysicsInternalInstruction::CollisionEnd(collision)=>{ - match (data.models.attr(collision.convex_mesh_id().model_id),&collision){ - (PhysicsCollisionAttributes::Contact{contacting:_,general:_},&Collision::Contact(contact))=>{ - state.touching.remove(&collision);//remove contact before calling contact_constrain_acceleration +} + +fn collision_end_contact( + state:&mut PhysicsState, + data:&PhysicsData, + _contacting:&gameplay_attributes::ContactingAttributes, + _general:&gameplay_attributes::GeneralAttributes, + contact:ContactCollision, +){ + state.touching.remove(&Collision::Contact(contact));//remove contact before calling contact_constrain_acceleration //check ground //TODO do better //this is inner code from state.cull_velocity @@ -1395,11 +1395,17 @@ fn atomic_internal_instruction(state:&mut PhysicsState,data:&PhysicsData,ins:Tim }, None=>state.apply_enum_and_body(data), } - }, - (PhysicsCollisionAttributes::Intersect{intersecting: _,general:_},Collision::Intersect(_))=>{ - state.touching.remove(&collision); +} +fn collision_end_intersect( + state:&mut PhysicsState, + data:&PhysicsData, + _intersecting:&gameplay_attributes::IntersectingAttributes, + _general:&gameplay_attributes::GeneralAttributes, + intersect:IntersectCollision, +){ + state.touching.remove(&Collision::Intersect(intersect)); 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()); + let zone=mode.get_zone(intersect.convex_mesh_id.model_id.into()); match zone{ Some(gameplay_modes::Zone::Start)=>{ match state.run.start(state.time){ @@ -1410,7 +1416,34 @@ fn atomic_internal_instruction(state:&mut PhysicsState,data:&PhysicsData,ins:Tim _=>(), } } - }, +} +fn atomic_internal_instruction(state:&mut PhysicsState,data:&PhysicsData,ins:TimedInstruction){ + state.time=ins.time; + let should_advance_body=match ins.instruction{ + PhysicsInternalInstruction::CollisionStart(_) + |PhysicsInternalInstruction::CollisionEnd(_) + |PhysicsInternalInstruction::StrafeTick + |PhysicsInternalInstruction::ReachWalkTargetVelocity=>true, + }; + if should_advance_body{ + state.body.advance_time(state.time); + } + match ins.instruction{ + PhysicsInternalInstruction::CollisionStart(collision)=>{ + match (data.models.attr(collision.convex_mesh_id().model_id),&collision){ + (PhysicsCollisionAttributes::Contact{contacting,general},&Collision::Contact(contact))=> + collision_start_contact(state,data,contacting,general,contact), + (PhysicsCollisionAttributes::Intersect{intersecting,general},&Collision::Intersect(intersect))=> + collision_start_intersect(state,data,intersecting,general,intersect), + _=>panic!("invalid pair"), + } + }, + PhysicsInternalInstruction::CollisionEnd(collision)=>{ + match (data.models.attr(collision.convex_mesh_id().model_id),&collision){ + (PhysicsCollisionAttributes::Contact{contacting,general},&Collision::Contact(contact))=> + collision_end_contact(state,data,contacting,general,contact), + (PhysicsCollisionAttributes::Intersect{intersecting,general},&Collision::Intersect(intersect))=> + collision_end_intersect(state,data,intersecting,general,intersect), _=>panic!("invalid pair"), } },