diff --git a/src/gameplay_attributes.rs b/src/gameplay_attributes.rs index aecb2a8..064bbcb 100644 --- a/src/gameplay_attributes.rs +++ b/src/gameplay_attributes.rs @@ -31,6 +31,22 @@ pub enum Booster{ //Affine(crate::integer::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 + AirTime(Time),//increase airtime, invariant across mass and gravity changes + Height(Planar64),//increase height, invariant across mass and gravity changes +} +impl Booster{ + pub fn boost(&self,velocity:Planar64Vec3)->Planar64Vec3{ + match self{ + &Booster::Velocity(boost_velocity)=>velocity+boost_velocity, + &Booster::Energy{direction,energy}=>{ + let d=direction.dot(velocity); + //TODO: think about negative + velocity+direction.with_length((d*d+energy).sqrt()-d) + }, + Booster::AirTime(_)=>todo!(), + Booster::Height(_)=>todo!(), + } + } } #[derive(Clone,Hash,Eq,PartialEq)] pub enum TrajectoryChoice{ diff --git a/src/gameplay_style.rs b/src/gameplay_style.rs index f03b226..aec74c1 100644 --- a/src/gameplay_style.rs +++ b/src/gameplay_style.rs @@ -41,33 +41,135 @@ impl std::default::Default for StyleModifiers{ #[derive(Clone,Debug)] pub enum JumpCalculation{ - Capped,//roblox - Energy,//new - Linear,//source + Max,//Roblox: jumped_speed=max(velocity.boost(),velocity.jump()) + BoostThenJump,//jumped_speed=velocity.boost().jump() + JumpThenBoost,//jumped_speed=velocity.jump().boost() } #[derive(Clone,Debug)] pub enum JumpImpulse{ - FromTime(Time),//jump time is invariant across mass and gravity changes - FromHeight(Planar64),//jump height is invariant across mass and gravity changes - FromLinear(Planar64),//jump velocity is invariant across mass and gravity changes - FromEnergy(Planar64),// :) + Time(Time),//jump time is invariant across mass and gravity changes + Height(Planar64),//jump height is invariant across mass and gravity changes + Linear(Planar64),//jump velocity is invariant across mass and gravity changes + Energy(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 impl JumpImpulse{ - //fn get_jump_time(&self)->Planar64 - //fn get_jump_height(&self)->Planar64 - //fn get_jump_energy(&self)->Planar64 + pub fn jump( + &self, + velocity:Planar64Vec3, + jump_dir:Planar64Vec3, + gravity:&Planar64Vec3, + mass:Planar64, + )->Planar64Vec3{ + match self{ + &JumpImpulse::Time(time)=>velocity-*gravity*time, + &JumpImpulse::Height(height)=>{ + //height==-v.y*v.y/(2*g.y); + //use energy to determine max height + let g=gravity.length(); + let v_g=gravity.dot(velocity)/g; + //do it backwards + velocity-gravity.with_length((v_g*v_g+height*g*2).sqrt()+v_g) + }, + &JumpImpulse::Linear(jump_speed)=>velocity+jump_dir.with_length(jump_speed), + &JumpImpulse::Energy(energy)=>{ + //calculate energy + let e=gravity.dot(velocity); + //add + //you get the idea + todo!() + }, + } + } + //TODO: remove this and implement JumpCalculation properly pub fn get_jump_deltav(&self,gravity:&Planar64Vec3,mass:Planar64)->Planar64{ //gravity.length() is actually the proper calculation because the jump is always opposite the gravity direction match self{ - &JumpImpulse::FromTime(time)=>gravity.length()*(time/2), - &JumpImpulse::FromHeight(height)=>(gravity.length()*height*2).sqrt(), - &JumpImpulse::FromLinear(deltav)=>deltav, - &JumpImpulse::FromEnergy(energy)=>(energy*2/mass).sqrt(), + &JumpImpulse::Time(time)=>gravity.length()*(time/2), + &JumpImpulse::Height(height)=>(gravity.length()*height*2).sqrt(), + &JumpImpulse::Linear(deltav)=>deltav, + &JumpImpulse::Energy(energy)=>(energy*2/mass).sqrt(), + } + } +} + +#[derive(Clone,Debug)] +pub struct JumpSettings{ + //information used to calculate jump power + pub impulse:JumpImpulse, + //information used to calculate jump behaviour + pub calculation:JumpCalculation, + //limit the minimum jump power when combined with downwards momentum + //This is true in both roblox and source + pub limit_minimum:bool, +} +impl JumpSettings{ + pub fn jumped_velocity( + &self, + style:&StyleModifiers, + jump_dir:Planar64Vec3, + rel_velocity:Planar64Vec3, + booster:Option<&crate::gameplay_attributes::Booster>, + )->Planar64Vec3{ + let jump_speed=self.impulse.get_jump_deltav(&style.gravity,style.mass); + match (self.limit_minimum,&self.calculation){ + (true,JumpCalculation::Max)=>{ + //the roblox calculation + let boost_vel=match booster{ + Some(booster)=>booster.boost(rel_velocity), + None=>rel_velocity, + }; + let j=boost_vel.dot(jump_dir); + if j{ + //the source calculation (?) + let boost_vel=match booster{ + Some(booster)=>booster.boost(rel_velocity), + None=>rel_velocity, + }; + let j=boost_vel.dot(jump_dir); + if j{ + //??? calculation + //max(boost_vel,jump_vel) + let boost_vel=match booster{ + Some(booster)=>booster.boost(rel_velocity), + None=>rel_velocity, + }; + let boost_dot=boost_vel.dot(jump_dir); + if boost_dot{ + let boost_vel=match booster{ + Some(booster)=>booster.boost(rel_velocity), + None=>rel_velocity, + }; + boost_vel+jump_dir.with_length(jump_speed) + }, } } } @@ -185,26 +287,6 @@ impl PropulsionSettings{ } } -#[derive(Clone,Debug)] -pub struct JumpSettings{ - //information used to calculate jump power - pub impulse:JumpImpulse, - //information used to calculate jump behaviour - pub calculation:JumpCalculation, -} -impl JumpSettings{ - pub fn jumped_velocity(&self,style:&StyleModifiers,jump_dir:Planar64Vec3,velocity:Planar64Vec3)->Planar64Vec3{ - match self.calculation{ - //roblox style - JumpCalculation::Capped=>todo!(), - //something different - JumpCalculation::Energy=>todo!(), - //source style - JumpCalculation::Linear=>velocity+jump_dir*(self.impulse.get_jump_deltav(&style.gravity,style.mass)/jump_dir.length()), - } - } -} - #[derive(Clone,Debug)] pub struct AccelerateSettings{ pub accel:Planar64, @@ -345,8 +427,9 @@ impl StyleModifiers{ tick_rate:Ratio64::new(64,Time::ONE_SECOND.nanos() as u64).unwrap(), }), jump:Some(JumpSettings{ - impulse:JumpImpulse::FromEnergy(Planar64::int(512)), - calculation:JumpCalculation::Energy, + impulse:JumpImpulse::Energy(Planar64::int(512)), + calculation:JumpCalculation::JumpThenBoost, + limit_minimum:false, }), gravity:Planar64Vec3::int(0,-80,0), mass:Planar64::int(1), @@ -386,8 +469,9 @@ impl StyleModifiers{ tick_rate:Ratio64::new(100,Time::ONE_SECOND.nanos() as u64).unwrap(), }), jump:Some(JumpSettings{ - impulse:JumpImpulse::FromTime(Time::from_micros(715_588)), - calculation:JumpCalculation::Linear,//Should be capped + impulse:JumpImpulse::Time(Time::from_micros(715_588)), + calculation:JumpCalculation::Max, + limit_minimum:true, }), gravity:Planar64Vec3::int(0,-100,0), mass:Planar64::int(1), @@ -442,8 +526,9 @@ impl StyleModifiers{ tick_rate:Ratio64::new(100,Time::ONE_SECOND.nanos() as u64).unwrap(), }), jump:Some(JumpSettings{ - impulse:JumpImpulse::FromHeight(Planar64::int(52)*VALVE_SCALE), - calculation:JumpCalculation::Linear, + impulse:JumpImpulse::Height(Planar64::int(52)*VALVE_SCALE), + calculation:JumpCalculation::JumpThenBoost, + limit_minimum:true, }), gravity:Planar64Vec3::int(0,-800,0)*VALVE_SCALE, mass:Planar64::int(1), @@ -482,8 +567,9 @@ impl StyleModifiers{ tick_rate:Ratio64::new(66,Time::ONE_SECOND.nanos() as u64).unwrap(), }), jump:Some(JumpSettings{ - impulse:JumpImpulse::FromHeight(Planar64::int(52)*VALVE_SCALE), - calculation:JumpCalculation::Linear, + impulse:JumpImpulse::Height(Planar64::int(52)*VALVE_SCALE), + calculation:JumpCalculation::JumpThenBoost, + limit_minimum:true, }), gravity:Planar64Vec3::int(0,-800,0)*VALVE_SCALE, mass:Planar64::int(1),