diff --git a/src/army/decoder.rs b/src/army/decoder.rs index 279e353..b1bb45f 100644 --- a/src/army/decoder.rs +++ b/src/army/decoder.rs @@ -12,7 +12,8 @@ pub enum DecodeError { IoError(IoError), InvalidFormat(u32), InvalidString, - InvalidClass(u8), + InvalidRegimentAlignment(u8), + InvalidRegimentClass(u8), } impl std::error::Error for DecodeError {} @@ -29,7 +30,10 @@ impl fmt::Display for DecodeError { DecodeError::IoError(e) => write!(f, "IO error: {}", e), DecodeError::InvalidFormat(format) => write!(f, "invalid format: {}", format), DecodeError::InvalidString => write!(f, "invalid string"), - DecodeError::InvalidClass(v) => write!(f, "invalid class: {}", v), + DecodeError::InvalidRegimentAlignment(v) => { + write!(f, "invalid regiment alignment: {}", v) + } + DecodeError::InvalidRegimentClass(v) => write!(f, "invalid regiment class: {}", v), } } } @@ -183,8 +187,11 @@ impl Decoder { let mut buf = vec![0; REGIMENT_BLOCK_SIZE]; self.reader.read_exact(&mut buf)?; + let alignment = RegimentAlignment::try_from(buf[56]) + .map_err(|_| DecodeError::InvalidRegimentAlignment(buf[56]))?; + let (typ, race) = Regiment::decode_class(buf[76]) - .map_err(|_| -> DecodeError { DecodeError::InvalidClass(buf[76]) })?; + .map_err(|_| -> DecodeError { DecodeError::InvalidRegimentClass(buf[76]) })?; Ok(Regiment { status: buf[0..2].try_into().unwrap(), @@ -200,7 +207,7 @@ impl Decoder { sprite_index: u16::from_le_bytes(buf[20..22].try_into().unwrap()), name: self.read_string(&buf[22..54])?, name_id: u16::from_le_bytes(buf[54..56].try_into().unwrap()), - alignment: buf[56], + alignment, max_troops: buf[57], alive_troops: buf[58], ranks: buf[59], diff --git a/src/army/encoder.rs b/src/army/encoder.rs index 0f80055..071df79 100644 --- a/src/army/encoder.rs +++ b/src/army/encoder.rs @@ -87,6 +87,8 @@ impl Encoder { } fn write_regiment(&mut self, r: &Regiment) -> Result<(), EncodeError> { + let alignment: u8 = r.alignment.into(); + self.writer.write_all(&r.status)?; self.writer.write_all(&r.unknown1)?; self.writer.write_all(&r.id.to_le_bytes())?; @@ -100,7 +102,7 @@ impl Encoder { self.writer.write_all(&r.sprite_index.to_le_bytes())?; self.write_string_with_limit(&r.name, 32)?; self.writer.write_all(&r.name_id.to_le_bytes())?; - self.writer.write_all(&[r.alignment])?; + self.writer.write_all(&[alignment])?; self.writer.write_all(&[r.max_troops])?; self.writer.write_all(&[r.alive_troops])?; self.writer.write_all(&[r.ranks])?; diff --git a/src/army/mod.rs b/src/army/mod.rs index 97b1077..672573c 100644 --- a/src/army/mod.rs +++ b/src/army/mod.rs @@ -48,7 +48,7 @@ pub struct Regiment { /// - 0x00 (decimal 0) is good. /// - 0x40 (decimal 64) is neutral. /// - 0x80 (decimal 128) is evil. - pub alignment: u8, + pub alignment: RegimentAlignment, /// The regiment's type. pub typ: RegimentType, /// The regiment's race. @@ -126,6 +126,14 @@ pub struct Regiment { unknown7: [u8; 12], } +#[repr(u8)] +#[derive(Debug, Clone, Copy, IntoPrimitive, PartialEq, Serialize, TryFromPrimitive)] +pub enum RegimentAlignment { + Good = 0, + Neutral = 64, + Evil = 128, +} + #[repr(u8)] #[derive(Debug, Clone, Copy, IntoPrimitive, PartialEq, Serialize, TryFromPrimitive)] pub enum RegimentType {