types: fix light types

Straight from RA2.exe, as exercised by Mars2 in DSL-IRL.
main
q3k 2022-04-15 18:43:54 +00:00
parent deca4f5565
commit 13efa89224
2 changed files with 51 additions and 14 deletions

View File

@ -673,8 +673,7 @@ pub struct LightObject {
#[gma_name("NODE_NAME")]
pub name: String,
pub tm: TransformMatrix,
#[gma_skip]
pub target: String,
pub tm2: Option<TransformMatrix>,
#[gma_name("LIGHT_TYPE")]
pub light_type: LightType,
pub shadows: LightShadows,
@ -684,17 +683,24 @@ pub struct LightObject {
#[gma_name("LIGHT_INTENS")]
pub intensity: f32,
pub aspect: f32,
#[gma_skip]
pub unk1: [u8; 8],
#[gma_skip(self.light_type == LightType::Omni)]
pub hotspot: f32,
#[gma_skip(self.light_type == LightType::Omni)]
pub falloff: f32,
#[gma_skip(self.light_type == LightType::Directional)]
pub attn_start: f32,
#[gma_skip(self.light_type == LightType::Directional)]
pub attn_end: f32,
pub tdist: f32,
pub use_far_attenuation: FarAttenuation,
}
#[derive(Debug,GMISerializable,GMASerializable,Serialize)]
#[derive(Debug,PartialEq,Eq,GMISerializable,GMASerializable,Serialize)]
pub enum LightType {
Omni = 0,
Target = 1,
Directional = 2,
Free = 4,
}
#[derive(Debug,GMISerializable,GMASerializable,Serialize)]
@ -931,7 +937,8 @@ pub struct RBCollectionObject {
#[gma_name("SOLVER_TYPE")]
pub solver_type: u32,
pub rigidbody_list: RigidBodyList,
#[gmi_read_parameters(disabled_pairs)]
// Some DSL-IRL 2.6 GMFs have this set to ffffff / ffffffff for some reason..
#[gmi_read_parameters(if disabled_pairs < 4096 { disabled_pairs } else { 0 })]
pub disabled_collision_pairs: Option<DisabledCollisionPairList>,
}

View File

@ -229,6 +229,35 @@ impl GMAValue {
}
}
struct GMASkip {
#[allow(dead_code)]
paren_token: syn::token::Paren,
fields: syn::punctuated::Punctuated<syn::Expr, syn::Token![,]>,
}
impl syn::parse::Parse for GMASkip {
fn parse(input: syn::parse::ParseStream) -> syn::parse::Result<Self> {
let content;
Ok(Self {
paren_token: parenthesized!(content in input),
fields: content.parse_terminated(syn::Expr::parse)?,
})
}
}
impl GMASkip {
fn from_attrs(attrs: &Vec<syn::Attribute>) -> Option<syn::Expr> {
if let Some(attr) = attrs.iter().find(|a| a.path.is_ident("gma_skip")) {
let parameters = syn::parse2::<GMIReadParameters>(attr.tokens.clone()).expect("invalid gma_skip attribute");
if parameters.fields.len() != 1 {
panic!("gma_skip must have exactly one attribute");
}
return Some(parameters.fields.iter().next().unwrap().clone());
}
None
}
}
#[proc_macro_derive(GMASerializable, attributes(gma_name, gma_name_bare, gma_value, gma_skip, gma_space_delim))]
pub fn gma_serializable_macro(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
@ -266,7 +295,7 @@ pub fn gma_serializable_macro(input: TokenStream) -> TokenStream {
}).unwrap();
let writes: Vec<proc_macro2::TokenStream> = fields.named.iter().map(|field| {
let field_ident = &field.ident;
let field_skip = field.attrs.iter().any(|a| a.path.is_ident("gma_skip"));
let field_skip = GMASkip::from_attrs(&field.attrs);
let field_space = field.attrs.iter().any(|a| a.path.is_ident("gma_space_delim"));
let field_name = GMAName::from_attrs(&field.attrs)
.map(|s|
@ -278,15 +307,16 @@ pub fn gma_serializable_macro(input: TokenStream) -> TokenStream {
.or_else(|| {
Some(struct_name.clone() + "_" + &gma_name_from_ident(field_ident.as_ref().unwrap()))
}).unwrap();
if field_skip {
quote! { }
} else {
if field_space {
quote! {
let mut cond = field_skip.map(|el| quote! { #el } ).unwrap_or(quote! { false } );
if field_space {
quote! {
if ! ( #cond ) {
_w.emit(&format!("{} {}", #field_name, self.#field_ident.atom()))?;
}
} else {
quote! {
}
} else {
quote! {
if ! ( #cond ) {
self.#field_ident.write(#field_name, _w)?;
}
}