From 7e1cf7041a958f4a2d25dbc6edcc7d2465a48c0c Mon Sep 17 00:00:00 2001 From: Quaternions Date: Sat, 14 Oct 2023 17:56:35 -0700 Subject: [PATCH] GameMechanics: make invalid states unrepresentable --- src/load_roblox.rs | 13 ++++++------- src/model.rs | 16 ++++++++++++---- src/physics.rs | 14 ++++++++++---- 3 files changed, 28 insertions(+), 15 deletions(-) diff --git a/src/load_roblox.rs b/src/load_roblox.rs index e22299e..6564b49 100644 --- a/src/load_roblox.rs +++ b/src/load_roblox.rs @@ -54,16 +54,16 @@ fn get_attributes(name:&str,can_collide:bool,velocity:Planar64Vec3,force_interse "Accelerator"=>{force_can_collide=false;intersecting.accelerator=Some(crate::model::IntersectingAccelerator{acceleration: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.stage_element=Some(crate::model::GameMechanicStageElement{ + "Platform"=>general.teleport_behaviour=Some(crate::model::TeleportBehaviour::StageElement(crate::model::GameMechanicStageElement{ mode_id:0, stage_id:0, force:false, behaviour:crate::model::StageElementBehaviour::Platform, - }), + })), other=>{ if let Some(captures)=lazy_regex::regex!(r"^(Force)?(Spawn|SpawnAt|Trigger|Teleport|Platform)(\d+)$") .captures(other){ - general.stage_element=Some(crate::model::GameMechanicStageElement{ + general.teleport_behaviour=Some(crate::model::TeleportBehaviour::StageElement(crate::model::GameMechanicStageElement{ mode_id:0, stage_id:captures[3].parse::().unwrap(), force:match captures.get(1){ @@ -77,7 +77,7 @@ fn get_attributes(name:&str,can_collide:bool,velocity:Planar64Vec3,force_interse "Platform"=>crate::model::StageElementBehaviour::Platform, _=>panic!("regex1[2] messed up bad"), } - }) + })); }else if let Some(captures)=lazy_regex::regex!(r"^Bonus(Finish|Anticheat)(\d+)$") .captures(other){ force_can_collide=false; @@ -104,7 +104,7 @@ fn get_attributes(name:&str,can_collide:bool,velocity:Planar64Vec3,force_interse .captures(other){ match &captures[1]{ "Jump"=>general.jump_limit=Some(crate::model::GameMechanicJumpLimit{count:captures[2].parse::().unwrap()}), - "WormholeIn"=>general.wormhole=Some(crate::model::GameMechanicWormhole{model_id:captures[2].parse::().unwrap()}), + "WormholeIn"=>general.teleport_behaviour=Some(crate::model::TeleportBehaviour::Wormhole(crate::model::GameMechanicWormhole{destination_model_id:captures[2].parse::().unwrap()})), _=>panic!("regex3[1] messed up bad"), } } @@ -116,8 +116,7 @@ fn get_attributes(name:&str,can_collide:bool,velocity:Planar64Vec3,force_interse ||general.jump_limit.is_some() ||general.booster.is_some() ||general.zone.is_some() - ||general.stage_element.is_some() - ||general.wormhole.is_some() + ||general.teleport_behaviour.is_some() ||intersecting.water.is_some() ||intersecting.accelerator.is_some() { diff --git a/src/model.rs b/src/model.rs index b783846..802dee4 100644 --- a/src/model.rs +++ b/src/model.rs @@ -152,16 +152,24 @@ pub struct GameMechanicStageElement{ pub behaviour:StageElementBehaviour } #[derive(Clone)] -pub struct GameMechanicWormhole{//(position,angles)*=origin.transform.inverse()*destination.transform - pub model_id:u32, +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)] +pub enum TeleportBehaviour{ + StageElement(GameMechanicStageElement), + Wormhole(GameMechanicWormhole), } #[derive(Default,Clone)] pub struct GameMechanicAttributes{ pub jump_limit:Option, pub booster:Option, pub zone:Option, - pub stage_element:Option, - pub wormhole:Option,//stage_element and wormhole are in conflict + pub teleport_behaviour:Option, } #[derive(Default,Clone)] pub struct ContactingAttributes{ diff --git a/src/physics.rs b/src/physics.rs index 005ab00..7c38ce1 100644 --- a/src/physics.rs +++ b/src/physics.rs @@ -1106,8 +1106,8 @@ impl crate::instruction::InstructionConsumer for PhysicsStat } //check ground self.contacts.insert(c.model,c); - match &general.stage_element{ - Some(stage_element)=>{ + match &general.teleport_behaviour{ + Some(crate::model::TeleportBehaviour::StageElement(stage_element))=>{ if stage_element.force||self.game.stage_id for PhysicsStat crate::model::StageElementBehaviour::Platform=>(), } }, + Some(crate::model::TeleportBehaviour::Wormhole(wormhole))=>{ + //telefart + } None=>(), } //flatten v @@ -1154,8 +1157,8 @@ impl crate::instruction::InstructionConsumer for PhysicsStat PhysicsCollisionAttributes::Intersect{intersecting,general}=>{ //I think that setting the velocity to 0 was preventing surface contacts from entering an infinite loop self.intersects.insert(c.model,c); - match &general.stage_element{ - Some(stage_element)=>{ + match &general.teleport_behaviour{ + Some(crate::model::TeleportBehaviour::StageElement(stage_element))=>{ if stage_element.force||self.game.stage_id for PhysicsStat crate::model::StageElementBehaviour::Platform=>(), } }, + Some(crate::model::TeleportBehaviour::Wormhole(wormhole))=>{ + //telefart + } None=>(), } },