diff --git a/engine/physics/src/physics.rs b/engine/physics/src/physics.rs index 3fd234022..0036a0441 100644 --- a/engine/physics/src/physics.rs +++ b/engine/physics/src/physics.rs @@ -982,10 +982,7 @@ impl PhysicsContext<'_>{ impl PhysicsData{ /// use with caution, this is the only non-instruction way to mess with physics pub fn generate_models(&mut self,map:&map::CompleteMap){ - let mut modes=map.modes.clone(); - for mode in &mut modes.modes{ - mode.denormalize_data(); - } + let mut modes=map.modes.clone().denormalize(); let mut used_contact_attributes=Vec::new(); let mut used_intersect_attributes=Vec::new(); diff --git a/lib/bsp_loader/src/bsp.rs b/lib/bsp_loader/src/bsp.rs index 0cbf32b5c..afbd2ff6e 100644 --- a/lib/bsp_loader/src/bsp.rs +++ b/lib/bsp_loader/src/bsp.rs @@ -6,6 +6,7 @@ use strafesnet_common::{map,model,integer,gameplay_attributes}; use strafesnet_deferred_loader::deferred_loader::{MeshDeferredLoader,RenderConfigDeferredLoader}; use strafesnet_deferred_loader::mesh::Meshes; use strafesnet_deferred_loader::texture::{RenderConfigs,Texture}; +use strafesnet_common::gameplay_modes::{NormalizedMode,NormalizedModes,Mode,Stage}; use crate::valve_transform; @@ -268,15 +269,15 @@ pub fn convert<'a>( color:glam::Vec4::W, }); - let first_stage=strafesnet_common::gameplay_modes::Stage::empty(model_id); - let main_mode=strafesnet_common::gameplay_modes::Mode::new( + let first_stage=Stage::empty(model_id); + let main_mode=Mode::new( strafesnet_common::gameplay_style::StyleModifiers::source_bhop(), model_id, std::collections::HashMap::new(), vec![first_stage], std::collections::HashMap::new(), ); - modes_list.push(main_mode); + modes_list.push(NormalizedMode::new(main_mode)); } PartialMap1{ @@ -284,7 +285,7 @@ pub fn convert<'a>( world_meshes, prop_models, world_models, - modes:strafesnet_common::gameplay_modes::Modes::new(modes_list), + modes:NormalizedModes::new(modes_list), } } @@ -294,7 +295,7 @@ pub struct PartialMap1{ prop_models:Vec<model::Model>, world_meshes:Vec<model::Mesh>, world_models:Vec<model::Model>, - modes:strafesnet_common::gameplay_modes::Modes, + modes:NormalizedModes, } impl PartialMap1{ pub fn add_prop_meshes<'a>( @@ -317,7 +318,7 @@ pub struct PartialMap2{ prop_models:Vec<model::Model>, world_meshes:Vec<model::Mesh>, world_models:Vec<model::Model>, - modes:strafesnet_common::gameplay_modes::Modes, + modes:NormalizedModes, } impl PartialMap2{ pub fn add_render_configs_and_textures( diff --git a/lib/common/src/gameplay_modes.rs b/lib/common/src/gameplay_modes.rs index 90735be00..42ee25043 100644 --- a/lib/common/src/gameplay_modes.rs +++ b/lib/common/src/gameplay_modes.rs @@ -214,19 +214,32 @@ impl Mode{ pub fn get_element(&self,model_id:ModelId)->Option<&StageElement>{ self.elements.get(&model_id) } +} + +#[derive(Clone)] +pub struct NormalizedMode(Mode); +impl NormalizedMode{ + pub fn new(mode:Mode)->Self{ + Self(mode) + } + pub fn into_inner(self)->Mode{ + let Self(mode)=self; + mode + } //TODO: put this in the SNF - pub fn denormalize_data(&mut self){ + pub fn denormalize(self)->Mode{ + let NormalizedMode(mut mode)=self; //expand and index normalized data - self.zones.insert(self.start,Zone::Start); - for (stage_id,stage) in self.stages.iter().enumerate(){ - self.elements.insert(stage.spawn,StageElement{ + mode.zones.insert(mode.start,Zone::Start); + for (stage_id,stage) in mode.stages.iter().enumerate(){ + mode.elements.insert(stage.spawn,StageElement{ stage_id:StageId(stage_id as u32), force:false, behaviour:StageElementBehaviour::SpawnAt, jump_limit:None, }); for (_,&model) in &stage.ordered_checkpoints{ - self.elements.insert(model,StageElement{ + mode.elements.insert(model,StageElement{ stage_id:StageId(stage_id as u32), force:false, behaviour:StageElementBehaviour::Checkpoint, @@ -234,7 +247,7 @@ impl Mode{ }); } for &model in &stage.unordered_checkpoints{ - self.elements.insert(model,StageElement{ + mode.elements.insert(model,StageElement{ stage_id:StageId(stage_id as u32), force:false, behaviour:StageElementBehaviour::Checkpoint, @@ -242,12 +255,13 @@ impl Mode{ }); } } + mode } } #[derive(Default,Clone)] pub struct Modes{ - pub modes:Vec<Mode>, + modes:Vec<Mode>, } impl Modes{ pub const fn new(modes:Vec<Mode>)->Self{ @@ -266,6 +280,31 @@ impl Modes{ } } +#[derive(Clone)] +pub struct NormalizedModes{ + modes:Vec<NormalizedMode>, +} +impl NormalizedModes{ + pub fn new(modes:Vec<NormalizedMode>)->Self{ + Self{modes} + } + pub fn len(&self)->usize{ + self.modes.len() + } + pub fn denormalize(self)->Modes{ + Modes{ + modes:self.modes.into_iter().map(NormalizedMode::denormalize).collect(), + } + } +} +impl IntoIterator for NormalizedModes{ + type Item=<Vec<NormalizedMode> as IntoIterator>::Item; + type IntoIter=<Vec<NormalizedMode> as IntoIterator>::IntoIter; + fn into_iter(self)->Self::IntoIter{ + self.modes.into_iter() + } +} + #[derive(Default)] pub struct StageUpdate{ @@ -352,7 +391,7 @@ pub struct ModesBuilder{ stage_updates:Vec<(ModeId,StageId,StageUpdate)>, } impl ModesBuilder{ - pub fn build(mut self)->Modes{ + pub fn build_normalized(mut self)->NormalizedModes{ //collect modes and stages into contiguous arrays let mut unique_modes:Vec<(ModeId,Mode)> =self.modes.into_iter().collect(); @@ -412,7 +451,7 @@ impl ModesBuilder{ } } } - Modes::new(modes.into_iter().map(|mode_builder|mode_builder.mode).collect()) + NormalizedModes::new(modes.into_iter().map(|mode_builder|NormalizedMode(mode_builder.mode)).collect()) } pub fn insert_mode(&mut self,mode_id:ModeId,mode:Mode){ assert!(self.modes.insert(mode_id,mode).is_none(),"Cannot replace existing mode"); diff --git a/lib/common/src/map.rs b/lib/common/src/map.rs index 3c4020c5e..6279ef2e3 100644 --- a/lib/common/src/map.rs +++ b/lib/common/src/map.rs @@ -4,7 +4,7 @@ use crate::gameplay_attributes; //this is a temporary struct to try to get the code running again //TODO: use snf::map::Region to update the data in physics and graphics instead of this pub struct CompleteMap{ - pub modes:gameplay_modes::Modes, + pub modes:gameplay_modes::NormalizedModes, pub attributes:Vec<gameplay_attributes::CollisionAttributes>, pub meshes:Vec<model::Mesh>, pub models:Vec<model::Model>, diff --git a/lib/rbx_loader/src/rbx.rs b/lib/rbx_loader/src/rbx.rs index 208394d0e..fbfc58b10 100644 --- a/lib/rbx_loader/src/rbx.rs +++ b/lib/rbx_loader/src/rbx.rs @@ -4,7 +4,7 @@ use crate::primitives; use strafesnet_common::aabb::Aabb; use strafesnet_common::map; use strafesnet_common::model; -use strafesnet_common::gameplay_modes::{Mode,ModeId,ModeUpdate,Modes,ModesBuilder,Stage,StageElement,StageElementBehaviour,StageId,Zone}; +use strafesnet_common::gameplay_modes::{NormalizedModes,Mode,ModeId,ModeUpdate,ModesBuilder,Stage,StageElement,StageElementBehaviour,StageId,Zone}; use strafesnet_common::gameplay_style; use strafesnet_common::gameplay_attributes as attr; use strafesnet_common::integer::{self,vec3,Planar64,Planar64Vec3,Planar64Mat3,Planar64Affine3}; @@ -922,7 +922,7 @@ impl PartialMap1<'_>{ PartialMap2{ meshes:self.primitive_meshes, models, - modes:modes_builder.build(), + modes:modes_builder.build_normalized(), attributes:unique_attributes, } } @@ -931,7 +931,7 @@ impl PartialMap1<'_>{ pub struct PartialMap2{ meshes:Vec<model::Mesh>, models:Vec<model::Model>, - modes:Modes, + modes:NormalizedModes, attributes:Vec<strafesnet_common::gameplay_attributes::CollisionAttributes>, } impl PartialMap2{ diff --git a/lib/snf/src/map.rs b/lib/snf/src/map.rs index 5661364b0..1f476c088 100644 --- a/lib/snf/src/map.rs +++ b/lib/snf/src/map.rs @@ -138,7 +138,7 @@ struct MapHeader{ //#[br(count=num_resources_external)] //external_resources:Vec<ResourceExternalHeader>, #[br(count=num_modes)] - modes:Vec<newtypes::gameplay_modes::Mode>, + modes:Vec<newtypes::gameplay_modes::NormalizedMode>, #[br(count=num_attributes)] attributes:Vec<newtypes::gameplay_attributes::CollisionAttributes>, #[br(count=num_render_configs)] @@ -181,7 +181,7 @@ fn read_texture<R:BinReaderExt>(file:&mut crate::file::File<R>,block_id:BlockId) pub struct StreamableMap<R:BinReaderExt>{ file:crate::file::File<R>, //this includes every platform... move the unconstrained datas to their appropriate data block? - modes:gameplay_modes::Modes, + modes:gameplay_modes::NormalizedModes, //this is every possible attribute... need some sort of streaming system attributes:Vec<strafesnet_common::gameplay_attributes::CollisionAttributes>, //this is every possible render configuration... shaders and such... need streaming @@ -223,7 +223,7 @@ impl<R:BinReaderExt> StreamableMap<R>{ } Ok(Self{ file, - modes:strafesnet_common::gameplay_modes::Modes::new(modes), + modes:strafesnet_common::gameplay_modes::NormalizedModes::new(modes), attributes, render_configs, bvh:strafesnet_common::bvh::generate_bvh(bvh), @@ -430,13 +430,13 @@ pub fn write_map<W:BinWriterExt>(mut writer:W,map:strafesnet_common::map::Comple num_spacial_blocks:spacial_blocks.len() as u32, num_resource_blocks:resource_blocks.len() as u32, //num_resources_external:0, - num_modes:map.modes.modes.len() as u32, + num_modes:map.modes.len() as u32, num_attributes:map.attributes.len() as u32, num_render_configs:map.render_configs.len() as u32, spacial_blocks, resource_blocks, //external_resources:Vec::new(), - modes:map.modes.modes.into_iter().map(Into::into).collect(), + modes:map.modes.into_iter().map(Into::into).collect(), attributes:map.attributes.into_iter().map(Into::into).collect(), render_configs:map.render_configs.into_iter().map(Into::into).collect(), }; diff --git a/lib/snf/src/newtypes/gameplay_modes.rs b/lib/snf/src/newtypes/gameplay_modes.rs index 4363208c7..d84249623 100644 --- a/lib/snf/src/newtypes/gameplay_modes.rs +++ b/lib/snf/src/newtypes/gameplay_modes.rs @@ -157,7 +157,7 @@ pub struct ModeHeader{ } #[binrw::binrw] #[brw(little)] -pub struct Mode{ +pub struct NormalizedMode{ pub header:ModeHeader, pub style:super::gameplay_style::StyleModifiers, pub start:u32, @@ -179,10 +179,10 @@ impl std::fmt::Display for ModeError{ } } impl std::error::Error for ModeError{} -impl TryInto<strafesnet_common::gameplay_modes::Mode> for Mode{ +impl TryInto<strafesnet_common::gameplay_modes::NormalizedMode> for NormalizedMode{ type Error=ModeError; - fn try_into(self)->Result<strafesnet_common::gameplay_modes::Mode,Self::Error>{ - Ok(strafesnet_common::gameplay_modes::Mode::new( + fn try_into(self)->Result<strafesnet_common::gameplay_modes::NormalizedMode,Self::Error>{ + Ok(strafesnet_common::gameplay_modes::NormalizedMode::new(strafesnet_common::gameplay_modes::Mode::new( self.style.try_into().map_err(ModeError::StyleModifier)?, strafesnet_common::model::ModelId::new(self.start), self.zones.into_iter().map(|(model_id,zone)| @@ -192,12 +192,12 @@ impl TryInto<strafesnet_common::gameplay_modes::Mode> for Mode{ self.elements.into_iter().map(|(model_id,stage_element)| Ok((strafesnet_common::model::ModelId::new(model_id),stage_element.try_into()?)) ).collect::<Result<_,_>>().map_err(ModeError::StageElement)?, - )) + ))) } } -impl From<strafesnet_common::gameplay_modes::Mode> for Mode{ - fn from(value:strafesnet_common::gameplay_modes::Mode)->Self{ - let (style,start,zones,stages,elements)=value.into_inner(); +impl From<strafesnet_common::gameplay_modes::NormalizedMode> for NormalizedMode{ + fn from(value:strafesnet_common::gameplay_modes::NormalizedMode)->Self{ + let (style,start,zones,stages,elements)=value.into_inner().into_inner(); Self{ header:ModeHeader{ zones:zones.len() as u32,