Added a Bytes implementation for EffectCondition and DigimonProperty.

This commit is contained in:
2020-05-01 06:09:12 +01:00
parent ee7bcbea0f
commit 2ae6711703
3 changed files with 118 additions and 68 deletions

View File

@@ -358,6 +358,31 @@ generate_enum_property_mod!(
_ => "Unknown byte 0x{:x} for a digimon property",
}
impl crate::game::Bytes for Option<DigimonProperty> {
type ByteArray = u8;
type FromError = FromBytesError;
fn from_bytes(byte: &Self::ByteArray) -> Result<Self, Self::FromError>
{
match byte {
0 => Ok( None ),
_ => Ok( Some( DigimonProperty::from_bytes(byte)? ) ),
}
}
type ToError = <DigimonProperty as crate::game::Bytes>::ToError;
#[allow(clippy::diverging_sub_expression)] // For if we ever change `CrossMoveEffect::ToError`
fn to_bytes(&self, byte: &mut Self::ByteArray) -> Result<(), Self::ToError>
{
match self {
Some(effect) => effect.to_bytes(byte)?,
None => *byte = 0,
}
Ok(())
}
}
}
);

View File

@@ -453,7 +453,6 @@ impl Bytes for Effect
}
}
#[allow(clippy::use_self)] // False positive
impl Bytes for Option<Effect>
{
type ByteArray = [u8; 0x10];
@@ -478,7 +477,6 @@ impl Bytes for Option<Effect>
}
type ToError = ToBytesError;
#[allow(clippy::too_many_lines)] // It's a single match, we can't really split it
fn to_bytes(&self, bytes: &mut Self::ByteArray) -> Result<(), Self::ToError>
{
let bytes = util::array_split_mut!(bytes,

View File

@@ -7,8 +7,8 @@
//!
//! | Offset | Size | Type | Name | Location | Details |
//! |--------|------|------------------------------|---------------------------|--------------- |------------------------------------------------------------------------------------|
//! | 0x0 | 0x0 | `bool` | Misfire | `misfire` | If the condition throws a misfire when false |
//! | 0x1 | 0x1 | `u8` | | | Always zero |
//! | 0x0 | 0x1 | `bool` | Misfire | `misfire` | If the condition throws a misfire when false |
//! | 0x1 | 0x1 | `u8` | | `unknown_1` | Always zero |
//! | 0x2 | 0x1 | [`DigimonProperty`] | Property compare | `property_cmp` | The property to compare to for the condition (or 0 if the condition doesn't exist) |
//! | 0x3 | 0x5 | `[u8; 0x5]` | | `unknown_3` | Unknown |
//! | 0x8 | 0x1 | `DigimonProperty` | Property argument | `arg_property` | Property argument for the comparation |
@@ -27,7 +27,7 @@ use crate::game::{
card::property::{
self, DigimonProperty, EffectConditionOperation
},
//util,
util,
};
/// A digimon's support effect condition
@@ -51,6 +51,7 @@ pub struct EffectCondition
operation: EffectConditionOperation,
// Unknown
unknown_1 : u8,
unknown_3 : [u8; 0x5],
unknown_9 : [u8; 0xb],
unknown_16: [u8; 0x4],
@@ -75,7 +76,87 @@ pub enum FromBytesError
Operation( #[error(source)] property::effect_condition_operation::FromBytesError ),
}
// Bytes
impl Bytes for EffectCondition
{
type ByteArray = [u8; 0x20];
type FromError = FromBytesError;
fn from_bytes(bytes: &Self::ByteArray) -> Result<Self, Self::FromError>
{
let bytes = util::array_split!(bytes,
misfire : 0x1,
unknown_1 : 0x1,
property_cmp: 0x1,
unknown_3 : [0x5],
arg_property: 0x1,
unknown_9 : [0xb],
arg_num : [0x2],
unknown_16 : [0x4],
operation : 1,
unknown_1b : [0x5],
);
Ok( Self {
misfire: (*bytes.misfire != 0),
property_cmp: DigimonProperty::from_bytes( bytes.property_cmp )
.map_err(FromBytesError::Condition)?,
arg_property: Option::<DigimonProperty>::from_bytes( bytes.arg_property )
.map_err(FromBytesError::PropertyArgument)?,
arg_num: LittleEndian::read_u16( bytes.arg_num ),
operation: EffectConditionOperation::from_bytes( bytes.operation )
.map_err(FromBytesError::Operation)?,
unknown_1 : *bytes.unknown_1,
unknown_3 : *bytes.unknown_3,
unknown_9 : *bytes.unknown_9,
unknown_16: *bytes.unknown_16,
unknown_1b: *bytes.unknown_1b,
})
}
type ToError = !;
fn to_bytes(&self, bytes: &mut Self::ByteArray) -> Result<(), Self::ToError>
{
let bytes = util::array_split_mut!(bytes,
misfire : 0x1,
unknown_1 : 0x1,
property_cmp: 0x1,
unknown_3 : [0x5],
arg_property: 0x1,
unknown_9 : [0xb],
arg_num : [0x2],
unknown_16 : [0x4],
operation : 1,
unknown_1b : [0x5],
);
// Misfire
*bytes.misfire = if self.misfire { 1 } else { 0 };
// Condition
self.property_cmp.to_bytes( bytes.property_cmp ).into_ok();
// Arguments
self.arg_property.to_bytes( bytes.arg_property ).into_ok();
LittleEndian::write_u16(bytes.arg_num, self.arg_num);
self.operation.to_bytes(bytes.operation).into_ok();
// Unknowns
*bytes.unknown_1 = self.unknown_1;
*bytes.unknown_3 = self.unknown_3;
*bytes.unknown_9 = self.unknown_9;
*bytes.unknown_16 = self.unknown_16;
*bytes.unknown_1b = self.unknown_1b;
// And return OK
Ok(())
}
}
impl Bytes for Option<EffectCondition>
{
type ByteArray = [u8; 0x20];
@@ -89,74 +170,20 @@ impl Bytes for Option<EffectCondition>
}
// Else build the type
Ok( Some( EffectCondition {
misfire: (bytes[0x0] != 0),
property_cmp: DigimonProperty::from_bytes( &bytes[0x2] )
.map_err(FromBytesError::Condition)?,
arg_property: (bytes[0x8] != 0)
.then(|| DigimonProperty::from_bytes( &bytes[0x8] ))
.transpose()
.map_err(FromBytesError::PropertyArgument)?,
arg_num: LittleEndian::read_u16( &bytes[0x14..0x16] ),
operation: EffectConditionOperation::from_bytes( &bytes[0x1a] )
.map_err(FromBytesError::Operation)?,
unknown_3: [ bytes[0x3], bytes[0x4], bytes[0x5], bytes[0x6], bytes[0x7] ],
unknown_9: [
bytes[0x9], bytes[0xa ], bytes[0xb ], bytes[0xc ], bytes[0xd ], bytes[0xe],
bytes[0xf], bytes[0x10], bytes[0x11], bytes[0x12], bytes[0x13]
],
unknown_16: [ bytes[0x16], bytes[0x17], bytes[0x18], bytes[0x19] ],
unknown_1b: [ bytes[0x1b], bytes[0x1c], bytes[0x1d], bytes[0x1e], bytes[0x1f] ],
}))
Ok( Some( EffectCondition::from_bytes(bytes)? ))
}
type ToError = !;
type ToError = <EffectCondition as crate::game::Bytes>::ToError;
#[allow(clippy::diverging_sub_expression)] // For if we ever change `EffectCondition::ToError`
fn to_bytes(&self, bytes: &mut Self::ByteArray) -> Result<(), Self::ToError>
{
// If we don't exist, write a `0` on the property comparation and return
let cond = match self {
Some(cond) => cond,
None => {
bytes[0x2] = 0;
return Ok(());
}
// Check if we exist
match self {
Some(cond) => cond.to_bytes(bytes)?,
None => bytes[0x2] = 0,
};
// 0x0 - Misfire
bytes[0x0] = if cond.misfire { 1 } else { 0 };
// 0x1 - Always zero
bytes[0x1] = 0;
// 0x2 - Condition
cond.property_cmp.to_bytes(&mut bytes[0x2]).into_ok();
// 0x3..0x8 - Unknown[0..5]
//bytes[0x3..0x8].copy_from_slice( &self.unknown[0..5] );
// 0x8 - Type arg / 0 if None
if let Some(type_arg) = cond.arg_property {
type_arg.to_bytes(&mut bytes[0x8]).into_ok();
}
else { bytes[0x8] = 0; }
// 0x9..0x14 - Unknown[0x5..0x10]
//bytes[0x9..0x14].copy_from_slice( &self.unknown[0x5..0x10] );
// 0x14..0x16 - Number arg
LittleEndian::write_u16(&mut bytes[0x14..0x16], cond.arg_num);
// 0x1a - Operation arg
cond.operation.to_bytes(&mut bytes[0x1a]).into_ok();
// And return OK
// And return Ok
Ok(())
}
}