Skip to main content

idmangler_lib/block/
durabilitydata.rs

1use crate::{
2    encoding::{
3        varint::{decode_varint, encode_varint},
4        BlockId, DataDecoder, DataEncoder, DecodeError, EncodeError,
5    },
6    types::EncodingVersion,
7};
8
9use super::{AnyBlock, DataBlockId};
10
11/// Durability data of a crafted item
12#[derive(PartialEq, Eq, Clone, Hash, Debug)]
13#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
14pub struct DurabilityData {
15    /// The effect strength of the item is the overall effectiveness of the identifications on the item. (the percentage shown next to the item name)
16    // TODO: fix misspelling in the next minor version
17    pub effect_strenght: u8,
18    /// Current durability of the item
19    pub current: i32,
20    /// Maximum durability of the item
21    pub max: i32,
22}
23
24impl BlockId for DurabilityData {
25    fn block_id(&self) -> DataBlockId {
26        DataBlockId::DurabilityData
27    }
28}
29
30impl DataEncoder for DurabilityData {
31    fn encode_data(&self, ver: EncodingVersion, out: &mut Vec<u8>) -> Result<(), EncodeError> {
32        match ver {
33            EncodingVersion::V1 | EncodingVersion::V2 => {
34                // Wynntils does not check this invariant during decoding. So lets just ignore it for fun
35                // if self.effect_strenght > 100 {
36                //     return Err(EncodeError::EffectStrengthTooHigh(self.effect_strenght));
37                // }
38
39                out.push(self.effect_strenght);
40
41                out.append(&mut encode_varint(self.max));
42
43                out.append(&mut encode_varint(self.current));
44
45                Ok(())
46            }
47        }
48    }
49}
50
51impl DataDecoder for DurabilityData {
52    fn decode_data(
53        bytes: &mut impl Iterator<Item = u8>,
54        ver: EncodingVersion,
55    ) -> Result<Self, DecodeError>
56    where
57        Self: Sized,
58    {
59        match ver {
60            EncodingVersion::V1 | EncodingVersion::V2 => {
61                let effect_strenght = bytes.next().ok_or(DecodeError::UnexpectedEndOfBytes)?;
62
63                let max = decode_varint(bytes)? as i32;
64
65                let current = decode_varint(bytes)? as i32;
66
67                Ok(Self {
68                    effect_strenght,
69                    current,
70                    max,
71                })
72            }
73        }
74    }
75}
76
77impl From<DurabilityData> for AnyBlock {
78    fn from(data: DurabilityData) -> Self {
79        AnyBlock::DurabilityData(data)
80    }
81}