rethink ordered checkpoints - do not support non-teleporting (backtracking)

This commit is contained in:
Quaternions 2023-11-03 18:01:01 -07:00
parent d374a3d4c6
commit 2a033b87e0
2 changed files with 39 additions and 13 deletions

View File

@ -176,7 +176,11 @@ pub enum StageElementBehaviour{
//Note that all stage elements act like this for the next stage. //Note that all stage elements act like this for the next stage.
Checkpoint, Checkpoint,
//OrderedCheckpoint. You must pass through all of these in ascending order. //OrderedCheckpoint. You must pass through all of these in ascending order.
Ordered(u32), //If you hit them out of order it acts like a trigger.
//Do not support backtracking at all for now.
Ordered{
checkpoint_id:u32,
},
//UnorderedCheckpoint. You must pass through all of these in any order. //UnorderedCheckpoint. You must pass through all of these in any order.
Unordered, Unordered,
//If you get reset by a jump limit //If you get reset by a jump limit
@ -208,7 +212,6 @@ pub enum TeleportBehaviour{
pub struct GameMechanicAttributes{ pub struct GameMechanicAttributes{
pub zone:Option<GameMechanicZone>, pub zone:Option<GameMechanicZone>,
pub booster:Option<GameMechanicBooster>, pub booster:Option<GameMechanicBooster>,
pub checkpoint:Option<GameMechanicCheckpoint>,
pub trajectory:Option<GameMechanicSetTrajectory>, pub trajectory:Option<GameMechanicSetTrajectory>,
pub teleport_behaviour:Option<TeleportBehaviour>, pub teleport_behaviour:Option<TeleportBehaviour>,
pub accelerator:Option<GameMechanicAccelerator>, pub accelerator:Option<GameMechanicAccelerator>,
@ -217,7 +220,6 @@ impl GameMechanicAttributes{
pub fn any(&self)->bool{ pub fn any(&self)->bool{
self.zone.is_some() self.zone.is_some()
||self.booster.is_some() ||self.booster.is_some()
||self.checkpoint.is_some()
||self.trajectory.is_some() ||self.trajectory.is_some()
||self.teleport_behaviour.is_some() ||self.teleport_behaviour.is_some()
||self.accelerator.is_some() ||self.accelerator.is_some()

View File

@ -1120,9 +1120,13 @@ fn teleport_to_spawn(body:&mut Body,touching:&mut TouchingState,style:&StyleModi
} }
fn run_teleport_behaviour(teleport_behaviour:&Option<crate::model::TeleportBehaviour>,game:&mut GameMechanicsState,models:&PhysicsModels,modes:&Modes,style:&StyleModifiers,touching:&mut TouchingState,body:&mut Body,model_id:usize)->Option<MoveState>{ fn run_teleport_behaviour(teleport_behaviour:&Option<crate::model::TeleportBehaviour>,game:&mut GameMechanicsState,models:&PhysicsModels,modes:&Modes,style:&StyleModifiers,touching:&mut TouchingState,body:&mut Body,model_id:usize)->Option<MoveState>{
//TODO: jump count and checkpoints are always reset on teleport.
//Map makers are expected to use tools to prevent
//multi-boosting on JumpLimit boosters such as spawning into a SetVelocity
match teleport_behaviour{ match teleport_behaviour{
Some(crate::model::TeleportBehaviour::StageElement(stage_element))=>{ Some(crate::model::TeleportBehaviour::StageElement(stage_element))=>{
if stage_element.force||game.stage_id<stage_element.stage_id{ if stage_element.force||game.stage_id<stage_element.stage_id{
//TODO: check if all checkpoints are complete up to destination stage id, otherwise set to checkpoint completion stage it
game.stage_id=stage_element.stage_id; game.stage_id=stage_element.stage_id;
} }
match &stage_element.behaviour{ match &stage_element.behaviour{
@ -1133,21 +1137,41 @@ fn run_teleport_behaviour(teleport_behaviour:&Option<crate::model::TeleportBehav
teleport_to_spawn(body,touching,style,modes.get_mode(stage_element.mode_id)?,models,game.stage_id) teleport_to_spawn(body,touching,style,modes.get_mode(stage_element.mode_id)?,models,game.stage_id)
}, },
crate::model::StageElementBehaviour::Platform=>None, crate::model::StageElementBehaviour::Platform=>None,
&crate::model::StageElementBehaviour::Checkpoint=>{
// let mode=modes.get_mode(stage_element.mode_id)?;
// if mode.ordered_checkpoint_id.map_or(true,|id|id<game.next_ordered_checkpoint_id)
// &&mode.unordered_checkpoint_count<=game.unordered_checkpoints.len() as u32{
// //pass
None
// }else{
// //fail
// teleport_to_spawn(body,touching,style,modes.get_mode(stage_element.mode_id)?,models,game.stage_id)
// }
},
&crate::model::StageElementBehaviour::Ordered{checkpoint_id}=>{
if checkpoint_id<game.next_ordered_checkpoint_id{
//if you hit a checkpoint you already hit, nothing happens
None
}else if game.next_ordered_checkpoint_id==checkpoint_id{
//if you hit the next number in a sequence of ordered checkpoints
//increment the current checkpoint id
game.next_ordered_checkpoint_id+=1;
None
}else{
//If you hit an ordered checkpoint after missing a previous one
teleport_to_spawn(body,touching,style,modes.get_mode(stage_element.mode_id)?,models,game.stage_id)
}
},
crate::model::StageElementBehaviour::Unordered=>{
//count model id in accumulated unordered checkpoints
game.unordered_checkpoints.insert(model_id);
None
},
&crate::model::StageElementBehaviour::JumpLimit(jump_limit)=>{ &crate::model::StageElementBehaviour::JumpLimit(jump_limit)=>{
//let count=game.jump_counts.get(&model.id); //let count=game.jump_counts.get(&model.id);
//TODO //TODO
None None
}, },
&crate::model::StageElementBehaviour::Checkpoint{ordered_checkpoint_id,unordered_checkpoint_count}=>{
if ordered_checkpoint_id.map_or(true,|id|id<game.next_ordered_checkpoint_id)
&&unordered_checkpoint_count<=game.unordered_checkpoints.len() as u32{
//pass
None
}else{
//fail
teleport_to_spawn(body,touching,style,modes.get_mode(stage_element.mode_id)?,models,game.stage_id)
}
},
} }
}, },
Some(crate::model::TeleportBehaviour::Wormhole(wormhole))=>{ Some(crate::model::TeleportBehaviour::Wormhole(wormhole))=>{