forked from StrafesNET/strafe-client
Compare commits
14 Commits
Author | SHA1 | Date | |
---|---|---|---|
54c0ef47c1 | |||
df2524cd2d | |||
d832004e03 | |||
f929a61ac4 | |||
aefaa8454c | |||
83e108c8e1 | |||
fde62febcf | |||
c5ecf6b34a | |||
2d2f0099ab | |||
edd15d0a09 | |||
526666651a | |||
9005de6e8e | |||
6114835471 | |||
cea51457a6 |
@ -12,12 +12,12 @@ use crate::aabb::Aabb;
|
||||
#[derive(Default)]
|
||||
pub struct BvhNode{
|
||||
children:Vec<Self>,
|
||||
models:Vec<u32>,
|
||||
models:Vec<usize>,
|
||||
aabb:Aabb,
|
||||
}
|
||||
|
||||
impl BvhNode{
|
||||
pub fn the_tester<F:FnMut(u32)>(&self,aabb:&Aabb,f:&mut F){
|
||||
pub fn the_tester<F:FnMut(usize)>(&self,aabb:&Aabb,f:&mut F){
|
||||
for &model in &self.models{
|
||||
f(model);
|
||||
}
|
||||
@ -37,7 +37,7 @@ fn generate_bvh_node(boxen:Vec<(usize,Aabb)>)->BvhNode{
|
||||
let n=boxen.len();
|
||||
if n<20{
|
||||
let mut aabb=Aabb::default();
|
||||
let models=boxen.into_iter().map(|b|{aabb.join(&b.1);b.0 as u32}).collect();
|
||||
let models=boxen.into_iter().map(|b|{aabb.join(&b.1);b.0}).collect();
|
||||
BvhNode{
|
||||
children:Vec::new(),
|
||||
models,
|
||||
|
@ -531,7 +531,14 @@ impl std::ops::Mul<Planar64> for Planar64{
|
||||
type Output=Planar64;
|
||||
#[inline]
|
||||
fn mul(self, rhs: Self) -> Self::Output {
|
||||
Planar64((((self.0 as i128)*(rhs.0 as i128))>>32) as i64)
|
||||
Planar64(((self.0 as i128*rhs.0 as i128)>>32) as i64)
|
||||
}
|
||||
}
|
||||
impl std::ops::Mul<Time> for Planar64{
|
||||
type Output=Planar64;
|
||||
#[inline]
|
||||
fn mul(self,rhs:Time)->Self::Output{
|
||||
Planar64(((self.0 as i128*rhs.0 as i128)/1_000_000_000) as i64)
|
||||
}
|
||||
}
|
||||
impl std::ops::Div<i64> for Planar64{
|
||||
@ -574,6 +581,10 @@ impl Planar64Vec3{
|
||||
Self(glam::i64vec3((x as i64)<<32,(y as i64)<<32,(z as i64)<<32))
|
||||
}
|
||||
#[inline]
|
||||
pub const fn raw(x:i64,y:i64,z:i64)->Self{
|
||||
Self(glam::i64vec3(x,y,z))
|
||||
}
|
||||
#[inline]
|
||||
pub fn x(&self)->Planar64{
|
||||
Planar64(self.0.x)
|
||||
}
|
||||
@ -808,6 +819,23 @@ impl Planar64Mat3{
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
pub fn from_rotation_yx(yaw:Angle32,pitch:Angle32)->Self{
|
||||
let xtheta=yaw.0 as f64*ANGLE32_TO_FLOAT64_RADIANS;
|
||||
let (xs,xc)=xtheta.sin_cos();
|
||||
let (xc,xs)=(xc*PLANAR64_ONE_FLOAT64,xs*PLANAR64_ONE_FLOAT64);
|
||||
let ytheta=pitch.0 as f64*ANGLE32_TO_FLOAT64_RADIANS;
|
||||
let (ys,yc)=ytheta.sin_cos();
|
||||
let (yc,ys)=(yc*PLANAR64_ONE_FLOAT64,ys*PLANAR64_ONE_FLOAT64);
|
||||
//TODO: fix this rounding towards 0
|
||||
let (xc,xs):(i64,i64)=(unsafe{xc.to_int_unchecked()},unsafe{xs.to_int_unchecked()});
|
||||
let (yc,ys):(i64,i64)=(unsafe{yc.to_int_unchecked()},unsafe{ys.to_int_unchecked()});
|
||||
Self::from_cols(
|
||||
Planar64Vec3(glam::i64vec3(xc,0,-xs)),
|
||||
Planar64Vec3(glam::i64vec3(((xs as i128*ys as i128)>>32) as i64,yc,((xc as i128*ys as i128)>>32) as i64)),
|
||||
Planar64Vec3(glam::i64vec3(((xs as i128*yc as i128)>>32) as i64,-ys,((xc as i128*yc as i128)>>32) as i64)),
|
||||
)
|
||||
}
|
||||
#[inline]
|
||||
pub fn from_rotation_y(angle:Angle32)->Self{
|
||||
let theta=angle.0 as f64*ANGLE32_TO_FLOAT64_RADIANS;
|
||||
let (s,c)=theta.sin_cos();
|
||||
|
@ -50,8 +50,17 @@ fn get_attributes(name:&str,can_collide:bool,velocity:Planar64Vec3,force_interse
|
||||
let mut contacting=crate::model::ContactingAttributes::default();
|
||||
let mut force_can_collide=can_collide;
|
||||
match name{
|
||||
"Water"=>intersecting.water=Some(crate::model::IntersectingWater{density:Planar64::ONE,viscosity:Planar64::ONE/10,current:velocity}),
|
||||
"Accelerator"=>{force_can_collide=false;intersecting.accelerator=Some(crate::model::IntersectingAccelerator{acceleration:velocity})},
|
||||
"Water"=>{
|
||||
force_can_collide=false;
|
||||
//TODO: read stupid CustomPhysicalProperties
|
||||
intersecting.water=Some(crate::model::IntersectingWater{density:Planar64::ONE,viscosity:Planar64::ONE/10,current:velocity});
|
||||
},
|
||||
"Accelerator"=>{
|
||||
//although the new game supports collidable accelerators, this is a roblox compatability map loader
|
||||
force_can_collide=false;
|
||||
general.accelerator=Some(crate::model::GameMechanicAccelerator{acceleration:velocity});
|
||||
},
|
||||
"SetVelocity"=>general.trajectory=Some(crate::model::GameMechanicSetTrajectory::Velocity(velocity)),
|
||||
"MapFinish"=>{force_can_collide=false;general.zone=Some(crate::model::GameMechanicZone{mode_id:0,behaviour:crate::model::ZoneBehaviour::Finish})},
|
||||
"MapAnticheat"=>{force_can_collide=false;general.zone=Some(crate::model::GameMechanicZone{mode_id:0,behaviour:crate::model::ZoneBehaviour::Anitcheat})},
|
||||
"Platform"=>general.teleport_behaviour=Some(crate::model::TeleportBehaviour::StageElement(crate::model::GameMechanicStageElement{
|
||||
@ -72,12 +81,28 @@ fn get_attributes(name:&str,can_collide:bool,velocity:Planar64Vec3,force_interse
|
||||
},
|
||||
behaviour:match &captures[2]{
|
||||
"Spawn"|"SpawnAt"=>crate::model::StageElementBehaviour::SpawnAt,
|
||||
//cancollide false so you don't hit the side
|
||||
//NOT a decoration
|
||||
"Trigger"=>{force_can_collide=false;crate::model::StageElementBehaviour::Trigger},
|
||||
"Teleport"=>{force_can_collide=false;crate::model::StageElementBehaviour::Teleport},
|
||||
"Platform"=>crate::model::StageElementBehaviour::Platform,
|
||||
_=>panic!("regex1[2] messed up bad"),
|
||||
}
|
||||
}));
|
||||
}else if let Some(captures)=lazy_regex::regex!(r"^(Force)?(Jump)(\d+)$")
|
||||
.captures(other){
|
||||
general.teleport_behaviour=Some(crate::model::TeleportBehaviour::StageElement(crate::model::GameMechanicStageElement{
|
||||
mode_id:0,
|
||||
stage_id:0,
|
||||
force:match captures.get(1){
|
||||
Some(m)=>m.as_str()=="Force",
|
||||
None=>false,
|
||||
},
|
||||
behaviour:match &captures[2]{
|
||||
"Jump"=>crate::model::StageElementBehaviour::JumpLimit(captures[3].parse::<u32>().unwrap()),
|
||||
_=>panic!("regex4[1] messed up bad"),
|
||||
}
|
||||
}));
|
||||
}else if let Some(captures)=lazy_regex::regex!(r"^Bonus(Finish|Anticheat)(\d+)$")
|
||||
.captures(other){
|
||||
force_can_collide=false;
|
||||
@ -86,39 +111,33 @@ fn get_attributes(name:&str,can_collide:bool,velocity:Planar64Vec3,force_interse
|
||||
"Anticheat"=>general.zone=Some(crate::model::GameMechanicZone{mode_id:captures[2].parse::<u32>().unwrap(),behaviour:crate::model::ZoneBehaviour::Anitcheat}),
|
||||
_=>panic!("regex2[1] messed up bad"),
|
||||
}
|
||||
}else if let Some(captures)=lazy_regex::regex!(r"^(WormholeIn)(\d+)$")
|
||||
.captures(other){
|
||||
force_can_collide=false;
|
||||
match &captures[1]{
|
||||
"WormholeIn"=>general.teleport_behaviour=Some(crate::model::TeleportBehaviour::Wormhole(crate::model::GameMechanicWormhole{destination_model_id:captures[2].parse::<u32>().unwrap()})),
|
||||
_=>panic!("regex3[1] messed up bad"),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//need some way to skip this
|
||||
if velocity!=Planar64Vec3::ZERO{
|
||||
general.booster=Some(crate::model::GameMechanicBooster{velocity});
|
||||
general.booster=Some(crate::model::GameMechanicBooster::Velocity(velocity));
|
||||
}
|
||||
match force_can_collide{
|
||||
true=>{
|
||||
match name{
|
||||
"Bounce"=>contacting.elasticity=Some(u32::MAX),
|
||||
"Surf"=>contacting.surf=Some(crate::model::ContactingSurf{}),
|
||||
"Ladder"=>contacting.ladder=Some(crate::model::ContactingLadder{sticky:true}),
|
||||
other=>{
|
||||
if let Some(captures)=lazy_regex::regex!(r"^(Jump|WormholeIn)(\d+)$")
|
||||
.captures(other){
|
||||
match &captures[1]{
|
||||
"Jump"=>general.jump_limit=Some(crate::model::GameMechanicJumpLimit{count:captures[2].parse::<u32>().unwrap()}),
|
||||
"WormholeIn"=>general.teleport_behaviour=Some(crate::model::TeleportBehaviour::Wormhole(crate::model::GameMechanicWormhole{destination_model_id:captures[2].parse::<u32>().unwrap()})),
|
||||
_=>panic!("regex3[1] messed up bad"),
|
||||
}
|
||||
}
|
||||
}
|
||||
"Bounce"=>contacting.contact_behaviour=Some(crate::model::ContactingBehaviour::Elastic(u32::MAX)),
|
||||
"Surf"=>contacting.contact_behaviour=Some(crate::model::ContactingBehaviour::Surf),
|
||||
"Ladder"=>contacting.contact_behaviour=Some(crate::model::ContactingBehaviour::Ladder(crate::model::ContactingLadder{sticky:true})),
|
||||
_=>(),
|
||||
}
|
||||
crate::model::CollisionAttributes::Contact{contacting,general}
|
||||
},
|
||||
false=>if force_intersecting
|
||||
||general.jump_limit.is_some()
|
||||
||general.booster.is_some()
|
||||
||general.zone.is_some()
|
||||
||general.teleport_behaviour.is_some()
|
||||
||intersecting.water.is_some()
|
||||
||intersecting.accelerator.is_some()
|
||||
||general.any()
|
||||
||intersecting.any()
|
||||
{
|
||||
crate::model::CollisionAttributes::Intersect{intersecting,general}
|
||||
}else{
|
||||
@ -244,16 +263,17 @@ pub fn generate_indexed_models(dom:rbx_dom_weak::WeakDom) -> crate::model::Index
|
||||
if let Some(attr)=match &object.name[..]{
|
||||
"MapStart"=>{
|
||||
spawn_point=model_transform.transform_point3(Planar64Vec3::ZERO)+Planar64Vec3::Y*5/2;
|
||||
Some(crate::model::TempIndexedAttributes::Start{mode_id:0})
|
||||
Some(crate::model::TempIndexedAttributes::Start(crate::model::TempAttrStart{mode_id:0}))
|
||||
},
|
||||
"UnorderedCheckpoint"=>Some(crate::model::TempIndexedAttributes::UnorderedCheckpoint{mode_id:0}),
|
||||
"UnorderedCheckpoint"=>Some(crate::model::TempIndexedAttributes::UnorderedCheckpoint(crate::model::TempAttrUnorderedCheckpoint{mode_id:0})),
|
||||
other=>{
|
||||
let regman=lazy_regex::regex!(r"^(BonusStart|Spawn|ForceSpawn|OrderedCheckpoint)(\d+)$");
|
||||
let regman=lazy_regex::regex!(r"^(BonusStart|Spawn|ForceSpawn|OrderedCheckpoint|WormholeOut)(\d+)$");
|
||||
if let Some(captures) = regman.captures(other) {
|
||||
match &captures[1]{
|
||||
"BonusStart"=>Some(crate::model::TempIndexedAttributes::Start{mode_id:captures[2].parse::<u32>().unwrap()}),
|
||||
"Spawn"|"ForceSpawn"=>Some(crate::model::TempIndexedAttributes::Spawn{mode_id:0,stage_id:captures[2].parse::<u32>().unwrap()}),
|
||||
"OrderedCheckpoint"=>Some(crate::model::TempIndexedAttributes::OrderedCheckpoint{mode_id:0,checkpoint_id:captures[2].parse::<u32>().unwrap()}),
|
||||
"BonusStart"=>Some(crate::model::TempIndexedAttributes::Start(crate::model::TempAttrStart{mode_id:captures[2].parse::<u32>().unwrap()})),
|
||||
"Spawn"|"ForceSpawn"=>Some(crate::model::TempIndexedAttributes::Spawn(crate::model::TempAttrSpawn{mode_id:0,stage_id:captures[2].parse::<u32>().unwrap()})),
|
||||
"OrderedCheckpoint"=>Some(crate::model::TempIndexedAttributes::OrderedCheckpoint(crate::model::TempAttrOrderedCheckpoint{mode_id:0,checkpoint_id:captures[2].parse::<u32>().unwrap()})),
|
||||
"WormholeOut"=>Some(crate::model::TempIndexedAttributes::Wormhole(crate::model::TempAttrWormhole{wormhole_id:captures[2].parse::<u32>().unwrap()})),
|
||||
_=>None,
|
||||
}
|
||||
}else{
|
||||
|
@ -931,7 +931,7 @@ impl framework::Example for GlobalState {
|
||||
let screen_size=glam::uvec2(config.width,config.height);
|
||||
|
||||
let camera=GraphicsCamera::new(screen_size,user_settings.calculate_fov(1.0,&screen_size).as_vec2());
|
||||
let camera_uniforms = camera.to_uniform_data(physics.output().adjust_mouse(&physics.next_mouse));
|
||||
let camera_uniforms = camera.to_uniform_data(physics.output().adjust_mouse(&physics::MouseState::default()));
|
||||
let camera_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("Camera"),
|
||||
contents: bytemuck::cast_slice(&camera_uniforms),
|
||||
@ -1063,6 +1063,7 @@ impl framework::Example for GlobalState {
|
||||
self.graphics.clear();
|
||||
|
||||
let mut physics=physics::PhysicsState::default();
|
||||
//physics.spawn()
|
||||
physics.game.stage_id=0;
|
||||
physics.spawn_point=spawn_point;
|
||||
physics.process_instruction(instruction::TimedInstruction{
|
||||
|
150
src/model.rs
150
src/model.rs
@ -1,4 +1,4 @@
|
||||
use crate::integer::{Planar64,Planar64Vec3,Planar64Affine3};
|
||||
use crate::integer::{Time,Planar64,Planar64Vec3,Planar64Affine3};
|
||||
pub type TextureCoordinate=glam::Vec2;
|
||||
pub type Color4=glam::Vec4;
|
||||
#[derive(Clone,Hash,PartialEq,Eq)]
|
||||
@ -50,53 +50,63 @@ pub struct IndexedModelInstances{
|
||||
}
|
||||
//stage description referencing flattened ids is spooky, but the map loading is meant to be deterministic.
|
||||
pub struct ModeDescription{
|
||||
pub start:u32,//start=model_id
|
||||
pub spawns:Vec<u32>,//spawns[spawn_id]=model_id
|
||||
pub ordered_checkpoints:Vec<u32>,//ordered_checkpoints[checkpoint_id]=model_id
|
||||
pub unordered_checkpoints:Vec<u32>,//unordered_checkpoints[checkpoint_id]=model_id
|
||||
pub start:usize,//start=model_id
|
||||
pub spawns:Vec<usize>,//spawns[spawn_id]=model_id
|
||||
pub ordered_checkpoints:Vec<usize>,//ordered_checkpoints[checkpoint_id]=model_id
|
||||
pub unordered_checkpoints:Vec<usize>,//unordered_checkpoints[checkpoint_id]=model_id
|
||||
pub spawn_from_stage_id:std::collections::HashMap::<u32,usize>,
|
||||
pub ordered_checkpoint_from_checkpoint_id:std::collections::HashMap::<u32,usize>,
|
||||
}
|
||||
impl ModeDescription{
|
||||
pub fn get_spawn_model_id(&self,stage_id:u32)->Option<&u32>{
|
||||
if let Some(&spawn)=self.spawn_from_stage_id.get(&stage_id){
|
||||
self.spawns.get(spawn)
|
||||
}else{
|
||||
None
|
||||
}
|
||||
pub fn get_spawn_model_id(&self,stage_id:u32)->Option<&usize>{
|
||||
self.spawns.get(*self.spawn_from_stage_id.get(&stage_id)?)
|
||||
}
|
||||
pub fn get_ordered_checkpoint_model_id(&self,checkpoint_id:u32)->Option<&u32>{
|
||||
if let Some(&checkpoint)=self.ordered_checkpoint_from_checkpoint_id.get(&checkpoint_id){
|
||||
self.ordered_checkpoints.get(checkpoint)
|
||||
}else{
|
||||
None
|
||||
}
|
||||
pub fn get_ordered_checkpoint_model_id(&self,checkpoint_id:u32)->Option<&usize>{
|
||||
self.ordered_checkpoints.get(*self.ordered_checkpoint_from_checkpoint_id.get(&checkpoint_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 TempAttrOrderedCheckpoint{
|
||||
pub mode_id:u32,
|
||||
pub checkpoint_id:u32,
|
||||
}
|
||||
#[derive(Clone)]
|
||||
pub struct TempAttrUnorderedCheckpoint{
|
||||
pub mode_id:u32,
|
||||
}
|
||||
#[derive(Clone)]
|
||||
pub struct TempAttrWormhole{
|
||||
pub wormhole_id:u32,
|
||||
}
|
||||
pub enum TempIndexedAttributes{
|
||||
Start{
|
||||
mode_id:u32,
|
||||
},
|
||||
Spawn{
|
||||
mode_id:u32,
|
||||
stage_id:u32,
|
||||
},
|
||||
OrderedCheckpoint{
|
||||
mode_id:u32,
|
||||
checkpoint_id:u32,
|
||||
},
|
||||
UnorderedCheckpoint{
|
||||
mode_id:u32,
|
||||
},
|
||||
Start(TempAttrStart),
|
||||
Spawn(TempAttrSpawn),
|
||||
OrderedCheckpoint(TempAttrOrderedCheckpoint),
|
||||
UnorderedCheckpoint(TempAttrUnorderedCheckpoint),
|
||||
Wormhole(TempAttrWormhole),
|
||||
}
|
||||
|
||||
//you have this effect while in contact
|
||||
#[derive(Clone)]
|
||||
pub struct ContactingSurf{}
|
||||
#[derive(Clone)]
|
||||
pub struct ContactingLadder{
|
||||
pub sticky:bool
|
||||
}
|
||||
#[derive(Clone)]
|
||||
pub enum ContactingBehaviour{
|
||||
Surf,
|
||||
Ladder(ContactingLadder),
|
||||
Elastic(u32),//[1/2^32,1] 0=None (elasticity+1)/2^32
|
||||
}
|
||||
//you have this effect while intersecting
|
||||
#[derive(Clone)]
|
||||
pub struct IntersectingWater{
|
||||
@ -104,18 +114,37 @@ pub struct IntersectingWater{
|
||||
pub density:Planar64,
|
||||
pub current:Planar64Vec3,
|
||||
}
|
||||
#[derive(Clone)]
|
||||
pub struct IntersectingAccelerator{
|
||||
pub acceleration:Planar64Vec3
|
||||
}
|
||||
//All models can be given these attributes
|
||||
#[derive(Clone)]
|
||||
pub struct GameMechanicJumpLimit{
|
||||
pub count:u32,
|
||||
pub struct GameMechanicAccelerator{
|
||||
pub acceleration:Planar64Vec3
|
||||
}
|
||||
#[derive(Clone)]
|
||||
pub struct GameMechanicBooster{
|
||||
pub velocity:Planar64Vec3,
|
||||
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)]
|
||||
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)]
|
||||
pub enum GameMechanicSetTrajectory{
|
||||
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
|
||||
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
|
||||
},
|
||||
TrajectoryTargetPoint{//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
|
||||
DotVelocity{direction:Planar64Vec3,dot:Planar64},//set your velocity in a specific direction without touching other directions
|
||||
}
|
||||
#[derive(Clone)]
|
||||
pub enum ZoneBehaviour{
|
||||
@ -130,10 +159,10 @@ pub struct GameMechanicZone{
|
||||
pub behaviour:ZoneBehaviour,
|
||||
}
|
||||
// enum TrapCondition{
|
||||
// FasterThan(i64),
|
||||
// SlowerThan(i64),
|
||||
// InRange(i64,i64),
|
||||
// OutsideRange(i64,i64),
|
||||
// FasterThan(Planar64),
|
||||
// SlowerThan(Planar64),
|
||||
// InRange(Planar64,Planar64),
|
||||
// OutsideRange(Planar64,Planar64),
|
||||
// }
|
||||
#[derive(Clone)]
|
||||
pub enum StageElementBehaviour{
|
||||
@ -142,6 +171,7 @@ pub enum StageElementBehaviour{
|
||||
Trigger,
|
||||
Teleport,
|
||||
Platform,
|
||||
JumpLimit(u32),
|
||||
//Speedtrap(TrapCondition),//Acts as a trigger with a speed condition
|
||||
}
|
||||
#[derive(Clone)]
|
||||
@ -164,24 +194,42 @@ pub enum TeleportBehaviour{
|
||||
StageElement(GameMechanicStageElement),
|
||||
Wormhole(GameMechanicWormhole),
|
||||
}
|
||||
//attributes listed in order of handling
|
||||
#[derive(Default,Clone)]
|
||||
pub struct GameMechanicAttributes{
|
||||
pub jump_limit:Option<GameMechanicJumpLimit>,
|
||||
pub booster:Option<GameMechanicBooster>,
|
||||
pub zone:Option<GameMechanicZone>,
|
||||
pub booster:Option<GameMechanicBooster>,
|
||||
pub trajectory:Option<GameMechanicSetTrajectory>,
|
||||
pub teleport_behaviour:Option<TeleportBehaviour>,
|
||||
pub accelerator:Option<GameMechanicAccelerator>,
|
||||
}
|
||||
impl GameMechanicAttributes{
|
||||
pub fn any(&self)->bool{
|
||||
self.booster.is_some()
|
||||
||self.trajectory.is_some()
|
||||
||self.zone.is_some()
|
||||
||self.teleport_behaviour.is_some()
|
||||
||self.accelerator.is_some()
|
||||
}
|
||||
}
|
||||
#[derive(Default,Clone)]
|
||||
pub struct ContactingAttributes{
|
||||
pub elasticity:Option<u32>,//[1/2^32,1] 0=None (elasticity+1)/2^32
|
||||
//friction?
|
||||
pub surf:Option<ContactingSurf>,
|
||||
pub ladder:Option<ContactingLadder>,
|
||||
pub contact_behaviour:Option<ContactingBehaviour>,
|
||||
}
|
||||
impl ContactingAttributes{
|
||||
pub fn any(&self)->bool{
|
||||
self.contact_behaviour.is_some()
|
||||
}
|
||||
}
|
||||
#[derive(Default,Clone)]
|
||||
pub struct IntersectingAttributes{
|
||||
pub water:Option<IntersectingWater>,
|
||||
pub accelerator:Option<IntersectingAccelerator>,
|
||||
}
|
||||
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{
|
||||
|
832
src/physics.rs
832
src/physics.rs
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user