wip make it work

This commit is contained in:
Quaternions 2024-01-30 20:25:07 -08:00
parent 20bbb6924e
commit 56859d4e0c

View File

@ -1,5 +1,9 @@
use std::collections::HashMap;
use crate::primitives; use crate::primitives;
use strafesnet_common::gameplay_attributes; use strafesnet_common::map;
use strafesnet_common::model;
use strafesnet_common::gameplay_modes;
use strafesnet_common::gameplay_attributes as attr;
use strafesnet_common::integer::{Planar64,Planar64Vec3,Planar64Mat3,Planar64Affine3}; use strafesnet_common::integer::{Planar64,Planar64Vec3,Planar64Mat3,Planar64Affine3};
fn class_is_a(class: &str, superclass: &str) -> bool { fn class_is_a(class: &str, superclass: &str) -> bool {
@ -40,91 +44,133 @@ fn planar64_affine3_from_roblox(cf:&rbx_dom_weak::types::CFrame,size:&rbx_dom_we
Planar64Vec3::try_from([cf.position.x,cf.position.y,cf.position.z]).unwrap() Planar64Vec3::try_from([cf.position.x,cf.position.y,cf.position.z]).unwrap()
) )
} }
fn get_attributes(name:&str,can_collide:bool,velocity:Planar64Vec3,force_intersecting:bool)->model::CollisionAttributes{ #[derive(Default)]
let mut general=model::GameMechanicAttributes::default(); struct ModesBuilder{
let mut intersecting=model::IntersectingAttributes::default(); modes:HashMap<gameplay_modes::ModeId,gameplay_modes::Mode>,
let mut contacting=model::ContactingAttributes::default(); mode_updates:Vec<(gameplay_modes::ModeId,gameplay_modes::ModeUpdate)>,
}
impl ModesBuilder{
fn insert_mode(&mut self,mode_id:gameplay_modes::ModeId,mode:gameplay_modes::Mode){
assert!(self.modes.insert(mode_id,mode).is_none(),"Cannot replace existing mode");
}
fn push_mode_update(&mut self,mode_id:gameplay_modes::ModeId,mode_update:gameplay_modes::ModeUpdate){
self.mode_updates.push((mode_id,mode_update));
}
}
fn get_attributes(modes_builder:&mut ModesBuilder,model_id:model::ModelId,name:&str,can_collide:bool,velocity:Planar64Vec3,force_intersecting:bool)->attr::CollisionAttributes{
let mut general=attr::GeneralAttributes::default();
let mut intersecting=attr::IntersectingAttributes::default();
let mut contacting=attr::ContactingAttributes::default();
let mut force_can_collide=can_collide; let mut force_can_collide=can_collide;
match name{ match name{
"Water"=>{ "Water"=>{
force_can_collide=false; force_can_collide=false;
//TODO: read stupid CustomPhysicalProperties //TODO: read stupid CustomPhysicalProperties
intersecting.water=Some(model::IntersectingWater{density:Planar64::ONE,viscosity:Planar64::ONE/10,velocity}); intersecting.water=Some(attr::IntersectingWater{density:Planar64::ONE,viscosity:Planar64::ONE/10,velocity});
}, },
"Accelerator"=>{ "Accelerator"=>{
//although the new game supports collidable accelerators, this is a roblox compatability map loader //although the new game supports collidable accelerators, this is a roblox compatability map loader
force_can_collide=false; force_can_collide=false;
general.accelerator=Some(model::GameMechanicAccelerator{acceleration:velocity}); general.accelerator=Some(attr::Accelerator{acceleration:velocity});
}, },
// "UnorderedCheckpoint"=>general.teleport_behaviour=Some(model::TeleportBehaviour::StageElement(model::GameMechanicStageElement{ // "UnorderedCheckpoint"=>general.teleport_behaviour=Some(model::TeleportBehaviour::StageElement(attr::StageElement{
// mode_id:0, // mode_id:0,
// stage_id:0, // stage_id:0,
// force:false, // force:false,
// behaviour:model::StageElementBehaviour::Unordered // behaviour:model::StageElementBehaviour::Unordered
// })), // })),
"SetVelocity"=>general.trajectory=Some(model::GameMechanicSetTrajectory::Velocity(velocity)), "SetVelocity"=>general.trajectory=Some(attr::SetTrajectory::Velocity(velocity)),
"MapFinish"=>{force_can_collide=false;general.zone=Some(model::GameMechanicZone{mode_id:0,behaviour:model::ZoneBehaviour::Finish})}, "MapFinish"=>{
"MapAnticheat"=>{force_can_collide=false;general.zone=Some(model::GameMechanicZone{mode_id:0,behaviour:model::ZoneBehaviour::Anitcheat})}, force_can_collide=false;
"Platform"=>general.teleport_behaviour=Some(model::TeleportBehaviour::StageElement(model::GameMechanicStageElement{ modes_builder.push_mode_update(
mode_id:0, gameplay_modes::ModeId::MAIN,
stage_id:0, gameplay_modes::ModeUpdate::zone(
force:false, model_id,
behaviour:model::StageElementBehaviour::Platform, gameplay_modes::Zone::Finish,
})), ),
);
},
"MapAnticheat"=>{
force_can_collide=false;
modes_builder.push_mode_update(
gameplay_modes::ModeId::MAIN,
gameplay_modes::ModeUpdate::zone(
model_id,
gameplay_modes::Zone::Anticheat,
),
);
},
"Platform"=>{
modes_builder.push_mode_update(
gameplay_modes::ModeId::MAIN,
gameplay_modes::ModeUpdate::element(
model_id,
gameplay_modes::StageElement::new(0,false,gameplay_modes::StageElementBehaviour::Platform),//roblox does not know which stage the platform belongs to
),
);
},
other=>{ other=>{
if let Some(captures)=lazy_regex::regex!(r"^(Force)?(Spawn|SpawnAt|Trigger|Teleport|Platform)(\d+)$") if let Some(captures)=lazy_regex::regex!(r"^(Force)?(Spawn|SpawnAt|Trigger|Teleport|Platform)(\d+)$")
.captures(other){ .captures(other){
general.teleport_behaviour=Some(model::TeleportBehaviour::StageElement(model::GameMechanicStageElement{ modes_builder.push_mode_update(
mode_id:0, gameplay_modes::ModeId::MAIN,
stage_id:captures[3].parse::<u32>().unwrap(), gameplay_modes::ModeUpdate::element(
force:match captures.get(1){ model_id,
gameplay_modes::StageElement::new(
//stage_id:
captures[3].parse::<u32>().unwrap(),
//force:
match captures.get(1){
Some(m)=>m.as_str()=="Force", Some(m)=>m.as_str()=="Force",
None=>false, None=>false,
}, },
behaviour:match &captures[2]{ //behaviour:
"Spawn"|"SpawnAt"=>model::StageElementBehaviour::SpawnAt, match &captures[2]{
"Spawn"|"SpawnAt"=>gameplay_modes::StageElementBehaviour::SpawnAt,
//cancollide false so you don't hit the side //cancollide false so you don't hit the side
//NOT a decoration //NOT a decoration
"Trigger"=>{force_can_collide=false;model::StageElementBehaviour::Trigger}, "Trigger"=>{force_can_collide=false;gameplay_modes::StageElementBehaviour::Trigger},
"Teleport"=>{force_can_collide=false;model::StageElementBehaviour::Teleport}, "Teleport"=>{force_can_collide=false;gameplay_modes::StageElementBehaviour::Teleport},
"Platform"=>model::StageElementBehaviour::Platform, "Platform"=>gameplay_modes::StageElementBehaviour::Platform,
_=>panic!("regex1[2] messed up bad"), _=>panic!("regex1[2] messed up bad"),
}
}));
}else if let Some(captures)=lazy_regex::regex!(r"^(Force)?(Jump)(\d+)$")
.captures(other){
general.teleport_behaviour=Some(model::TeleportBehaviour::StageElement(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"=>model::StageElementBehaviour::JumpLimit(captures[3].parse::<u32>().unwrap()), ),
_=>panic!("regex4[1] messed up bad"), );
} }else if let Some(captures)=lazy_regex::regex!(r"^Jump(\d+)$")
})); .captures(other){
modes_builder.push_mode_update(
gameplay_modes::ModeId::MAIN,
gameplay_modes::ModeUpdate::jump_limit(
model_id,
//jump_limit:
captures[1].parse::<u32>().unwrap()
),
);
}else if let Some(captures)=lazy_regex::regex!(r"^Bonus(Finish|Anticheat)(\d+)$") }else if let Some(captures)=lazy_regex::regex!(r"^Bonus(Finish|Anticheat)(\d+)$")
.captures(other){ .captures(other){
force_can_collide=false; force_can_collide=false;
modes_builder.push_mode_update(
gameplay_modes::ModeId::mode(captures[2].parse::<u32>().unwrap()),
gameplay_modes::ModeUpdate::zone(
model_id,
//zone:
match &captures[1]{ match &captures[1]{
"Finish"=>general.zone=Some(model::GameMechanicZone{mode_id:captures[2].parse::<u32>().unwrap(),behaviour:model::ZoneBehaviour::Finish}), "Finish"=>gameplay_modes::Zone::Finish,
"Anticheat"=>general.zone=Some(model::GameMechanicZone{mode_id:captures[2].parse::<u32>().unwrap(),behaviour:model::ZoneBehaviour::Anitcheat}), "Anticheat"=>gameplay_modes::Zone::Anticheat,
_=>panic!("regex2[1] messed up bad"), _=>panic!("regex2[1] messed up bad"),
} },
}else if let Some(captures)=lazy_regex::regex!(r"^(WormholeIn)(\d+)$") ),
);
}else if let Some(captures)=lazy_regex::regex!(r"^WormholeIn(\d+)$")
.captures(other){ .captures(other){
force_can_collide=false; force_can_collide=false;
match &captures[1]{ general.wormhole=Some(attr::Wormhole{destination_model_id:captures[1].parse::<u32>().unwrap()});
"WormholeIn"=>general.teleport_behaviour=Some(model::TeleportBehaviour::Wormhole(model::GameMechanicWormhole{destination_model_id:captures[2].parse::<u32>().unwrap()})),
_=>panic!("regex3[1] messed up bad"),
}
} }
// else if let Some(captures)=lazy_regex::regex!(r"^(OrderedCheckpoint)(\d+)$") // else if let Some(captures)=lazy_regex::regex!(r"^(OrderedCheckpoint)(\d+)$")
// .captures(other){ // .captures(other){
// match &captures[1]{ // match &captures[1]{
// "OrderedCheckpoint"=>general.checkpoint=Some(model::GameMechanicCheckpoint::Ordered{mode_id:0,checkpoint_id:captures[2].parse::<u32>().unwrap()}), // "OrderedCheckpoint"=>general.checkpoint=Some(attr::Checkpoint::Ordered{mode_id:0,checkpoint_id:captures[2].parse::<u32>().unwrap()}),
// _=>panic!("regex3[1] messed up bad"), // _=>panic!("regex3[1] messed up bad"),
// } // }
// } // }
@ -132,25 +178,25 @@ fn get_attributes(name:&str,can_collide:bool,velocity:Planar64Vec3,force_interse
} }
//need some way to skip this //need some way to skip this
if velocity!=Planar64Vec3::ZERO{ if velocity!=Planar64Vec3::ZERO{
general.booster=Some(model::GameMechanicBooster::Velocity(velocity)); general.booster=Some(attr::Booster::Velocity(velocity));
} }
match force_can_collide{ match force_can_collide{
true=>{ true=>{
match name{ match name{
"Bounce"=>contacting.contact_behaviour=Some(model::ContactingBehaviour::Elastic(u32::MAX)), "Bounce"=>contacting.contact_behaviour=Some(attr::ContactingBehaviour::Elastic(u32::MAX)),
"Surf"=>contacting.contact_behaviour=Some(model::ContactingBehaviour::Surf), "Surf"=>contacting.contact_behaviour=Some(attr::ContactingBehaviour::Surf),
"Ladder"=>contacting.contact_behaviour=Some(model::ContactingBehaviour::Ladder(model::ContactingLadder{sticky:true})), "Ladder"=>contacting.contact_behaviour=Some(attr::ContactingBehaviour::Ladder(attr::ContactingLadder{sticky:true})),
_=>(), _=>(),
} }
model::CollisionAttributes::Contact{contacting,general} attr::CollisionAttributes::Contact{contacting,general}
}, },
false=>if force_intersecting false=>if force_intersecting
||general.any() ||general.any()
||intersecting.any() ||intersecting.any()
{ {
model::CollisionAttributes::Intersect{intersecting,general} attr::CollisionAttributes::Intersect{intersecting,general}
}else{ }else{
model::CollisionAttributes::Decoration attr::CollisionAttributes::Decoration
}, },
} }
} }
@ -233,7 +279,7 @@ enum RobloxBasePartDescription{
Wedge(RobloxWedgeDescription), Wedge(RobloxWedgeDescription),
CornerWedge(RobloxCornerWedgeDescription), CornerWedge(RobloxCornerWedgeDescription),
} }
pub fn generate_indexed_models(dom:rbx_dom_weak::WeakDom) -> model::IndexedModelInstances{ pub fn convert(dom:rbx_dom_weak::WeakDom)->map::Map{
//IndexedModelInstances includes textures //IndexedModelInstances includes textures
let mut spawn_point=Planar64Vec3::ZERO; let mut spawn_point=Planar64Vec3::ZERO;
@ -506,7 +552,7 @@ pub fn generate_indexed_models(dom:rbx_dom_weak::WeakDom) -> model::IndexedModel
}); });
model_id model_id
}; };
indexed_models[model_id].instances.push(model::ModelInstance { indexed_models[model_id].instances.push(model::Model{
transform:model_transform, transform:model_transform,
color:glam::vec4(color3.r as f32/255f32, color3.g as f32/255f32, color3.b as f32/255f32, 1.0-*transparency), color:glam::vec4(color3.r as f32/255f32, color3.g as f32/255f32, color3.b as f32/255f32, 1.0-*transparency),
attributes:get_attributes(&object.name,*can_collide,Planar64Vec3::try_from([velocity.x,velocity.y,velocity.z]).unwrap(),force_intersecting), attributes:get_attributes(&object.name,*can_collide,Planar64Vec3::try_from([velocity.x,velocity.y,velocity.z]).unwrap(),force_intersecting),