GameMechanics: make invalid states unrepresentable

This commit is contained in:
Quaternions 2023-10-14 17:56:35 -07:00
parent 50543ffcea
commit 7e1cf7041a
3 changed files with 28 additions and 15 deletions

View File

@ -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})}, "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})}, "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})}, "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, mode_id:0,
stage_id:0, stage_id:0,
force:false, force:false,
behaviour:crate::model::StageElementBehaviour::Platform, behaviour:crate::model::StageElementBehaviour::Platform,
}), })),
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.stage_element=Some(crate::model::GameMechanicStageElement{ general.teleport_behaviour=Some(crate::model::TeleportBehaviour::StageElement(crate::model::GameMechanicStageElement{
mode_id:0, mode_id:0,
stage_id:captures[3].parse::<u32>().unwrap(), stage_id:captures[3].parse::<u32>().unwrap(),
force:match captures.get(1){ 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, "Platform"=>crate::model::StageElementBehaviour::Platform,
_=>panic!("regex1[2] messed up bad"), _=>panic!("regex1[2] messed up bad"),
} }
}) }));
}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;
@ -104,7 +104,7 @@ fn get_attributes(name:&str,can_collide:bool,velocity:Planar64Vec3,force_interse
.captures(other){ .captures(other){
match &captures[1]{ match &captures[1]{
"Jump"=>general.jump_limit=Some(crate::model::GameMechanicJumpLimit{count:captures[2].parse::<u32>().unwrap()}), "Jump"=>general.jump_limit=Some(crate::model::GameMechanicJumpLimit{count:captures[2].parse::<u32>().unwrap()}),
"WormholeIn"=>general.wormhole=Some(crate::model::GameMechanicWormhole{model_id: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"), _=>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.jump_limit.is_some()
||general.booster.is_some() ||general.booster.is_some()
||general.zone.is_some() ||general.zone.is_some()
||general.stage_element.is_some() ||general.teleport_behaviour.is_some()
||general.wormhole.is_some()
||intersecting.water.is_some() ||intersecting.water.is_some()
||intersecting.accelerator.is_some() ||intersecting.accelerator.is_some()
{ {

View File

@ -152,16 +152,24 @@ pub struct GameMechanicStageElement{
pub behaviour:StageElementBehaviour pub behaviour:StageElementBehaviour
} }
#[derive(Clone)] #[derive(Clone)]
pub struct GameMechanicWormhole{//(position,angles)*=origin.transform.inverse()*destination.transform pub struct GameMechanicWormhole{
pub model_id:u32, //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)] #[derive(Default,Clone)]
pub struct GameMechanicAttributes{ pub struct GameMechanicAttributes{
pub jump_limit:Option<GameMechanicJumpLimit>, pub jump_limit:Option<GameMechanicJumpLimit>,
pub booster:Option<GameMechanicBooster>, pub booster:Option<GameMechanicBooster>,
pub zone:Option<GameMechanicZone>, pub zone:Option<GameMechanicZone>,
pub stage_element:Option<GameMechanicStageElement>, pub teleport_behaviour:Option<TeleportBehaviour>,
pub wormhole:Option<GameMechanicWormhole>,//stage_element and wormhole are in conflict
} }
#[derive(Default,Clone)] #[derive(Default,Clone)]
pub struct ContactingAttributes{ pub struct ContactingAttributes{

View File

@ -1106,8 +1106,8 @@ impl crate::instruction::InstructionConsumer<PhysicsInstruction> for PhysicsStat
} }
//check ground //check ground
self.contacts.insert(c.model,c); self.contacts.insert(c.model,c);
match &general.stage_element{ match &general.teleport_behaviour{
Some(stage_element)=>{ Some(crate::model::TeleportBehaviour::StageElement(stage_element))=>{
if stage_element.force||self.game.stage_id<stage_element.stage_id{ if stage_element.force||self.game.stage_id<stage_element.stage_id{
self.game.stage_id=stage_element.stage_id; self.game.stage_id=stage_element.stage_id;
} }
@ -1133,6 +1133,9 @@ impl crate::instruction::InstructionConsumer<PhysicsInstruction> for PhysicsStat
crate::model::StageElementBehaviour::Platform=>(), crate::model::StageElementBehaviour::Platform=>(),
} }
}, },
Some(crate::model::TeleportBehaviour::Wormhole(wormhole))=>{
//telefart
}
None=>(), None=>(),
} }
//flatten v //flatten v
@ -1154,8 +1157,8 @@ impl crate::instruction::InstructionConsumer<PhysicsInstruction> for PhysicsStat
PhysicsCollisionAttributes::Intersect{intersecting,general}=>{ PhysicsCollisionAttributes::Intersect{intersecting,general}=>{
//I think that setting the velocity to 0 was preventing surface contacts from entering an infinite loop //I think that setting the velocity to 0 was preventing surface contacts from entering an infinite loop
self.intersects.insert(c.model,c); self.intersects.insert(c.model,c);
match &general.stage_element{ match &general.teleport_behaviour{
Some(stage_element)=>{ Some(crate::model::TeleportBehaviour::StageElement(stage_element))=>{
if stage_element.force||self.game.stage_id<stage_element.stage_id{ if stage_element.force||self.game.stage_id<stage_element.stage_id{
self.game.stage_id=stage_element.stage_id; self.game.stage_id=stage_element.stage_id;
} }
@ -1181,6 +1184,9 @@ impl crate::instruction::InstructionConsumer<PhysicsInstruction> for PhysicsStat
crate::model::StageElementBehaviour::Platform=>(), crate::model::StageElementBehaviour::Platform=>(),
} }
}, },
Some(crate::model::TeleportBehaviour::Wormhole(wormhole))=>{
//telefart
}
None=>(), None=>(),
} }
}, },