Compare commits
10 Commits
master
...
redesign-s
Author | SHA1 | Date | |
---|---|---|---|
edf5278e37 | |||
43a4237c17 | |||
c44e5dad96 | |||
1c45e9a821 | |||
3f62b9b353 | |||
59348f8cbe | |||
d292993c16 | |||
12907fa4a9 | |||
73cd6b74fc | |||
1ca1169697 |
7
Cargo.lock
generated
7
Cargo.lock
generated
@ -2,6 +2,12 @@
|
|||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitflags"
|
||||||
|
version = "2.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "glam"
|
name = "glam"
|
||||||
version = "0.25.0"
|
version = "0.25.0"
|
||||||
@ -40,6 +46,7 @@ dependencies = [
|
|||||||
name = "strafesnet_common"
|
name = "strafesnet_common"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
"glam",
|
"glam",
|
||||||
"id",
|
"id",
|
||||||
]
|
]
|
||||||
|
@ -6,5 +6,6 @@ edition = "2021"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
bitflags = "2.4.2"
|
||||||
glam = "0.25.0"
|
glam = "0.25.0"
|
||||||
id = { git = "https://git.itzana.me/Quaternions/id", rev = "1f710976cc786c8853dab73d6e1cee53158deeb0" }
|
id = { git = "https://git.itzana.me/Quaternions/id", rev = "1f710976cc786c8853dab73d6e1cee53158deeb0" }
|
||||||
|
30
src/controls_bitflag.rs
Normal file
30
src/controls_bitflag.rs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
bitflags::bitflags!{
|
||||||
|
#[derive(Clone,Copy,Debug,Default)]
|
||||||
|
pub struct Controls:u32{
|
||||||
|
const MoveForward=1<<0;
|
||||||
|
const MoveLeft=1<<1;
|
||||||
|
const MoveBackward=1<<2;
|
||||||
|
const MoveRight=1<<3;
|
||||||
|
const MoveUp=1<<4;
|
||||||
|
const MoveDown=1<<5;
|
||||||
|
const LookUp=1<<6;
|
||||||
|
const LookLeft=1<<7;
|
||||||
|
const LookDown=1<<8;
|
||||||
|
const LookRight=1<<9;
|
||||||
|
const Jump=1<<10;
|
||||||
|
const Crouch=1<<11;
|
||||||
|
const Sprint=1<<12;
|
||||||
|
const Zoom=1<<13;
|
||||||
|
const Use=1<<14;//Interact with object
|
||||||
|
const PrimaryAction=1<<15;//LBM/Shoot/Melee
|
||||||
|
const SecondaryAction=1<<16;//RMB/ADS/Block
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Controls{
|
||||||
|
pub const fn wasd()->Self{
|
||||||
|
Self::MoveForward.union(Self::MoveLeft).union(Self::MoveBackward).union(Self::MoveRight)
|
||||||
|
}
|
||||||
|
pub const fn wasdqe()->Self{
|
||||||
|
Self::MoveForward.union(Self::MoveLeft).union(Self::MoveBackward).union(Self::MoveRight).union(Self::MoveUp).union(Self::MoveDown)
|
||||||
|
}
|
||||||
|
}
|
@ -7,15 +7,17 @@ use crate::updatable::Updatable;
|
|||||||
pub struct StageElement{
|
pub struct StageElement{
|
||||||
stage_id:StageId,//which stage spawn to send to
|
stage_id:StageId,//which stage spawn to send to
|
||||||
force:bool,//allow setting to lower spawn id i.e. 7->3
|
force:bool,//allow setting to lower spawn id i.e. 7->3
|
||||||
behaviour:StageElementBehaviour
|
behaviour:StageElementBehaviour,
|
||||||
|
jump_limit:Option<u8>,
|
||||||
}
|
}
|
||||||
impl StageElement{
|
impl StageElement{
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn new(stage_id:StageId,force:bool,behaviour:StageElementBehaviour)->Self{
|
pub const fn new(stage_id:StageId,force:bool,behaviour:StageElementBehaviour,jump_limit:Option<u8>)->Self{
|
||||||
Self{
|
Self{
|
||||||
stage_id,
|
stage_id,
|
||||||
force,
|
force,
|
||||||
behaviour,
|
behaviour,
|
||||||
|
jump_limit,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -30,6 +32,10 @@ impl StageElement{
|
|||||||
pub const fn behaviour(&self)->StageElementBehaviour{
|
pub const fn behaviour(&self)->StageElementBehaviour{
|
||||||
self.behaviour
|
self.behaviour
|
||||||
}
|
}
|
||||||
|
#[inline]
|
||||||
|
pub const fn jump_limit(&self)->Option<u8>{
|
||||||
|
self.jump_limit
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone,Copy,Hash,Eq,PartialEq)]
|
#[derive(Clone,Copy,Hash,Eq,PartialEq)]
|
||||||
@ -44,12 +50,12 @@ pub enum StageElementBehaviour{
|
|||||||
Checkpoint,//this is a combined behaviour for Ordered & Unordered in case a model is used multiple times or for both.
|
Checkpoint,//this is a combined behaviour for Ordered & Unordered in case a model is used multiple times or for both.
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone,Copy,Hash,id::Id,Eq,PartialEq)]
|
#[derive(Clone,Copy,Debug,Hash,id::Id,Eq,PartialEq)]
|
||||||
pub struct CheckpointId(u32);
|
pub struct CheckpointId(u32);
|
||||||
impl CheckpointId{
|
impl CheckpointId{
|
||||||
pub const FIRST:Self=Self(0);
|
pub const FIRST:Self=Self(0);
|
||||||
}
|
}
|
||||||
#[derive(Clone,Copy,Hash,id::Id,Eq,PartialEq,Ord,PartialOrd)]
|
#[derive(Clone,Copy,Debug,Hash,id::Id,Eq,PartialEq,Ord,PartialOrd)]
|
||||||
pub struct StageId(u32);
|
pub struct StageId(u32);
|
||||||
impl StageId{
|
impl StageId{
|
||||||
pub const FIRST:Self=Self(0);
|
pub const FIRST:Self=Self(0);
|
||||||
@ -114,7 +120,7 @@ pub enum Zone{
|
|||||||
Finish,
|
Finish,
|
||||||
Anticheat,
|
Anticheat,
|
||||||
}
|
}
|
||||||
#[derive(Clone,Copy,Hash,id::Id,Eq,PartialEq,Ord,PartialOrd)]
|
#[derive(Clone,Copy,Debug,Hash,id::Id,Eq,PartialEq,Ord,PartialOrd)]
|
||||||
pub struct ModeId(u32);
|
pub struct ModeId(u32);
|
||||||
impl ModeId{
|
impl ModeId{
|
||||||
pub const MAIN:Self=Self(0);
|
pub const MAIN:Self=Self(0);
|
||||||
@ -128,7 +134,6 @@ pub struct Mode{
|
|||||||
stages:Vec<Stage>,//when you load the map you go to stages[0].spawn
|
stages:Vec<Stage>,//when you load the map you go to stages[0].spawn
|
||||||
//mutually exlusive stage element behaviour
|
//mutually exlusive stage element behaviour
|
||||||
elements:HashMap<ModelId,StageElement>,
|
elements:HashMap<ModelId,StageElement>,
|
||||||
jump_limit:HashMap<ModelId,u32>,
|
|
||||||
}
|
}
|
||||||
impl Mode{
|
impl Mode{
|
||||||
pub fn new(style:gameplay_style::StyleModifiers,start:ModelId)->Self{
|
pub fn new(style:gameplay_style::StyleModifiers,start:ModelId)->Self{
|
||||||
@ -138,7 +143,6 @@ impl Mode{
|
|||||||
zones:HashMap::new(),
|
zones:HashMap::new(),
|
||||||
stages:Vec::new(),
|
stages:Vec::new(),
|
||||||
elements:HashMap::new(),
|
elements:HashMap::new(),
|
||||||
jump_limit:HashMap::new(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub const fn get_start(&self)->ModelId{
|
pub const fn get_start(&self)->ModelId{
|
||||||
@ -165,9 +169,6 @@ impl Mode{
|
|||||||
pub fn get_element(&self,model_id:ModelId)->Option<&StageElement>{
|
pub fn get_element(&self,model_id:ModelId)->Option<&StageElement>{
|
||||||
self.elements.get(&model_id)
|
self.elements.get(&model_id)
|
||||||
}
|
}
|
||||||
pub fn get_jump_limit(&self,model_id:ModelId)->Option<u32>{
|
|
||||||
self.jump_limit.get(&model_id).copied()
|
|
||||||
}
|
|
||||||
//TODO: put this in the SNF
|
//TODO: put this in the SNF
|
||||||
pub fn denormalize_data(&mut self){
|
pub fn denormalize_data(&mut self){
|
||||||
//expand and index normalized data
|
//expand and index normalized data
|
||||||
@ -177,12 +178,14 @@ impl Mode{
|
|||||||
stage_id:StageId(stage_id as u32),
|
stage_id:StageId(stage_id as u32),
|
||||||
force:false,
|
force:false,
|
||||||
behaviour:StageElementBehaviour::SpawnAt,
|
behaviour:StageElementBehaviour::SpawnAt,
|
||||||
|
jump_limit:None,
|
||||||
});
|
});
|
||||||
for (_,&model) in &stage.ordered_checkpoints{
|
for (_,&model) in &stage.ordered_checkpoints{
|
||||||
self.elements.insert(model,StageElement{
|
self.elements.insert(model,StageElement{
|
||||||
stage_id:StageId(stage_id as u32),
|
stage_id:StageId(stage_id as u32),
|
||||||
force:false,
|
force:false,
|
||||||
behaviour:StageElementBehaviour::Checkpoint,
|
behaviour:StageElementBehaviour::Checkpoint,
|
||||||
|
jump_limit:None,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
for &model in &stage.unordered_checkpoints{
|
for &model in &stage.unordered_checkpoints{
|
||||||
@ -190,6 +193,7 @@ impl Mode{
|
|||||||
stage_id:StageId(stage_id as u32),
|
stage_id:StageId(stage_id as u32),
|
||||||
force:false,
|
force:false,
|
||||||
behaviour:StageElementBehaviour::Checkpoint,
|
behaviour:StageElementBehaviour::Checkpoint,
|
||||||
|
jump_limit:None,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -202,7 +206,6 @@ pub struct ModeUpdate{
|
|||||||
stages:HashMap<StageId,StageUpdate>,
|
stages:HashMap<StageId,StageUpdate>,
|
||||||
//mutually exlusive stage element behaviour
|
//mutually exlusive stage element behaviour
|
||||||
elements:HashMap<ModelId,StageElement>,
|
elements:HashMap<ModelId,StageElement>,
|
||||||
jump_limit:HashMap<ModelId,u32>,
|
|
||||||
}
|
}
|
||||||
impl Updatable<ModeUpdate> for Mode{
|
impl Updatable<ModeUpdate> for Mode{
|
||||||
fn update(&mut self,update:ModeUpdate){
|
fn update(&mut self,update:ModeUpdate){
|
||||||
@ -213,7 +216,6 @@ impl Updatable<ModeUpdate> for Mode{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.elements.extend(update.elements);
|
self.elements.extend(update.elements);
|
||||||
self.jump_limit.extend(update.jump_limit);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl ModeUpdate{
|
impl ModeUpdate{
|
||||||
@ -232,11 +234,6 @@ impl ModeUpdate{
|
|||||||
mu.elements.insert(model_id,element);
|
mu.elements.insert(model_id,element);
|
||||||
mu
|
mu
|
||||||
}
|
}
|
||||||
pub fn jump_limit(model_id:ModelId,jump_limit:u32)->Self{
|
|
||||||
let mut mu=Self::default();
|
|
||||||
mu.jump_limit.insert(model_id,jump_limit);
|
|
||||||
mu
|
|
||||||
}
|
|
||||||
pub fn map_stage_element_ids<F:Fn(StageId)->StageId>(&mut self,f:F){
|
pub fn map_stage_element_ids<F:Fn(StageId)->StageId>(&mut self,f:F){
|
||||||
for (_,stage_element) in self.elements.iter_mut(){
|
for (_,stage_element) in self.elements.iter_mut(){
|
||||||
stage_element.stage_id=f(stage_element.stage_id);
|
stage_element.stage_id=f(stage_element.stage_id);
|
||||||
|
@ -1,225 +1,50 @@
|
|||||||
const VALVE_SCALE:Planar64=Planar64::raw(1<<28);// 1/16
|
const VALVE_SCALE:Planar64=Planar64::raw(1<<28);// 1/16
|
||||||
|
|
||||||
use crate::integer::{Time,Ratio64,Planar64,Planar64Vec3};
|
use crate::integer::{Time,Ratio64,Planar64,Planar64Vec3};
|
||||||
|
use crate::controls_bitflag::Controls;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone,Debug)]
|
||||||
pub struct StyleModifiers{
|
pub struct StyleModifiers{
|
||||||
pub controls_used:u32,//controls which are allowed to pass into gameplay
|
//controls which are allowed to pass into gameplay (usually all)
|
||||||
pub controls_mask:u32,//controls which are masked from control state (e.g. jump in scroll style)
|
pub controls_mask:Controls,
|
||||||
|
//controls which are masked from control state (e.g. !jump in scroll style)
|
||||||
|
pub controls_mask_state:Controls,
|
||||||
|
//strafing
|
||||||
pub strafe:Option<StrafeSettings>,
|
pub strafe:Option<StrafeSettings>,
|
||||||
pub jump_impulse:JumpImpulse,
|
//player gets a controllable rocket force
|
||||||
pub jump_calculation:JumpCalculation,
|
pub rocket:Option<PropulsionSettings>,
|
||||||
pub static_friction:Planar64,
|
//flying
|
||||||
pub kinetic_friction:Planar64,
|
//jumping is allowed
|
||||||
pub walk_speed:Planar64,
|
pub jump:Option<JumpSettings>,
|
||||||
pub walk_accel:Planar64,
|
//standing & walking is allowed
|
||||||
pub ladder_speed:Planar64,
|
pub walk:Option<WalkSettings>,
|
||||||
pub ladder_accel:Planar64,
|
//laddering is allowed
|
||||||
pub ladder_dot:Planar64,
|
pub ladder:Option<LadderSettings>,
|
||||||
pub swim_speed:Planar64,
|
//water propulsion
|
||||||
pub mass:Planar64,
|
pub swim:Option<PropulsionSettings>,
|
||||||
pub mv:Planar64,
|
//maximum slope before sloped surfaces become frictionless
|
||||||
pub surf_slope:Option<Planar64>,
|
|
||||||
pub rocket_force:Option<Planar64>,
|
|
||||||
pub gravity:Planar64Vec3,
|
pub gravity:Planar64Vec3,
|
||||||
|
//hitbox
|
||||||
pub hitbox:Hitbox,
|
pub hitbox:Hitbox,
|
||||||
|
//camera location relative to the center (0,0,0) of the hitbox
|
||||||
pub camera_offset:Planar64Vec3,
|
pub camera_offset:Planar64Vec3,
|
||||||
|
//unused
|
||||||
|
pub mass:Planar64,
|
||||||
}
|
}
|
||||||
impl std::default::Default for StyleModifiers{
|
impl std::default::Default for StyleModifiers{
|
||||||
fn default()->Self{
|
fn default()->Self{
|
||||||
Self::roblox_bhop()
|
Self::roblox_bhop()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl StyleModifiers{
|
|
||||||
pub const CONTROL_MOVEFORWARD:u32=0b00000001;
|
|
||||||
pub const CONTROL_MOVEBACK:u32=0b00000010;
|
|
||||||
pub const CONTROL_MOVERIGHT:u32=0b00000100;
|
|
||||||
pub const CONTROL_MOVELEFT:u32=0b00001000;
|
|
||||||
pub const CONTROL_MOVEUP:u32=0b00010000;
|
|
||||||
pub const CONTROL_MOVEDOWN:u32=0b00100000;
|
|
||||||
pub const CONTROL_JUMP:u32=0b01000000;
|
|
||||||
pub const CONTROL_ZOOM:u32=0b10000000;
|
|
||||||
|
|
||||||
pub const RIGHT_DIR:Planar64Vec3=Planar64Vec3::X;
|
#[derive(Clone,Debug)]
|
||||||
pub const UP_DIR:Planar64Vec3=Planar64Vec3::Y;
|
|
||||||
pub 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub 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::int(52)*VALVE_SCALE),
|
|
||||||
jump_calculation:JumpCalculation::Linear,
|
|
||||||
gravity:Planar64Vec3::int(0,-800,0)*VALVE_SCALE,
|
|
||||||
static_friction:Planar64::int(2),//?
|
|
||||||
kinetic_friction:Planar64::int(3),//?
|
|
||||||
mass:Planar64::int(1),
|
|
||||||
mv:Planar64::raw(30)*VALVE_SCALE,
|
|
||||||
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::int(0,64,0)-Planar64Vec3::int(0,73,0)/2)*VALVE_SCALE,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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::int(150)*66*VALVE_SCALE),
|
|
||||||
tick_rate:Ratio64::new(66,Time::ONE_SECOND.nanos() as u64).unwrap(),
|
|
||||||
}),
|
|
||||||
jump_impulse:JumpImpulse::FromHeight(Planar64::int(52)*VALVE_SCALE),
|
|
||||||
jump_calculation:JumpCalculation::Linear,
|
|
||||||
gravity:Planar64Vec3::int(0,-800,0)*VALVE_SCALE,
|
|
||||||
static_friction:Planar64::int(2),//?
|
|
||||||
kinetic_friction:Planar64::int(3),//?
|
|
||||||
mass:Planar64::int(1),
|
|
||||||
mv:Planar64::int(30)*VALVE_SCALE,
|
|
||||||
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::int(0,64,0)-Planar64Vec3::int(0,73,0)/2)*VALVE_SCALE,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
pub enum JumpCalculation{
|
pub enum JumpCalculation{
|
||||||
Capped,//roblox
|
Capped,//roblox
|
||||||
Energy,//new
|
Energy,//new
|
||||||
Linear,//source
|
Linear,//source
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone,Debug)]
|
||||||
pub enum JumpImpulse{
|
pub enum JumpImpulse{
|
||||||
FromTime(Time),//jump time is invariant across mass and gravity changes
|
FromTime(Time),//jump time is invariant across mass and gravity changes
|
||||||
FromHeight(Planar64),//jump height is invariant across mass and gravity changes
|
FromHeight(Planar64),//jump height is invariant across mass and gravity changes
|
||||||
@ -230,35 +55,260 @@ pub enum JumpImpulse{
|
|||||||
//Capped means it increases the dot to the cap
|
//Capped means it increases the dot to the cap
|
||||||
//Energy means it adds energy
|
//Energy means it adds energy
|
||||||
//Linear means it linearly adds on
|
//Linear means it linearly adds on
|
||||||
|
impl JumpImpulse{
|
||||||
#[derive(Clone)]
|
//fn get_jump_time(&self)->Planar64
|
||||||
pub enum EnableStrafe{
|
//fn get_jump_height(&self)->Planar64
|
||||||
Always,
|
//fn get_jump_energy(&self)->Planar64
|
||||||
MaskAny(u32),//hsw, shsw
|
pub fn get_jump_deltav(&self,gravity:&Planar64Vec3,mass:Planar64)->Planar64{
|
||||||
MaskAll(u32),
|
//gravity.length() is actually the proper calculation because the jump is always opposite the gravity direction
|
||||||
//Function(Box<dyn Fn(u32)->bool>),
|
match self{
|
||||||
|
&JumpImpulse::FromTime(time)=>gravity.length()*(time/2),
|
||||||
|
&JumpImpulse::FromHeight(height)=>(gravity.length()*height*2).sqrt(),
|
||||||
|
&JumpImpulse::FromDeltaV(deltav)=>deltav,
|
||||||
|
&JumpImpulse::FromEnergy(energy)=>(energy*2/mass).sqrt(),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone,Debug)]
|
||||||
|
pub struct ControlsActivation{
|
||||||
|
//allowed keys
|
||||||
|
controls_mask:Controls,
|
||||||
|
//allow strafing only if any of the masked controls are held, eg W|S for shsw
|
||||||
|
controls_intersects:Controls,
|
||||||
|
//allow strafing only if all of the masked controls are held, eg W for hsw, w-only
|
||||||
|
controls_contains:Controls,
|
||||||
|
//Function(Box<dyn Fn(u32)->bool>),
|
||||||
|
}
|
||||||
|
impl ControlsActivation{
|
||||||
|
pub const fn new(
|
||||||
|
controls_mask:Controls,
|
||||||
|
controls_intersects:Controls,
|
||||||
|
controls_contains:Controls,
|
||||||
|
)->Self{
|
||||||
|
Self{
|
||||||
|
controls_mask,
|
||||||
|
controls_intersects,
|
||||||
|
controls_contains,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub const fn mask(&self,controls:Controls)->Controls{
|
||||||
|
controls.intersection(self.controls_mask)
|
||||||
|
}
|
||||||
|
pub const fn activates(&self,controls:Controls)->bool{
|
||||||
|
(self.controls_intersects.is_empty()||controls.intersects(self.controls_intersects))
|
||||||
|
&&controls.contains(self.controls_contains)
|
||||||
|
}
|
||||||
|
pub const fn full_3d()->Self{
|
||||||
|
Self{
|
||||||
|
controls_mask:Controls::wasdqe(),
|
||||||
|
controls_intersects:Controls::wasdqe(),
|
||||||
|
controls_contains:Controls::empty(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//classical styles
|
||||||
|
//Normal
|
||||||
|
pub const fn full_2d()->Self{
|
||||||
|
Self{
|
||||||
|
controls_mask:Controls::wasd(),
|
||||||
|
controls_intersects:Controls::wasd(),
|
||||||
|
controls_contains:Controls::empty(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Sideways
|
||||||
|
pub const fn sideways()->Self{
|
||||||
|
Self{
|
||||||
|
controls_mask:Controls::MoveForward.union(Controls::MoveBackward),
|
||||||
|
controls_intersects:Controls::MoveForward.union(Controls::MoveBackward),
|
||||||
|
controls_contains:Controls::empty(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Half-Sideways
|
||||||
|
pub const fn half_sideways()->Self{
|
||||||
|
Self{
|
||||||
|
controls_mask:Controls::MoveForward.union(Controls::MoveLeft).union(Controls::MoveRight),
|
||||||
|
controls_intersects:Controls::MoveLeft.union(Controls::MoveRight),
|
||||||
|
controls_contains:Controls::MoveForward,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Surf Half-Sideways
|
||||||
|
pub const fn surf_half_sideways()->Self{
|
||||||
|
Self{
|
||||||
|
controls_mask:Controls::MoveForward.union(Controls::MoveBackward).union(Controls::MoveLeft).union(Controls::MoveRight),
|
||||||
|
controls_intersects:Controls::MoveForward.union(Controls::MoveBackward),
|
||||||
|
controls_contains:Controls::empty(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//W-Only
|
||||||
|
pub const fn w_only()->Self{
|
||||||
|
Self{
|
||||||
|
controls_mask:Controls::MoveForward,
|
||||||
|
controls_intersects:Controls::empty(),
|
||||||
|
controls_contains:Controls::MoveForward,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//A-Only
|
||||||
|
pub const fn a_only()->Self{
|
||||||
|
Self{
|
||||||
|
controls_mask:Controls::MoveLeft,
|
||||||
|
controls_intersects:Controls::empty(),
|
||||||
|
controls_contains:Controls::MoveLeft,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//Backwards
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone,Debug)]
|
||||||
pub struct StrafeSettings{
|
pub struct StrafeSettings{
|
||||||
enable:EnableStrafe,
|
enable:ControlsActivation,
|
||||||
|
mv:Planar64,
|
||||||
air_accel_limit:Option<Planar64>,
|
air_accel_limit:Option<Planar64>,
|
||||||
tick_rate:Ratio64,
|
tick_rate:Ratio64,
|
||||||
}
|
}
|
||||||
impl StrafeSettings{
|
impl StrafeSettings{
|
||||||
|
pub fn tick_velocity(&self,velocity:Planar64Vec3,control_dir:Planar64Vec3)->Option<Planar64Vec3>{
|
||||||
|
let d=velocity.dot(control_dir);
|
||||||
|
match d<self.mv{
|
||||||
|
true=>Some(velocity+control_dir*self.air_accel_limit.map_or(self.mv-d,|limit|limit.min(self.mv-d))),
|
||||||
|
false=>None,
|
||||||
|
}
|
||||||
|
}
|
||||||
pub fn next_tick(&self,time:Time)->Time{
|
pub fn next_tick(&self,time:Time)->Time{
|
||||||
Time::from_nanos(self.tick_rate.rhs_div_int(self.tick_rate.mul_int(time.nanos())+1))
|
Time::from_nanos(self.tick_rate.rhs_div_int(self.tick_rate.mul_int(time.nanos())+1))
|
||||||
}
|
}
|
||||||
pub fn mask(&self,controls:u32)->bool{
|
pub const fn activates(&self,controls:Controls)->bool{
|
||||||
match self.enable{
|
self.enable.activates(controls)
|
||||||
EnableStrafe::Always=>true,
|
}
|
||||||
EnableStrafe::MaskAny(mask)=>mask&controls!=0,
|
pub const fn mask(&self,controls:Controls)->Controls{
|
||||||
EnableStrafe::MaskAll(mask)=>mask&controls==mask,
|
self.enable.mask(controls)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone,Debug)]
|
||||||
|
pub struct PropulsionSettings{
|
||||||
|
magnitude:Planar64,
|
||||||
|
}
|
||||||
|
impl PropulsionSettings{
|
||||||
|
pub fn acceleration(&self,control_dir:Planar64Vec3)->Planar64Vec3{
|
||||||
|
control_dir*self.magnitude
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone,Debug)]
|
||||||
|
pub struct JumpSettings{
|
||||||
|
//information used to calculate jump power
|
||||||
|
impulse:JumpImpulse,
|
||||||
|
//information used to calculate jump behaviour
|
||||||
|
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)]
|
#[derive(Clone,Debug)]
|
||||||
|
pub struct AccelerateSettings{
|
||||||
|
accel:Planar64,
|
||||||
|
topspeed:Planar64,
|
||||||
|
}
|
||||||
|
#[derive(Clone,Debug)]
|
||||||
|
pub struct WalkSettings{
|
||||||
|
accelerate:AccelerateSettings,
|
||||||
|
static_friction:Planar64,
|
||||||
|
kinetic_friction:Planar64,
|
||||||
|
//if a surf slope angle does not exist, then everything is slippery and walking is impossible
|
||||||
|
surf_dot:Planar64,//surf_dot<n.dot(up)/n.length()
|
||||||
|
}
|
||||||
|
impl WalkSettings{
|
||||||
|
pub fn accel(&self,target_diff:Planar64Vec3,gravity:Planar64Vec3)->Planar64{
|
||||||
|
//TODO: fallible walk accel
|
||||||
|
let diff_len=target_diff.length();
|
||||||
|
let friction=if diff_len<self.accelerate.topspeed{
|
||||||
|
self.static_friction
|
||||||
|
}else{
|
||||||
|
self.kinetic_friction
|
||||||
|
};
|
||||||
|
self.accelerate.accel.min(-Planar64Vec3::Y.dot(gravity)*friction)
|
||||||
|
}
|
||||||
|
pub fn get_walk_target_velocity(&self,control_dir:Planar64Vec3,normal:Planar64Vec3)->Planar64Vec3{
|
||||||
|
if control_dir==Planar64Vec3::ZERO{
|
||||||
|
return control_dir;
|
||||||
|
}
|
||||||
|
let n=normal.length();
|
||||||
|
let m=control_dir.length();
|
||||||
|
let d=normal.dot(control_dir)/m;
|
||||||
|
if d<n{
|
||||||
|
let cr=normal.cross(control_dir);
|
||||||
|
if cr==Planar64Vec3::ZERO{
|
||||||
|
Planar64Vec3::ZERO
|
||||||
|
}else{
|
||||||
|
cr.cross(normal)*(self.accelerate.topspeed/(n*(n*n-d*d).sqrt()*m))
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
Planar64Vec3::ZERO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn is_slope_walkable(&self,normal:Planar64Vec3,up:Planar64Vec3)->bool{
|
||||||
|
//normal is not guaranteed to be unit length
|
||||||
|
let ny=normal.dot(up);
|
||||||
|
let h=normal.length();
|
||||||
|
//remember this is a normal vector
|
||||||
|
Planar64::ZERO<ny&&h*self.surf_dot<ny
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone,Debug)]
|
||||||
|
pub struct LadderSettings{
|
||||||
|
accelerate:AccelerateSettings,
|
||||||
|
//how close to pushing directly into/out of the ladder normal
|
||||||
|
//does your input need to be to redirect straight up/down the ladder
|
||||||
|
dot:Planar64,
|
||||||
|
}
|
||||||
|
impl LadderSettings{
|
||||||
|
pub fn accel(&self,target_diff:Planar64Vec3,gravity:Planar64Vec3)->Planar64{
|
||||||
|
//TODO: fallible ladder accel
|
||||||
|
self.accelerate.accel
|
||||||
|
}
|
||||||
|
pub fn get_ladder_target_velocity(&self,mut control_dir:Planar64Vec3,normal:Planar64Vec3)->Planar64Vec3{
|
||||||
|
if control_dir==Planar64Vec3::ZERO{
|
||||||
|
return control_dir;
|
||||||
|
}
|
||||||
|
let n=normal.length();
|
||||||
|
let m=control_dir.length();
|
||||||
|
let mut d=normal.dot(control_dir)/m;
|
||||||
|
if d< -self.dot*n{
|
||||||
|
control_dir=Planar64Vec3::Y*m;
|
||||||
|
d=normal.y();
|
||||||
|
}else if self.dot*n<d{
|
||||||
|
control_dir=Planar64Vec3::NEG_Y*m;
|
||||||
|
d=-normal.y();
|
||||||
|
}
|
||||||
|
//n=d if you are standing on top of a ladder and press E.
|
||||||
|
//two fixes:
|
||||||
|
//- ladder movement is not allowed on walkable surfaces
|
||||||
|
//- fix the underlying issue
|
||||||
|
if d.get().unsigned_abs()<n.get().unsigned_abs(){
|
||||||
|
let cr=normal.cross(control_dir);
|
||||||
|
if cr==Planar64Vec3::ZERO{
|
||||||
|
Planar64Vec3::ZERO
|
||||||
|
}else{
|
||||||
|
cr.cross(normal)*(self.accelerate.topspeed/(n*(n*n-d*d).sqrt()))
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
Planar64Vec3::ZERO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone,Debug)]
|
||||||
pub enum HitboxMesh{
|
pub enum HitboxMesh{
|
||||||
Box,//source
|
Box,//source
|
||||||
Cylinder,//roblox
|
Cylinder,//roblox
|
||||||
@ -268,22 +318,206 @@ pub enum HitboxMesh{
|
|||||||
//DualCone,
|
//DualCone,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone,Debug)]
|
||||||
pub struct Hitbox{
|
pub struct Hitbox{
|
||||||
pub halfsize:Planar64Vec3,
|
pub halfsize:Planar64Vec3,
|
||||||
pub mesh:HitboxMesh,
|
pub mesh:HitboxMesh,
|
||||||
}
|
}
|
||||||
impl Hitbox{
|
impl Hitbox{
|
||||||
fn roblox()->Self{
|
pub fn roblox()->Self{
|
||||||
Self{
|
Self{
|
||||||
halfsize:Planar64Vec3::int(2,5,2)/2,
|
halfsize:Planar64Vec3::int(2,5,2)/2,
|
||||||
mesh:HitboxMesh::Cylinder,
|
mesh:HitboxMesh::Cylinder,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn source()->Self{
|
pub fn source()->Self{
|
||||||
Self{
|
Self{
|
||||||
halfsize:Planar64Vec3::raw(33,73,33)/2*VALVE_SCALE,
|
halfsize:Planar64Vec3::raw(33,73,33)/2*VALVE_SCALE,
|
||||||
mesh:HitboxMesh::Box,
|
mesh:HitboxMesh::Box,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl StyleModifiers{
|
||||||
|
pub const RIGHT_DIR:Planar64Vec3=Planar64Vec3::X;
|
||||||
|
pub const UP_DIR:Planar64Vec3=Planar64Vec3::Y;
|
||||||
|
pub const FORWARD_DIR:Planar64Vec3=Planar64Vec3::NEG_Z;
|
||||||
|
|
||||||
|
pub fn neo()->Self{
|
||||||
|
Self{
|
||||||
|
controls_mask:Controls::all(),
|
||||||
|
controls_mask_state:Controls::all(),
|
||||||
|
strafe:Some(StrafeSettings{
|
||||||
|
enable:ControlsActivation::full_2d(),
|
||||||
|
air_accel_limit:None,
|
||||||
|
mv:Planar64::int(3),
|
||||||
|
tick_rate:Ratio64::new(64,Time::ONE_SECOND.nanos() as u64).unwrap(),
|
||||||
|
}),
|
||||||
|
jump:Some(JumpSettings{
|
||||||
|
impulse:JumpImpulse::FromEnergy(Planar64::int(512)),
|
||||||
|
calculation:JumpCalculation::Energy,
|
||||||
|
}),
|
||||||
|
gravity:Planar64Vec3::int(0,-80,0),
|
||||||
|
mass:Planar64::int(1),
|
||||||
|
rocket:None,
|
||||||
|
walk:Some(WalkSettings{
|
||||||
|
accelerate:AccelerateSettings{
|
||||||
|
topspeed:Planar64::int(16),
|
||||||
|
accel:Planar64::int(80),
|
||||||
|
},
|
||||||
|
static_friction:Planar64::int(2),
|
||||||
|
kinetic_friction:Planar64::int(3),//unrealistic: kinetic friction is typically lower than static
|
||||||
|
surf_dot:Planar64::int(3)/4,
|
||||||
|
}),
|
||||||
|
ladder:Some(LadderSettings{
|
||||||
|
accelerate:AccelerateSettings{
|
||||||
|
topspeed:Planar64::int(16),
|
||||||
|
accel:Planar64::int(160),
|
||||||
|
},
|
||||||
|
dot:(Planar64::int(1)/2).sqrt(),
|
||||||
|
}),
|
||||||
|
swim:Some(PropulsionSettings{
|
||||||
|
magnitude:Planar64::int(12),
|
||||||
|
}),
|
||||||
|
hitbox:Hitbox::roblox(),
|
||||||
|
camera_offset:Planar64Vec3::int(0,2,0),//4.5-2.5=2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn roblox_bhop()->Self{
|
||||||
|
Self{
|
||||||
|
controls_mask:Controls::all(),
|
||||||
|
controls_mask_state:Controls::all(),
|
||||||
|
strafe:Some(StrafeSettings{
|
||||||
|
enable:ControlsActivation::full_2d(),
|
||||||
|
air_accel_limit:None,
|
||||||
|
mv:Planar64::int(27)/10,
|
||||||
|
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
|
||||||
|
}),
|
||||||
|
gravity:Planar64Vec3::int(0,-100,0),
|
||||||
|
mass:Planar64::int(1),
|
||||||
|
rocket:None,
|
||||||
|
walk:Some(WalkSettings{
|
||||||
|
accelerate:AccelerateSettings{
|
||||||
|
topspeed:Planar64::int(18),
|
||||||
|
accel:Planar64::int(90),
|
||||||
|
},
|
||||||
|
static_friction:Planar64::int(2),
|
||||||
|
kinetic_friction:Planar64::int(3),//unrealistic: kinetic friction is typically lower than static
|
||||||
|
surf_dot:Planar64::int(3)/4,// normal.y=0.75
|
||||||
|
}),
|
||||||
|
ladder:Some(LadderSettings{
|
||||||
|
accelerate:AccelerateSettings{
|
||||||
|
topspeed:Planar64::int(18),
|
||||||
|
accel:Planar64::int(180),
|
||||||
|
},
|
||||||
|
dot:(Planar64::int(1)/2).sqrt(),
|
||||||
|
}),
|
||||||
|
swim:Some(PropulsionSettings{
|
||||||
|
magnitude:Planar64::int(12),
|
||||||
|
}),
|
||||||
|
hitbox:Hitbox::roblox(),
|
||||||
|
camera_offset:Planar64Vec3::int(0,2,0),//4.5-2.5=2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn roblox_surf()->Self{
|
||||||
|
Self{
|
||||||
|
gravity:Planar64Vec3::int(0,-50,0),
|
||||||
|
..Self::roblox_bhop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn roblox_rocket()->Self{
|
||||||
|
Self{
|
||||||
|
strafe:None,
|
||||||
|
rocket:Some(PropulsionSettings{
|
||||||
|
magnitude:Planar64::int(200),
|
||||||
|
}),
|
||||||
|
..Self::roblox_bhop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn source_bhop()->Self{
|
||||||
|
Self{
|
||||||
|
controls_mask:Controls::all()-Controls::MoveUp-Controls::MoveDown,
|
||||||
|
controls_mask_state:Controls::all(),
|
||||||
|
strafe:Some(StrafeSettings{
|
||||||
|
enable:ControlsActivation::full_2d(),
|
||||||
|
air_accel_limit:Some(Planar64::raw(150<<28)*100),
|
||||||
|
mv:Planar64::raw(30)*VALVE_SCALE,
|
||||||
|
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,
|
||||||
|
}),
|
||||||
|
gravity:Planar64Vec3::int(0,-800,0)*VALVE_SCALE,
|
||||||
|
mass:Planar64::int(1),
|
||||||
|
rocket:None,
|
||||||
|
walk:Some(WalkSettings{
|
||||||
|
accelerate:AccelerateSettings{
|
||||||
|
topspeed:Planar64::int(18),//?
|
||||||
|
accel:Planar64::int(90),//?
|
||||||
|
},
|
||||||
|
static_friction:Planar64::int(2),//?
|
||||||
|
kinetic_friction:Planar64::int(3),//?
|
||||||
|
surf_dot:Planar64::int(3)/4,// normal.y=0.75
|
||||||
|
}),
|
||||||
|
ladder:Some(LadderSettings{
|
||||||
|
accelerate:AccelerateSettings{
|
||||||
|
topspeed:Planar64::int(18),//?
|
||||||
|
accel:Planar64::int(180),//?
|
||||||
|
},
|
||||||
|
dot:(Planar64::int(1)/2).sqrt(),//?
|
||||||
|
}),
|
||||||
|
swim:Some(PropulsionSettings{
|
||||||
|
magnitude:Planar64::int(12),//?
|
||||||
|
}),
|
||||||
|
hitbox:Hitbox::source(),
|
||||||
|
camera_offset:(Planar64Vec3::int(0,64,0)-Planar64Vec3::int(0,73,0)/2)*VALVE_SCALE,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn source_surf()->Self{
|
||||||
|
Self{
|
||||||
|
controls_mask:Controls::all()-Controls::MoveUp-Controls::MoveDown,
|
||||||
|
controls_mask_state:Controls::all(),
|
||||||
|
strafe:Some(StrafeSettings{
|
||||||
|
enable:ControlsActivation::full_2d(),
|
||||||
|
air_accel_limit:Some(Planar64::int(150)*66*VALVE_SCALE),
|
||||||
|
mv:Planar64::int(30)*VALVE_SCALE,
|
||||||
|
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,
|
||||||
|
}),
|
||||||
|
gravity:Planar64Vec3::int(0,-800,0)*VALVE_SCALE,
|
||||||
|
mass:Planar64::int(1),
|
||||||
|
rocket:None,
|
||||||
|
walk:Some(WalkSettings{
|
||||||
|
accelerate:AccelerateSettings{
|
||||||
|
topspeed:Planar64::int(18),//?
|
||||||
|
accel:Planar64::int(90),//?
|
||||||
|
},
|
||||||
|
static_friction:Planar64::int(2),//?
|
||||||
|
kinetic_friction:Planar64::int(3),//?
|
||||||
|
surf_dot:Planar64::int(3)/4,// normal.y=0.75
|
||||||
|
}),
|
||||||
|
ladder:Some(LadderSettings{
|
||||||
|
accelerate:AccelerateSettings{
|
||||||
|
topspeed:Planar64::int(18),//?
|
||||||
|
accel:Planar64::int(180),//?
|
||||||
|
},
|
||||||
|
dot:(Planar64::int(1)/2).sqrt(),//?
|
||||||
|
}),
|
||||||
|
swim:Some(PropulsionSettings{
|
||||||
|
magnitude:Planar64::int(12),//?
|
||||||
|
}),
|
||||||
|
hitbox:Hitbox::source(),
|
||||||
|
camera_offset:(Planar64Vec3::int(0,64,0)-Planar64Vec3::int(0,73,0)/2)*VALVE_SCALE,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -10,24 +10,24 @@ impl Time{
|
|||||||
pub const ONE_MICROSECOND:Self=Self(1_000);
|
pub const ONE_MICROSECOND:Self=Self(1_000);
|
||||||
pub const ONE_NANOSECOND:Self=Self(1);
|
pub const ONE_NANOSECOND:Self=Self(1);
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_secs(num:i64)->Self{
|
pub const fn from_secs(num:i64)->Self{
|
||||||
Self(Self::ONE_SECOND.0*num)
|
Self(Self::ONE_SECOND.0*num)
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_millis(num:i64)->Self{
|
pub const fn from_millis(num:i64)->Self{
|
||||||
Self(Self::ONE_MILLISECOND.0*num)
|
Self(Self::ONE_MILLISECOND.0*num)
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_micros(num:i64)->Self{
|
pub const fn from_micros(num:i64)->Self{
|
||||||
Self(Self::ONE_MICROSECOND.0*num)
|
Self(Self::ONE_MICROSECOND.0*num)
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_nanos(num:i64)->Self{
|
pub const fn from_nanos(num:i64)->Self{
|
||||||
Self(Self::ONE_NANOSECOND.0*num)
|
Self(Self::ONE_NANOSECOND.0*num)
|
||||||
}
|
}
|
||||||
//should I have checked subtraction? force all time variables to be positive?
|
//should I have checked subtraction? force all time variables to be positive?
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn nanos(&self)->i64{
|
pub const fn nanos(self)->i64{
|
||||||
self.0
|
self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -91,7 +91,7 @@ const fn gcd(mut a:u64,mut b:u64)->u64{
|
|||||||
};
|
};
|
||||||
a
|
a
|
||||||
}
|
}
|
||||||
#[derive(Clone,Hash)]
|
#[derive(Clone,Copy,Debug,Hash)]
|
||||||
pub struct Ratio64{
|
pub struct Ratio64{
|
||||||
num:i64,
|
num:i64,
|
||||||
den:u64,
|
den:u64,
|
||||||
@ -109,15 +109,15 @@ impl Ratio64{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn mul_int(&self,rhs:i64)->i64{
|
pub const fn mul_int(&self,rhs:i64)->i64{
|
||||||
rhs*self.num/(self.den as i64)
|
rhs*self.num/(self.den as i64)
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn rhs_div_int(&self,rhs:i64)->i64{
|
pub const fn rhs_div_int(&self,rhs:i64)->i64{
|
||||||
rhs*(self.den as i64)/self.num
|
rhs*(self.den as i64)/self.num
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn mul_ref(&self,rhs:&Ratio64)->Ratio64{
|
pub const fn mul_ref(&self,rhs:&Ratio64)->Ratio64{
|
||||||
let (num,den)=(self.num*rhs.num,self.den*rhs.den);
|
let (num,den)=(self.num*rhs.num,self.den*rhs.den);
|
||||||
let d=gcd(num.unsigned_abs(),den);
|
let d=gcd(num.unsigned_abs(),den);
|
||||||
Self{
|
Self{
|
||||||
@ -259,7 +259,7 @@ impl std::ops::Div<u64> for Ratio64{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[derive(Clone,Hash)]
|
#[derive(Clone,Copy,Debug,Hash)]
|
||||||
pub struct Ratio64Vec2{
|
pub struct Ratio64Vec2{
|
||||||
pub x:Ratio64,
|
pub x:Ratio64,
|
||||||
pub y:Ratio64,
|
pub y:Ratio64,
|
||||||
@ -267,11 +267,11 @@ pub struct Ratio64Vec2{
|
|||||||
impl Ratio64Vec2{
|
impl Ratio64Vec2{
|
||||||
pub const ONE:Self=Self{x:Ratio64::ONE,y:Ratio64::ONE};
|
pub const ONE:Self=Self{x:Ratio64::ONE,y:Ratio64::ONE};
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(x:Ratio64,y:Ratio64)->Self{
|
pub const fn new(x:Ratio64,y:Ratio64)->Self{
|
||||||
Self{x,y}
|
Self{x,y}
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn mul_int(&self,rhs:glam::I64Vec2)->glam::I64Vec2{
|
pub const fn mul_int(&self,rhs:glam::I64Vec2)->glam::I64Vec2{
|
||||||
glam::i64vec2(
|
glam::i64vec2(
|
||||||
self.x.mul_int(rhs.x),
|
self.x.mul_int(rhs.x),
|
||||||
self.y.mul_int(rhs.y),
|
self.y.mul_int(rhs.y),
|
||||||
@ -606,15 +606,15 @@ impl Planar64Vec3{
|
|||||||
Self(glam::i64vec3(x,y,z))
|
Self(glam::i64vec3(x,y,z))
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn x(&self)->Planar64{
|
pub const fn x(&self)->Planar64{
|
||||||
Planar64(self.0.x)
|
Planar64(self.0.x)
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn y(&self)->Planar64{
|
pub const fn y(&self)->Planar64{
|
||||||
Planar64(self.0.y)
|
Planar64(self.0.y)
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn z(&self)->Planar64{
|
pub const fn z(&self)->Planar64{
|
||||||
Planar64(self.0.z)
|
Planar64(self.0.z)
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -642,7 +642,7 @@ impl Planar64Vec3{
|
|||||||
self.0.cmplt(rhs.0)
|
self.0.cmplt(rhs.0)
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn dot(&self,rhs:Self)->Planar64{
|
pub const fn dot(&self,rhs:Self)->Planar64{
|
||||||
Planar64(((
|
Planar64(((
|
||||||
(self.0.x as i128)*(rhs.0.x as i128)+
|
(self.0.x as i128)*(rhs.0.x as i128)+
|
||||||
(self.0.y as i128)*(rhs.0.y as i128)+
|
(self.0.y as i128)*(rhs.0.y as i128)+
|
||||||
@ -650,13 +650,13 @@ impl Planar64Vec3{
|
|||||||
)>>32) as i64)
|
)>>32) as i64)
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn dot128(&self,rhs:Self)->i128{
|
pub const fn dot128(&self,rhs:Self)->i128{
|
||||||
(self.0.x as i128)*(rhs.0.x as i128)+
|
(self.0.x as i128)*(rhs.0.x as i128)+
|
||||||
(self.0.y as i128)*(rhs.0.y as i128)+
|
(self.0.y as i128)*(rhs.0.y as i128)+
|
||||||
(self.0.z as i128)*(rhs.0.z as i128)
|
(self.0.z as i128)*(rhs.0.z as i128)
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn cross(&self,rhs:Self)->Planar64Vec3{
|
pub const fn cross(&self,rhs:Self)->Planar64Vec3{
|
||||||
Planar64Vec3(glam::i64vec3(
|
Planar64Vec3(glam::i64vec3(
|
||||||
(((self.0.y as i128)*(rhs.0.z as i128)-(self.0.z as i128)*(rhs.0.y as i128))>>32) as i64,
|
(((self.0.y as i128)*(rhs.0.z as i128)-(self.0.z as i128)*(rhs.0.y as i128))>>32) as i64,
|
||||||
(((self.0.z as i128)*(rhs.0.x as i128)-(self.0.x as i128)*(rhs.0.z as i128))>>32) as i64,
|
(((self.0.z as i128)*(rhs.0.x as i128)-(self.0.x as i128)*(rhs.0.z as i128))>>32) as i64,
|
||||||
@ -664,12 +664,6 @@ impl Planar64Vec3{
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn walkable(&self,slope:Planar64,up:Self)->bool{
|
|
||||||
let y=self.dot(up);
|
|
||||||
let x=self.cross(up).length();
|
|
||||||
x*slope<y
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
pub fn length(&self)->Planar64{
|
pub fn length(&self)->Planar64{
|
||||||
let radicand=(self.0.x as i128)*(self.0.x as i128)+(self.0.y as i128)*(self.0.y as i128)+(self.0.z as i128)*(self.0.z as i128);
|
let radicand=(self.0.x as i128)*(self.0.x as i128)+(self.0.y as i128)*(self.0.y as i128)+(self.0.z as i128)*(self.0.z as i128);
|
||||||
Planar64(unsafe{(radicand as f64).sqrt().to_int_unchecked()})
|
Planar64(unsafe{(radicand as f64).sqrt().to_int_unchecked()})
|
||||||
@ -846,7 +840,7 @@ impl Default for Planar64Mat3{
|
|||||||
}
|
}
|
||||||
impl Planar64Mat3{
|
impl Planar64Mat3{
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_cols(x_axis:Planar64Vec3,y_axis:Planar64Vec3,z_axis:Planar64Vec3)->Self{
|
pub const fn from_cols(x_axis:Planar64Vec3,y_axis:Planar64Vec3,z_axis:Planar64Vec3)->Self{
|
||||||
Self{
|
Self{
|
||||||
x_axis,
|
x_axis,
|
||||||
y_axis,
|
y_axis,
|
||||||
|
@ -6,6 +6,7 @@ pub mod zeroes;
|
|||||||
pub mod integer;
|
pub mod integer;
|
||||||
pub mod updatable;
|
pub mod updatable;
|
||||||
pub mod instruction;
|
pub mod instruction;
|
||||||
|
pub mod gameplay_attributes;
|
||||||
pub mod gameplay_modes;
|
pub mod gameplay_modes;
|
||||||
pub mod gameplay_style;
|
pub mod gameplay_style;
|
||||||
pub mod gameplay_attributes;
|
pub mod controls_bitflag;
|
Loading…
Reference in New Issue
Block a user