From 020eae4781dd162b24e2a01cbc36c3836d407f33 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Fri, 26 Jul 2024 15:43:08 -0700 Subject: [PATCH] work around broken binrw option --- src/newtypes/gameplay_attributes.rs | 99 +++++++++++++++++++++-------- src/newtypes/gameplay_modes.rs | 21 +++--- src/newtypes/gameplay_style.rs | 81 ++++++++++++++++------- src/newtypes/model.rs | 11 ++-- 4 files changed, 150 insertions(+), 62 deletions(-) diff --git a/src/newtypes/gameplay_attributes.rs b/src/newtypes/gameplay_attributes.rs index c8039d7..06e168e 100644 --- a/src/newtypes/gameplay_attributes.rs +++ b/src/newtypes/gameplay_attributes.rs @@ -1,24 +1,44 @@ use super::integer::{Time,Planar64,Planar64Vec3}; +#[binrw::binrw] +#[brw(little,repr=u8)] +pub enum Boolio{ + True, + False +} +impl Into for Boolio{ + fn into(self)->bool{ + match self{ + Boolio::True=>true, + Boolio::False=>false, + } + } +} +impl From for Boolio{ + fn from(value:bool)->Self{ + match value{ + true=>Boolio::True, + false=>Boolio::False, + } + } +} + #[binrw::binrw] #[brw(little)] pub struct ContactingLadder{ - pub sticky:Option<()>, + pub sticky:Boolio, } impl Into for ContactingLadder{ fn into(self)->strafesnet_common::gameplay_attributes::ContactingLadder{ strafesnet_common::gameplay_attributes::ContactingLadder{ - sticky:self.sticky.is_some(), + sticky:self.sticky.into(), } } } impl From for ContactingLadder{ fn from(value:strafesnet_common::gameplay_attributes::ContactingLadder)->Self{ Self{ - sticky:match value.sticky{ - true=>Some(()), - false=>None, - } + sticky:value.sticky.into(), } } } @@ -283,31 +303,50 @@ impl From for Wormhole{ } } +#[binrw::binrw] +#[brw(little)] +pub struct GeneralAttributesHeader{ + pub booster:u8, + pub trajectory:u8, + pub wormhole:u8, + pub accelerator:u8, +} #[binrw::binrw] #[brw(little)] pub struct GeneralAttributes{ - pub booster:Option, - pub trajectory:Option, - pub wormhole:Option, - pub accelerator:Option, + pub header:GeneralAttributesHeader, + #[br(count=header.booster)] + pub booster:Vec, + #[br(count=header.trajectory)] + pub trajectory:Vec, + #[br(count=header.wormhole)] + pub wormhole:Vec, + #[br(count=header.accelerator)] + pub accelerator:Vec, } impl Into for GeneralAttributes{ - fn into(self)->strafesnet_common::gameplay_attributes::GeneralAttributes{ + fn into(mut self)->strafesnet_common::gameplay_attributes::GeneralAttributes{ strafesnet_common::gameplay_attributes::GeneralAttributes{ - booster:self.booster.map(Into::into), - trajectory:self.trajectory.map(Into::into), - wormhole:self.wormhole.map(Into::into), - accelerator:self.accelerator.map(Into::into), + booster:self.booster.pop().map(Into::into), + trajectory:self.trajectory.pop().map(Into::into), + wormhole:self.wormhole.pop().map(Into::into), + accelerator:self.accelerator.pop().map(Into::into), } } } impl From for GeneralAttributes{ fn from(value:strafesnet_common::gameplay_attributes::GeneralAttributes)->Self{ Self{ - booster:value.booster.map(Into::into), - trajectory:value.trajectory.map(Into::into), - wormhole:value.wormhole.map(Into::into), - accelerator:value.accelerator.map(Into::into), + header:GeneralAttributesHeader{ + booster:value.booster.is_some() as u8, + trajectory:value.trajectory.is_some() as u8, + wormhole:value.wormhole.is_some() as u8, + accelerator:value.accelerator.is_some() as u8, + }, + booster:super::gameplay_style::stupid(value.booster.map(Into::into)), + trajectory:super::gameplay_style::stupid(value.trajectory.map(Into::into)), + wormhole:super::gameplay_style::stupid(value.wormhole.map(Into::into)), + accelerator:super::gameplay_style::stupid(value.accelerator.map(Into::into)), } } } @@ -315,19 +354,22 @@ impl From for General #[binrw::binrw] #[brw(little)] pub struct ContactingAttributes{ - pub contact_behaviour:Option, + pub contact_behaviour_enabled:u8, + #[br(count=contact_behaviour_enabled)] + pub contact_behaviour:Vec, } impl Into for ContactingAttributes{ - fn into(self)->strafesnet_common::gameplay_attributes::ContactingAttributes{ + fn into(mut self)->strafesnet_common::gameplay_attributes::ContactingAttributes{ strafesnet_common::gameplay_attributes::ContactingAttributes{ - contact_behaviour:self.contact_behaviour.map(Into::into), + contact_behaviour:self.contact_behaviour.pop().map(Into::into), } } } impl From for ContactingAttributes{ fn from(value:strafesnet_common::gameplay_attributes::ContactingAttributes)->Self{ Self{ - contact_behaviour:value.contact_behaviour.map(Into::into), + contact_behaviour_enabled:value.contact_behaviour.is_some() as u8, + contact_behaviour:super::gameplay_style::stupid(value.contact_behaviour.map(Into::into)), } } } @@ -335,19 +377,22 @@ impl From for Cont #[binrw::binrw] #[brw(little)] pub struct IntersectingAttributes{ - pub water:Option, + pub water_enabled:u8, + #[br(count=water_enabled)] + pub water:Vec, } impl Into for IntersectingAttributes{ - fn into(self)->strafesnet_common::gameplay_attributes::IntersectingAttributes{ + fn into(mut self)->strafesnet_common::gameplay_attributes::IntersectingAttributes{ strafesnet_common::gameplay_attributes::IntersectingAttributes{ - water:self.water.map(Into::into), + water:self.water.pop().map(Into::into), } } } impl From for IntersectingAttributes{ fn from(value:strafesnet_common::gameplay_attributes::IntersectingAttributes)->Self{ Self{ - water:value.water.map(Into::into), + water_enabled:value.water.is_some() as u8, + water:super::gameplay_style::stupid(value.water.map(Into::into)), } } } diff --git a/src/newtypes/gameplay_modes.rs b/src/newtypes/gameplay_modes.rs index aa7848e..8605db8 100644 --- a/src/newtypes/gameplay_modes.rs +++ b/src/newtypes/gameplay_modes.rs @@ -40,16 +40,18 @@ impl From for StageEle pub struct StageElement{ pub stage_id:u32,//which stage spawn to send to pub behaviour:StageElementBehaviour, - pub jump_limit:Option, - pub force:Option<()>,//allow setting to lower spawn id i.e. 7->3 + pub jump_limit_enabled:u8, + #[br(count=jump_limit_enabled)] + pub jump_limit:Vec, + pub force:super::gameplay_attributes::Boolio,//allow setting to lower spawn id i.e. 7->3 } impl Into for StageElement{ - fn into(self)->strafesnet_common::gameplay_modes::StageElement{ + fn into(mut self)->strafesnet_common::gameplay_modes::StageElement{ strafesnet_common::gameplay_modes::StageElement::new( strafesnet_common::gameplay_modes::StageId::new(self.stage_id), - self.force.is_some(), + self.force.into(), self.behaviour.into(), - self.jump_limit, + self.jump_limit.pop(), ) } } @@ -58,8 +60,9 @@ impl From for StageElement{ Self{ stage_id:value.stage_id().get(), behaviour:value.behaviour().into(), - jump_limit:value.jump_limit(), - force:match value.force(){true=>Some(()),false=>None}, + jump_limit_enabled:value.jump_limit().is_some() as u8, + jump_limit:super::gameplay_style::stupid(value.jump_limit()), + force:value.force().into(), } } } @@ -114,7 +117,8 @@ impl From for Stage{ } #[binrw::binrw] -#[brw(little,repr=u8)] +#[brw(little,repr=u32)] +#[repr(u32)] pub enum Zone{ Start, Finish, @@ -141,6 +145,7 @@ impl From for Zone{ #[binrw::binrw] #[brw(little)] +#[derive(Debug)] pub struct ModeHeader{ pub zones:u32, pub stages:u32, diff --git a/src/newtypes/gameplay_style.rs b/src/newtypes/gameplay_style.rs index 1983a22..209aae6 100644 --- a/src/newtypes/gameplay_style.rs +++ b/src/newtypes/gameplay_style.rs @@ -2,34 +2,52 @@ use super::integer::{Time,Ratio64,Planar64,Planar64Vec3}; pub type Controls=u32; +#[binrw::binrw] +#[brw(little)] +pub struct StyleModifiersHeader{ + pub strafe:u8, + pub rocket:u8, + pub jump:u8, + pub walk:u8, + pub ladder:u8, + pub swim:u8, +} + #[binrw::binrw] #[brw(little)] pub struct StyleModifiers{ + pub header:StyleModifiersHeader, pub controls_mask:Controls, pub controls_mask_state:Controls, - pub strafe:Option, - pub rocket:Option, - pub jump:Option, - pub walk:Option, - pub ladder:Option, - pub swim:Option, + #[br(count=header.strafe)] + pub strafe:Vec, + #[br(count=header.rocket)] + pub rocket:Vec, + #[br(count=header.jump)] + pub jump:Vec, + #[br(count=header.walk)] + pub walk:Vec, + #[br(count=header.ladder)] + pub ladder:Vec, + #[br(count=header.swim)] + pub swim:Vec, pub gravity:Planar64Vec3, pub hitbox:Hitbox, pub camera_offset:Planar64Vec3, pub mass:Planar64, } impl Into for StyleModifiers{ - fn into(self)->strafesnet_common::gameplay_style::StyleModifiers{ + fn into(mut self)->strafesnet_common::gameplay_style::StyleModifiers{ strafesnet_common::gameplay_style::StyleModifiers{ //TODO: fail gracefully in binrw instead of panicing here controls_mask:strafesnet_common::controls_bitflag::Controls::from_bits(self.controls_mask).unwrap(), controls_mask_state:strafesnet_common::controls_bitflag::Controls::from_bits(self.controls_mask_state).unwrap(), - strafe:self.strafe.map(Into::into), - rocket:self.rocket.map(Into::into), - jump:self.jump.map(Into::into), - walk:self.walk.map(Into::into), - ladder:self.ladder.map(Into::into), - swim:self.swim.map(Into::into), + strafe:self.strafe.pop().map(Into::into), + rocket:self.rocket.pop().map(Into::into), + jump:self.jump.pop().map(Into::into), + walk:self.walk.pop().map(Into::into), + ladder:self.ladder.pop().map(Into::into), + swim:self.swim.pop().map(Into::into), gravity:strafesnet_common::integer::Planar64Vec3::raw_array(self.gravity), hitbox:self.hitbox.into(), camera_offset:strafesnet_common::integer::Planar64Vec3::raw_array(self.camera_offset), @@ -37,17 +55,31 @@ impl Into for StyleModifiers{ } } } +pub(crate) fn stupid(o:Option)->Vec{ + match o{ + Some(v)=>vec![v], + None=>Vec::new(), + } +} impl From for StyleModifiers{ fn from(value:strafesnet_common::gameplay_style::StyleModifiers)->Self{ Self{ + header:StyleModifiersHeader{ + strafe:value.strafe.is_some() as u8, + rocket:value.rocket.is_some() as u8, + jump:value.jump.is_some() as u8, + walk:value.walk.is_some() as u8, + ladder:value.ladder.is_some() as u8, + swim:value.swim.is_some() as u8, + }, controls_mask:value.controls_mask.bits(), controls_mask_state:value.controls_mask_state.bits(), - strafe:value.strafe.map(Into::into), - rocket:value.rocket.map(Into::into), - jump:value.jump.map(Into::into), - walk:value.walk.map(Into::into), - ladder:value.ladder.map(Into::into), - swim:value.swim.map(Into::into), + strafe:stupid(value.strafe.map(Into::into)), + rocket:stupid(value.rocket.map(Into::into)), + jump:stupid(value.jump.map(Into::into)), + walk:stupid(value.walk.map(Into::into)), + ladder:stupid(value.ladder.map(Into::into)), + swim:stupid(value.swim.map(Into::into)), gravity:value.gravity.get().to_array(), hitbox:value.hitbox.into(), camera_offset:value.camera_offset.get().to_array(), @@ -142,15 +174,17 @@ impl From for ControlsAct pub struct StrafeSettings{ enable:ControlsActivation, mv:Planar64, - air_accel_limit:Option, + air_accel_limit_enabled:u8, + #[br(count=air_accel_limit_enabled)] + air_accel_limit:Vec, tick_rate:Ratio64, } impl Into for StrafeSettings{ - fn into(self)->strafesnet_common::gameplay_style::StrafeSettings{ + fn into(mut self)->strafesnet_common::gameplay_style::StrafeSettings{ strafesnet_common::gameplay_style::StrafeSettings::new( self.enable.into(), strafesnet_common::integer::Planar64::raw(self.mv), - self.air_accel_limit.map(strafesnet_common::integer::Planar64::raw), + self.air_accel_limit.pop().map(strafesnet_common::integer::Planar64::raw), self.tick_rate.into(), ) } @@ -161,7 +195,8 @@ impl From for StrafeSettings{ Self{ enable:enable.into(), mv:mv.get(), - air_accel_limit:air_accel_limit.map(|a|a.get()), + air_accel_limit_enabled:air_accel_limit.is_some() as u8, + air_accel_limit:stupid(air_accel_limit.map(|a|a.get())), tick_rate:tick_rate.into(), } } diff --git a/src/newtypes/model.rs b/src/newtypes/model.rs index 4d42aa9..3fc7f64 100644 --- a/src/newtypes/model.rs +++ b/src/newtypes/model.rs @@ -60,19 +60,22 @@ impl From for PolygonGroup{ #[binrw::binrw] #[brw(little)] pub struct RenderConfig{ - pub texture:Option, + pub texture_enabled:u8, + #[br(count=texture_enabled)] + pub texture:Vec, } impl Into for RenderConfig{ - fn into(self)->strafesnet_common::model::RenderConfig{ + fn into(mut self)->strafesnet_common::model::RenderConfig{ strafesnet_common::model::RenderConfig{ - texture:self.texture.map(strafesnet_common::model::TextureId::new), + texture:self.texture.pop().map(strafesnet_common::model::TextureId::new), } } } impl From for RenderConfig{ fn from(value:strafesnet_common::model::RenderConfig)->Self{ Self{ - texture:value.texture.map(|texture_id|texture_id.get()), + texture_enabled:value.texture.is_some() as u8, + texture:super::gameplay_style::stupid(value.texture.map(|texture_id|texture_id.get())), } } }