mirror of
https://github.com/Zenithsiz/dcb.git
synced 2026-02-08 19:34:27 +00:00
Made game::util::read_null_ascii_string more generic.
Added some implementations of `Bytes` for `Option<...>` where relevant. Started using `array_split` in `Move::from_bytes`.
This commit is contained in:
@@ -191,6 +191,7 @@ pub enum FromBytesError
|
||||
#[display(fmt = "Unable to read the third effect")]
|
||||
EffectThird( #[error(source)] property::effect::FromBytesError ),
|
||||
}
|
||||
|
||||
/// Error type for [`Bytes::to_bytes`]
|
||||
#[derive(Debug)]
|
||||
#[derive(derive_more::Display, err_impl::Error)]
|
||||
@@ -323,16 +324,12 @@ impl Bytes for Digimon
|
||||
.map_err(FromBytesError::EffectThird)?,
|
||||
],
|
||||
|
||||
cross_move_effect: (*bytes.cross_move_effect != 0)
|
||||
.then(|| CrossMoveEffect::from_bytes( bytes.cross_move_effect ) )
|
||||
.transpose()
|
||||
cross_move_effect: Option::<CrossMoveEffect>::from_bytes(bytes.cross_move_effect)
|
||||
.map_err(FromBytesError::CrossMoveEffect)?,
|
||||
|
||||
unknown_e2: *bytes.unknown_e2,
|
||||
|
||||
effect_arrow_color: (*bytes.effect_arrow_color != 0)
|
||||
.then(|| ArrowColor::from_bytes( bytes.effect_arrow_color ) )
|
||||
.transpose()
|
||||
effect_arrow_color: Option::<ArrowColor>::from_bytes(bytes.effect_arrow_color)
|
||||
.map_err(FromBytesError::ArrowColor)?,
|
||||
|
||||
effect_description: [
|
||||
@@ -425,13 +422,13 @@ impl Bytes for Digimon
|
||||
self.effects[2].to_bytes( bytes.effect_third ).map_err(ToBytesError::EffectThird )?;
|
||||
|
||||
// Cross move
|
||||
if let Some(move_cross) = self.cross_move_effect { move_cross.to_bytes( bytes.cross_move_effect )? };
|
||||
Option::<CrossMoveEffect>::to_bytes(&self.cross_move_effect, bytes.cross_move_effect).into_ok();
|
||||
|
||||
// Unknown
|
||||
*bytes.unknown_e2 = self.unknown_e2;
|
||||
|
||||
// Support arrow color
|
||||
if let Some(arrow_color) = self.effect_arrow_color { arrow_color.to_bytes( bytes.effect_arrow_color )? }
|
||||
Option::<ArrowColor>::to_bytes(&self.effect_arrow_color, bytes.effect_arrow_color).into_ok();
|
||||
|
||||
// effect_description
|
||||
util::write_null_ascii_string(self.effect_description[0].as_ref(), bytes.effect_description_0)
|
||||
|
||||
@@ -136,6 +136,31 @@ generate_enum_property_mod!(
|
||||
|
||||
_ => "Unknown byte 0x{:x} for an arrow color"
|
||||
}
|
||||
|
||||
impl crate::game::Bytes for Option<ArrowColor> {
|
||||
type ByteArray = u8;
|
||||
|
||||
type FromError = FromBytesError;
|
||||
fn from_bytes(byte: &Self::ByteArray) -> Result<Self, Self::FromError>
|
||||
{
|
||||
match byte {
|
||||
0 => Ok( None ),
|
||||
_ => Ok( Some( ArrowColor::from_bytes(byte)? ) ),
|
||||
}
|
||||
}
|
||||
|
||||
type ToError = <ArrowColor as crate::game::Bytes>::ToError;
|
||||
#[allow(clippy::diverging_sub_expression)] // For if we ever change `ArrowColor::ToError`
|
||||
fn to_bytes(&self, byte: &mut Self::ByteArray) -> Result<(), Self::ToError>
|
||||
{
|
||||
match self {
|
||||
Some(effect) => effect.to_bytes(byte)?,
|
||||
None => *byte = 0,
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub mod attack_type {
|
||||
@@ -272,6 +297,31 @@ generate_enum_property_mod!(
|
||||
|
||||
_ => "Unknown byte 0x{:x} for a cross move effect",
|
||||
}
|
||||
|
||||
impl crate::game::Bytes for Option<CrossMoveEffect> {
|
||||
type ByteArray = u8;
|
||||
|
||||
type FromError = FromBytesError;
|
||||
fn from_bytes(byte: &Self::ByteArray) -> Result<Self, Self::FromError>
|
||||
{
|
||||
match byte {
|
||||
0 => Ok( None ),
|
||||
_ => Ok( Some( CrossMoveEffect::from_bytes(byte)? ) ),
|
||||
}
|
||||
}
|
||||
|
||||
type ToError = <CrossMoveEffect 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(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub mod digimon_property {
|
||||
|
||||
@@ -58,13 +58,20 @@ impl Bytes for Move
|
||||
type FromError = FromBytesError;
|
||||
fn from_bytes(bytes: &Self::ByteArray) -> Result<Self, Self::FromError>
|
||||
{
|
||||
// Get all byte arrays we need
|
||||
let bytes = util::array_split!(bytes,
|
||||
power : [0x2],
|
||||
unknown: [0x4],
|
||||
name : [0x16],
|
||||
);
|
||||
|
||||
// Return the move
|
||||
Ok( Self {
|
||||
name : util::read_null_ascii_string( &bytes[0x6..0x1c] )
|
||||
name : util::read_null_ascii_string( bytes.name )
|
||||
.map_err(FromBytesError::Name)?
|
||||
.chars().collect(),
|
||||
power : LittleEndian::read_u16( &bytes[0x0..0x2] ),
|
||||
unknown: LittleEndian::read_u32( &bytes[0x2..0x6] ),
|
||||
power : LittleEndian::read_u16( bytes.power ),
|
||||
unknown: LittleEndian::read_u32( bytes.unknown ),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -221,13 +221,13 @@ pub enum ReadNullAsciiStringError {
|
||||
}
|
||||
|
||||
/// Reads a null-terminated ascii string from a buffer.
|
||||
pub fn read_null_ascii_string(mut buf: &[u8]) -> Result<&ascii::AsciiStr, ReadNullAsciiStringError> {
|
||||
pub fn read_null_ascii_string(buf: &impl AsRef<[u8]>) -> Result<&ascii::AsciiStr, ReadNullAsciiStringError> {
|
||||
// Find the first null and trim the buffer until it
|
||||
if let Some(null_idx) = buf.iter().position(|&b| b == 0) {
|
||||
buf = &buf[0..null_idx];
|
||||
} else {
|
||||
return Err( ReadNullAsciiStringError::NoNull );
|
||||
}
|
||||
let buf = buf.as_ref();
|
||||
let buf = match buf.iter().position(|&b| b == 0) {
|
||||
Some(null_idx) => &buf[0..null_idx],
|
||||
None => return Err( ReadNullAsciiStringError::NoNull ),
|
||||
};
|
||||
|
||||
// Then convert it from Ascii
|
||||
ascii::AsciiStr::from_ascii(buf)
|
||||
@@ -254,6 +254,7 @@ pub fn write_null_ascii_string<'a>(input: &ascii::AsciiStr, buf: &'a mut [u8]) -
|
||||
}
|
||||
|
||||
// Else copy everything over and set the last byte to null
|
||||
// Note: We leave all other bytes as they are, no need to set them to 0
|
||||
buf[ 0..input.len() ].copy_from_slice( input.as_bytes() );
|
||||
buf[ input.len() ] = 0;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user