diff --git a/src/main.rs b/src/main.rs index 3f4300b..de83db1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,5 @@ -use strafesnet_common::integer; +use strafesnet_common::{model,integer}; -mod model; mod setup; mod window; mod worker; diff --git a/src/model.rs b/src/model.rs deleted file mode 100644 index ddfc3d9..0000000 --- a/src/model.rs +++ /dev/null @@ -1,321 +0,0 @@ -use strafesnet_common::integer::{Time,Planar64,Planar64Vec3,Planar64Affine3}; -pub type TextureCoordinate=glam::Vec2; -pub type Color4=glam::Vec4; -#[derive(Clone,Hash,PartialEq,Eq)] -pub struct IndexedVertex{ - pub pos:u32, - pub tex:u32, - pub normal:u32, - pub color:u32, -} -pub struct IndexedPolygon{ - pub vertices:Vec, -} -pub struct IndexedGroup{ - pub texture:Option,//RenderPattern? material/texture/shader/flat color - pub polys:Vec, -} -pub struct IndexedModel{ - pub unique_pos:Vec, - pub unique_normal:Vec, - pub unique_tex:Vec, - pub unique_color:Vec, - pub unique_vertices:Vec, - pub groups: Vec, - pub instances:Vec, -} -pub struct ModelInstance{ - //pub id:u64,//this does not actually help with map fixes resimulating bots, they must always be resimulated - pub transform:Planar64Affine3, - pub color:Color4,//transparency is in here - pub attributes:CollisionAttributes, - pub temp_indexing:Vec, -} -impl std::default::Default for ModelInstance{ - fn default() -> Self { - Self{ - color:Color4::ONE, - transform:Default::default(), - attributes:Default::default(), - temp_indexing:Default::default(), - } - } -} -pub struct IndexedModelInstances{ - pub textures:Vec,//RenderPattern - pub models:Vec, - //may make this into an object later. - pub modes:Vec, - pub spawn_point:Planar64Vec3, -} -//stage description referencing flattened ids is spooky, but the map loading is meant to be deterministic. -pub struct ModeDescription{ - //TODO: put "default" style modifiers in mode - //pub style:StyleModifiers, - pub start:usize,//start=model_id - pub spawns:Vec,//spawns[spawn_id]=model_id - pub spawn_from_stage_id:std::collections::HashMap::, - pub ordered_checkpoint_from_checkpoint_id:std::collections::HashMap::, -} -impl ModeDescription{ - pub fn get_spawn_model_id(&self,stage_id:u32)->Option<&usize>{ - self.spawns.get(*self.spawn_from_stage_id.get(&stage_id)?) - } -} -//I don't want this code to exist! -#[derive(Clone)] -pub struct TempAttrStart{ - pub mode_id:u32, -} -#[derive(Clone)] -pub struct TempAttrSpawn{ - pub mode_id:u32, - pub stage_id:u32, -} -#[derive(Clone)] -pub struct TempAttrWormhole{ - pub wormhole_id:u32, -} -pub enum TempIndexedAttributes{ - Start(TempAttrStart), - Spawn(TempAttrSpawn), - Wormhole(TempAttrWormhole), -} - -//you have this effect while in contact -#[derive(Clone,Hash,Eq,PartialEq)] -pub struct ContactingLadder{ - pub sticky:bool -} -#[derive(Clone,Hash,Eq,PartialEq)] -pub enum ContactingBehaviour{ - Surf, - Cling,//usable as a zipline, or other weird and wonderful things - Ladder(ContactingLadder), - Elastic(u32),//[1/2^32,1] 0=None (elasticity+1)/2^32 -} -//you have this effect while intersecting -#[derive(Clone,Hash,Eq,PartialEq)] -pub struct IntersectingWater{ - pub viscosity:Planar64, - pub density:Planar64, - pub velocity:Planar64Vec3, -} -//All models can be given these attributes -#[derive(Clone,Hash,Eq,PartialEq)] -pub struct GameMechanicAccelerator{ - pub acceleration:Planar64Vec3 -} -#[derive(Clone,Hash,Eq,PartialEq)] -pub enum GameMechanicBooster{ - Affine(Planar64Affine3),//capable of SetVelocity,DotVelocity,normal booster,bouncy part,redirect velocity, and much more - Velocity(Planar64Vec3),//straight up boost velocity adds to your current velocity - Energy{direction:Planar64Vec3,energy:Planar64},//increase energy in direction -} -#[derive(Clone,Hash,Eq,PartialEq)] -pub enum TrajectoryChoice{ - HighArcLongDuration,//underhand lob at target: less horizontal speed and more air time - LowArcShortDuration,//overhand throw at target: more horizontal speed and less air time -} -#[derive(Clone,Hash,Eq,PartialEq)] -pub enum GameMechanicSetTrajectory{ - //Speed-type SetTrajectory - AirTime(Time),//air time (relative to gravity direction) is invariant across mass and gravity changes - Height(Planar64),//boost height (relative to gravity direction) is invariant across mass and gravity changes - DotVelocity{direction:Planar64Vec3,dot:Planar64},//set your velocity in a specific direction without touching other directions - //Velocity-type SetTrajectory - TargetPointTime{//launch on a trajectory that will land at a target point in a set amount of time - target_point:Planar64Vec3, - time:Time,//short time = fast and direct, long time = launch high in the air, negative time = wrong way - }, - TargetPointSpeed{//launch at a fixed speed and land at a target point - target_point:Planar64Vec3, - speed:Planar64,//if speed is too low this will fail to reach the target. The closest-passing trajectory will be chosen instead - trajectory_choice:TrajectoryChoice, - }, - Velocity(Planar64Vec3),//SetVelocity -} -impl GameMechanicSetTrajectory{ - fn is_velocity(&self)->bool{ - match self{ - GameMechanicSetTrajectory::AirTime(_) - |GameMechanicSetTrajectory::Height(_) - |GameMechanicSetTrajectory::DotVelocity{direction:_,dot:_}=>false, - GameMechanicSetTrajectory::TargetPointTime{target_point:_,time:_} - |GameMechanicSetTrajectory::TargetPointSpeed{target_point:_,speed:_,trajectory_choice:_} - |GameMechanicSetTrajectory::Velocity(_)=>true, - } - } -} -#[derive(Clone,Hash,Eq,PartialEq)] -pub enum ZoneBehaviour{ - //Start is indexed - //Checkpoints are indexed - Finish, - Anitcheat, -} -#[derive(Clone,Hash,Eq,PartialEq)] -pub struct GameMechanicZone{ - pub mode_id:u32, - pub behaviour:ZoneBehaviour, -} -// enum TrapCondition{ -// FasterThan(Planar64), -// SlowerThan(Planar64), -// InRange(Planar64,Planar64), -// OutsideRange(Planar64,Planar64), -// } -#[derive(Clone,Hash,Eq,PartialEq)] -pub enum StageElementBehaviour{ - //Spawn,//The behaviour of stepping on a spawn setting the spawnid - SpawnAt,//must be standing on top to get effect. except cancollide false - Trigger, - Teleport, - Platform, - //Checkpoint acts like a trigger if you haven't hit all the checkpoints yet. - //Note that all stage elements act like this for the next stage. - Checkpoint, - //OrderedCheckpoint. You must pass through all of these in ascending order. - //If you hit them out of order it acts like a trigger. - //Do not support backtracking at all for now. - Ordered{ - checkpoint_id:u32, - }, - //UnorderedCheckpoint. You must pass through all of these in any order. - Unordered, - //If you get reset by a jump limit - JumpLimit(u32), - //Speedtrap(TrapCondition),//Acts as a trigger with a speed condition -} -#[derive(Clone,Hash,Eq,PartialEq)] -pub struct GameMechanicStageElement{ - pub mode_id:u32, - pub stage_id:u32,//which spawn to send to - pub force:bool,//allow setting to lower spawn id i.e. 7->3 - pub behaviour:StageElementBehaviour -} -#[derive(Clone,Hash,Eq,PartialEq)] -pub struct GameMechanicWormhole{ - //destination does not need to be another wormhole - //this defines a one way portal to a destination model transform - //two of these can create a two way wormhole - pub destination_model_id:u32, - //(position,angles)*=origin.transform.inverse()*destination.transform -} -#[derive(Clone,Hash,Eq,PartialEq)] -pub enum TeleportBehaviour{ - StageElement(GameMechanicStageElement), - Wormhole(GameMechanicWormhole), -} -//attributes listed in order of handling -#[derive(Default,Clone,Hash,Eq,PartialEq)] -pub struct GameMechanicAttributes{ - pub zone:Option, - pub booster:Option, - pub trajectory:Option, - pub teleport_behaviour:Option, - pub accelerator:Option, -} -impl GameMechanicAttributes{ - pub fn any(&self)->bool{ - self.zone.is_some() - ||self.booster.is_some() - ||self.trajectory.is_some() - ||self.teleport_behaviour.is_some() - ||self.accelerator.is_some() - } - pub fn is_wrcp(&self,current_mode_id:u32)->bool{ - self.trajectory.as_ref().map_or(false,|t|t.is_velocity()) - &&match &self.teleport_behaviour{ - Some(TeleportBehaviour::StageElement( - GameMechanicStageElement{ - mode_id, - stage_id:_, - force:true, - behaviour:StageElementBehaviour::Trigger|StageElementBehaviour::Teleport - } - ))=>current_mode_id==*mode_id, - _=>false, - } - } -} -#[derive(Default,Clone,Hash,Eq,PartialEq)] -pub struct ContactingAttributes{ - //friction? - pub contact_behaviour:Option, -} -impl ContactingAttributes{ - pub fn any(&self)->bool{ - self.contact_behaviour.is_some() - } -} -#[derive(Default,Clone,Hash,Eq,PartialEq)] -pub struct IntersectingAttributes{ - pub water:Option, -} -impl IntersectingAttributes{ - pub fn any(&self)->bool{ - self.water.is_some() - } -} -//Spawn(u32) NO! spawns are indexed in the map header instead of marked with attibutes -pub enum CollisionAttributes{ - Decoration,//visual only - Contact{//track whether you are contacting the object - contacting:ContactingAttributes, - general:GameMechanicAttributes, - }, - Intersect{//track whether you are intersecting the object - intersecting:IntersectingAttributes, - general:GameMechanicAttributes, - }, -} -impl std::default::Default for CollisionAttributes{ - fn default() -> Self { - Self::Contact{ - contacting:ContactingAttributes::default(), - general:GameMechanicAttributes::default() - } - } -} - -pub fn generate_indexed_model_list_from_obj(data:obj::ObjData,color:Color4)->Vec{ - let mut unique_vertex_index = std::collections::HashMap::::new(); - return data.objects.iter().map(|object|{ - unique_vertex_index.clear(); - let mut unique_vertices = Vec::new(); - let groups = object.groups.iter().map(|group|{ - IndexedGroup{ - texture:None, - polys:group.polys.iter().map(|poly|{ - IndexedPolygon{ - vertices:poly.0.iter().map(|&tup|{ - if let Some(&i)=unique_vertex_index.get(&tup){ - i - }else{ - let i=unique_vertices.len() as u32; - unique_vertices.push(IndexedVertex{ - pos: tup.0 as u32, - tex: tup.1.unwrap() as u32, - normal: tup.2.unwrap() as u32, - color: 0, - }); - unique_vertex_index.insert(tup,i); - i - } - }).collect() - } - }).collect() - } - }).collect(); - IndexedModel{ - unique_pos: data.position.iter().map(|&v|Planar64Vec3::try_from(v).unwrap()).collect(), - unique_tex: data.texture.iter().map(|&v|TextureCoordinate::from_array(v)).collect(), - unique_normal: data.normal.iter().map(|&v|Planar64Vec3::try_from(v).unwrap()).collect(), - unique_color: vec![color], - unique_vertices, - groups, - instances:Vec::new(), - } - }).collect() -} diff --git a/src/physics.rs b/src/physics.rs index cccb4f3..0f769ba 100644 --- a/src/physics.rs +++ b/src/physics.rs @@ -1,8 +1,9 @@ use crate::model_physics::{PhysicsMesh,TransformedMesh,MeshQuery}; use strafesnet_common::bvh; use strafesnet_common::aabb; +use strafesnet_common::game_mechanics::{self,StyleModifiers}; use strafesnet_common::instruction::{self,InstructionEmitter,InstructionConsumer,TimedInstruction}; -use strafesnet_common::integer::{self,Time,Planar64,Planar64Vec3,Planar64Mat3,Angle32,Ratio64,Ratio64Vec2}; +use strafesnet_common::integer::{self,Time,Planar64,Planar64Vec3,Planar64Mat3,Angle32,Ratio64Vec2}; #[derive(Debug)] pub enum PhysicsInstruction { @@ -143,33 +144,6 @@ impl WalkState{ } } -struct Modes{ - modes:Vec, - mode_from_mode_id:std::collections::HashMap::, -} -impl Modes{ - fn clear(&mut self){ - self.modes.clear(); - self.mode_from_mode_id.clear(); - } - fn get_mode(&self,mode_id:u32)->Option<&crate::model::ModeDescription>{ - self.modes.get(*self.mode_from_mode_id.get(&mode_id)?) - } - fn insert(&mut self,temp_map_mode_id:u32,mode:crate::model::ModeDescription){ - let mode_id=self.modes.len(); - self.mode_from_mode_id.insert(temp_map_mode_id,mode_id); - self.modes.push(mode); - } -} -impl Default for Modes{ - fn default() -> Self { - Self{ - modes:Vec::new(), - mode_from_mode_id:std::collections::HashMap::new(), - } - } -} - #[derive(Default)] struct PhysicsModels{ meshes:Vec, @@ -188,15 +162,6 @@ impl PhysicsModels{ self.attributes.clear(); self.model_id_from_wormhole_id.clear(); } - fn aabb_list(&self)->Vec{ - self.models.iter().map(|model|{ - let mut aabb=aabb::Aabb::default(); - for pos in self.meshes[model.mesh_id].verts(){ - aabb.grow(model.transform.transform_point3(pos)); - } - aabb - }).collect() - } //TODO: "statically" verify the maps don't refer to any nonexistant data, if they do delete the references. //then I can make these getter functions unchecked. fn mesh(&self,model_id:usize)->TransformedMesh{ @@ -311,298 +276,33 @@ impl std::default::Default for GameMechanicsState{ struct WorldState{} -enum JumpCalculation{ - Capped,//roblox - Energy,//new - Linear,//source +trait HitboxMeshPresets{ + fn roblox()->Self; + fn source()->Self; } - -enum JumpImpulse{ - FromTime(Time),//jump time is invariant across mass and gravity changes - FromHeight(Planar64),//jump height is invariant across mass and gravity changes - FromDeltaV(Planar64),//jump velocity is invariant across mass and gravity changes - FromEnergy(Planar64),// :) -} -//Jumping acts on dot(walks_state.normal,body.velocity) -//Capped means it increases the dot to the cap -//Energy means it adds energy -//Linear means it linearly adds on - -enum EnableStrafe{ - Always, - MaskAny(u32),//hsw, shsw - MaskAll(u32), - //Function(Boxbool>), -} - -struct StrafeSettings{ - enable:EnableStrafe, - air_accel_limit:Option, - tick_rate:Ratio64, -} - -struct Hitbox{ - halfsize:Planar64Vec3, - mesh:PhysicsMesh, - transform:integer::Planar64Affine3, - normal_transform:Planar64Mat3, - transform_det:Planar64, -} -impl Hitbox{ - fn new(mesh:PhysicsMesh,transform:integer::Planar64Affine3)->Self{ - //calculate extents - let mut aabb=aabb::Aabb::default(); - for vert in mesh.verts(){ - aabb.grow(transform.transform_point3(vert)); - } - Self{ - halfsize:aabb.size()/2, - mesh, - transform, - normal_transform:transform.matrix3.inverse_times_det().transpose(), - transform_det:transform.matrix3.determinant(), - } - } - fn from_mesh_scale(mesh:PhysicsMesh,scale:Planar64Vec3)->Self{ - let matrix3=Planar64Mat3::from_diagonal(scale); - Self{ - halfsize:scale, - mesh, - normal_transform:matrix3.inverse_times_det().transpose(), - transform:integer::Planar64Affine3::new(matrix3,Planar64Vec3::ZERO), - transform_det:matrix3.determinant(),//scale.x*scale.y*scale.z but whatever - } - } - fn from_mesh_scale_offset(mesh:PhysicsMesh,scale:Planar64Vec3,offset:Planar64Vec3)->Self{ - let matrix3=Planar64Mat3::from_diagonal(scale); - Self{ - halfsize:scale, - mesh, - normal_transform:matrix3.inverse_times_det().transpose(), - transform:integer::Planar64Affine3::new(matrix3,offset), - transform_det:matrix3.determinant(), - } - } +impl HitboxMeshPresets for game_mechanics::Hitbox{ fn roblox()->Self{ Self::from_mesh_scale(PhysicsMesh::from(&crate::primitives::unit_cylinder()),Planar64Vec3::int(2,5,2)/2) } fn source()->Self{ Self::from_mesh_scale(PhysicsMesh::from(&crate::primitives::unit_cube()),Planar64Vec3::raw(33<<28,73<<28,33<<28)/2) } - #[inline] - fn transformed_mesh(&self)->TransformedMesh{ - TransformedMesh::new(&self.mesh,&self.transform,&self.normal_transform,self.transform_det) - } } -struct StyleModifiers{ - controls_used:u32,//controls which are allowed to pass into gameplay - controls_mask:u32,//controls which are masked from control state (e.g. jump in scroll style) - strafe:Option, - jump_impulse:JumpImpulse, - jump_calculation:JumpCalculation, - static_friction:Planar64, - kinetic_friction:Planar64, - walk_speed:Planar64, - walk_accel:Planar64, - ladder_speed:Planar64, - ladder_accel:Planar64, - ladder_dot:Planar64, - swim_speed:Planar64, - mass:Planar64, - mv:Planar64, - surf_slope:Option, - rocket_force:Option, - gravity:Planar64Vec3, - hitbox:Hitbox, - camera_offset:Planar64Vec3, +trait StyleHelper{ + fn get_control(&self,control:u32,controls:u32)->bool; + fn allow_strafe(&self,controls:u32)->bool; + fn get_control_dir(&self,controls:u32)->Planar64Vec3; + //fn get_jump_time(&self)->Planar64; + //fn get_jump_height(&self)->Planar64; + //fn get_jump_energy(&self)->Planar64; + fn get_jump_deltav(&self)->Planar64; + fn get_walk_target_velocity(&self,camera:&PhysicsCamera,controls:u32,next_mouse:&MouseState,time:Time,normal:&Planar64Vec3)->Planar64Vec3; + fn get_ladder_target_velocity(&self,camera:&PhysicsCamera,controls:u32,next_mouse:&MouseState,time:Time,normal:&Planar64Vec3)->Planar64Vec3; + fn get_propulsion_control_dir(&self,camera:&PhysicsCamera,controls:u32,next_mouse:&MouseState,time:Time)->Planar64Vec3; + fn mesh(&self)->TransformedMesh; } -impl std::default::Default for StyleModifiers{ - fn default()->Self{ - Self::roblox_bhop() - } -} -impl StyleModifiers{ - const CONTROL_MOVEFORWARD:u32=0b00000001; - const CONTROL_MOVEBACK:u32=0b00000010; - const CONTROL_MOVERIGHT:u32=0b00000100; - const CONTROL_MOVELEFT:u32=0b00001000; - const CONTROL_MOVEUP:u32=0b00010000; - const CONTROL_MOVEDOWN:u32=0b00100000; - const CONTROL_JUMP:u32=0b01000000; - const CONTROL_ZOOM:u32=0b10000000; - - const RIGHT_DIR:Planar64Vec3=Planar64Vec3::X; - const UP_DIR:Planar64Vec3=Planar64Vec3::Y; - const FORWARD_DIR:Planar64Vec3=Planar64Vec3::NEG_Z; - - fn neo()->Self{ - Self{ - controls_used:!0, - controls_mask:!0,//&!(Self::CONTROL_MOVEUP|Self::CONTROL_MOVEDOWN), - strafe:Some(StrafeSettings{ - enable:EnableStrafe::Always, - air_accel_limit:None, - tick_rate:Ratio64::new(64,Time::ONE_SECOND.nanos() as u64).unwrap(), - }), - jump_impulse:JumpImpulse::FromEnergy(Planar64::int(512)), - jump_calculation:JumpCalculation::Energy, - gravity:Planar64Vec3::int(0,-80,0), - static_friction:Planar64::int(2), - kinetic_friction:Planar64::int(3),//unrealistic: kinetic friction is typically lower than static - mass:Planar64::int(1), - mv:Planar64::int(3), - rocket_force:None, - walk_speed:Planar64::int(16), - walk_accel:Planar64::int(80), - ladder_speed:Planar64::int(16), - ladder_accel:Planar64::int(160), - ladder_dot:(Planar64::int(1)/2).sqrt(), - swim_speed:Planar64::int(12), - surf_slope:Some(Planar64::raw(7)/8), - hitbox:Hitbox::roblox(), - camera_offset:Planar64Vec3::int(0,2,0),//4.5-2.5=2 - } - } - - fn roblox_bhop()->Self{ - Self{ - controls_used:!0, - controls_mask:!0,//&!(Self::CONTROL_MOVEUP|Self::CONTROL_MOVEDOWN), - strafe:Some(StrafeSettings{ - enable:EnableStrafe::Always, - air_accel_limit:None, - tick_rate:Ratio64::new(100,Time::ONE_SECOND.nanos() as u64).unwrap(), - }), - jump_impulse:JumpImpulse::FromTime(Time::from_micros(715_588)), - jump_calculation:JumpCalculation::Capped, - gravity:Planar64Vec3::int(0,-100,0), - static_friction:Planar64::int(2), - kinetic_friction:Planar64::int(3),//unrealistic: kinetic friction is typically lower than static - mass:Planar64::int(1), - mv:Planar64::int(27)/10, - rocket_force:None, - walk_speed:Planar64::int(18), - walk_accel:Planar64::int(90), - ladder_speed:Planar64::int(18), - ladder_accel:Planar64::int(180), - ladder_dot:(Planar64::int(1)/2).sqrt(), - swim_speed:Planar64::int(12), - surf_slope:Some(Planar64::raw(3787805118)),// normal.y=0.75 - hitbox:Hitbox::roblox(), - camera_offset:Planar64Vec3::int(0,2,0),//4.5-2.5=2 - } - } - fn roblox_surf()->Self{ - Self{ - controls_used:!0, - controls_mask:!0,//&!(Self::CONTROL_MOVEUP|Self::CONTROL_MOVEDOWN), - strafe:Some(StrafeSettings{ - enable:EnableStrafe::Always, - air_accel_limit:None, - tick_rate:Ratio64::new(100,Time::ONE_SECOND.nanos() as u64).unwrap(), - }), - jump_impulse:JumpImpulse::FromTime(Time::from_micros(715_588)), - jump_calculation:JumpCalculation::Capped, - gravity:Planar64Vec3::int(0,-50,0), - static_friction:Planar64::int(2), - kinetic_friction:Planar64::int(3),//unrealistic: kinetic friction is typically lower than static - mass:Planar64::int(1), - mv:Planar64::int(27)/10, - rocket_force:None, - walk_speed:Planar64::int(18), - walk_accel:Planar64::int(90), - ladder_speed:Planar64::int(18), - ladder_accel:Planar64::int(180), - ladder_dot:(Planar64::int(1)/2).sqrt(), - swim_speed:Planar64::int(12), - surf_slope:Some(Planar64::raw(3787805118)),// normal.y=0.75 - hitbox:Hitbox::roblox(), - camera_offset:Planar64Vec3::int(0,2,0),//4.5-2.5=2 - } - } - - fn source_bhop()->Self{ - Self{ - controls_used:!0, - controls_mask:!0,//&!(Self::CONTROL_MOVEUP|Self::CONTROL_MOVEDOWN), - strafe:Some(StrafeSettings{ - enable:EnableStrafe::Always, - air_accel_limit:Some(Planar64::raw(150<<28)*100), - tick_rate:Ratio64::new(100,Time::ONE_SECOND.nanos() as u64).unwrap(), - }), - jump_impulse:JumpImpulse::FromHeight(Planar64::raw(52<<28)), - jump_calculation:JumpCalculation::Linear, - gravity:Planar64Vec3::raw(0,-800<<28,0), - static_friction:Planar64::int(2),//? - kinetic_friction:Planar64::int(3),//? - mass:Planar64::int(1), - mv:Planar64::raw(30<<28), - rocket_force:None, - walk_speed:Planar64::int(18),//? - walk_accel:Planar64::int(90),//? - ladder_speed:Planar64::int(18),//? - ladder_accel:Planar64::int(180),//? - ladder_dot:(Planar64::int(1)/2).sqrt(),//? - swim_speed:Planar64::int(12),//? - surf_slope:Some(Planar64::raw(3787805118)),// normal.y=0.75 - hitbox:Hitbox::source(), - camera_offset:Planar64Vec3::raw(0,(64<<28)-(73<<27),0), - } - } - fn source_surf()->Self{ - Self{ - controls_used:!0, - controls_mask:!0,//&!(Self::CONTROL_MOVEUP|Self::CONTROL_MOVEDOWN), - strafe:Some(StrafeSettings{ - enable:EnableStrafe::Always, - air_accel_limit:Some(Planar64::raw(150<<28)*66), - tick_rate:Ratio64::new(66,Time::ONE_SECOND.nanos() as u64).unwrap(), - }), - jump_impulse:JumpImpulse::FromHeight(Planar64::raw(52<<28)), - jump_calculation:JumpCalculation::Linear, - gravity:Planar64Vec3::raw(0,-800<<28,0), - static_friction:Planar64::int(2),//? - kinetic_friction:Planar64::int(3),//? - mass:Planar64::int(1), - mv:Planar64::raw(30<<28), - rocket_force:None, - walk_speed:Planar64::int(18),//? - walk_accel:Planar64::int(90),//? - ladder_speed:Planar64::int(18),//? - ladder_accel:Planar64::int(180),//? - ladder_dot:(Planar64::int(1)/2).sqrt(),//? - swim_speed:Planar64::int(12),//? - surf_slope:Some(Planar64::raw(3787805118)),// normal.y=0.75 - hitbox:Hitbox::source(), - camera_offset:Planar64Vec3::raw(0,(64<<28)-(73<<27),0), - } - } - fn roblox_rocket()->Self{ - Self{ - controls_used:!0, - controls_mask:!0, - strafe:None, - jump_impulse:JumpImpulse::FromTime(Time::from_micros(715_588)), - jump_calculation:JumpCalculation::Capped, - gravity:Planar64Vec3::int(0,-100,0), - static_friction:Planar64::int(2), - kinetic_friction:Planar64::int(3),//unrealistic: kinetic friction is typically lower than static - mass:Planar64::int(1), - mv:Planar64::int(27)/10, - rocket_force:Some(Planar64::int(200)), - walk_speed:Planar64::int(18), - walk_accel:Planar64::int(90), - ladder_speed:Planar64::int(18), - ladder_accel:Planar64::int(180), - ladder_dot:(Planar64::int(1)/2).sqrt(), - swim_speed:Planar64::int(12), - surf_slope:Some(Planar64::raw(3787805118)),// normal.y=0.75 - hitbox:Hitbox::roblox(), - camera_offset:Planar64Vec3::int(0,2,0),//4.5-2.5=2 - } - } - +impl StyleHelper for StyleModifiers{ fn get_control(&self,control:u32,controls:u32)->bool{ controls&self.controls_mask&control==control }