use data::tables::AvatarBaseID; use proto::{AvatarBin, AvatarInfo, AvatarSkillInfo}; use crate::logic::item::ItemUID; use super::AvatarSkill; pub const AVATAR_TALENT_COUNT: usize = 6; pub struct Avatar { pub template_id: AvatarBaseID, pub level: u32, pub exp: u32, pub star: u32, pub rank: u32, pub unlocked_talent_num: u32, pub weapon_uid: Option, pub skill_list: Vec, pub talent_switch: [bool; AVATAR_TALENT_COUNT], } impl Avatar { pub fn new(template_id: AvatarBaseID) -> Self { Self { template_id, level: 60, exp: 0, star: 0, rank: 6, unlocked_talent_num: 6, weapon_uid: None, skill_list: (0..=6) .map(|st| AvatarSkill { skill_type: st, level: 1, }) .collect(), talent_switch: [true; AVATAR_TALENT_COUNT], } } pub fn from_bin(bin: AvatarBin) -> Self { Self { template_id: AvatarBaseID::new_unchecked(bin.template_id), level: bin.level, exp: bin.exp, star: bin.star, rank: bin.rank, unlocked_talent_num: bin.unlocked_talent_num, weapon_uid: (bin.weapon_uid != 0).then_some(bin.weapon_uid.into()), skill_list: bin .avatar_skill_list .into_iter() .map(AvatarSkill::from_bin) .collect(), talent_switch: bin .talent_switch_list .try_into() .unwrap_or([false; AVATAR_TALENT_COUNT]), } } pub fn to_bin(&self) -> AvatarBin { AvatarBin { template_id: self.template_id.value(), exp: self.exp, level: self.level, star: self.star, rank: self.rank, unlocked_talent_num: self.unlocked_talent_num, weapon_uid: self.weapon_uid.map(|u| u.value()).unwrap_or_default(), avatar_skill_list: self.skill_list.iter().map(AvatarSkill::to_bin).collect(), talent_switch_list: self.talent_switch.to_vec(), } } pub fn to_client(&self) -> AvatarInfo { AvatarInfo { template_id: self.template_id.value(), level: self.level, skill_list: self .skill_list .iter() .map(|s| AvatarSkillInfo { skill_type: s.skill_type, level: s.level, }) .collect(), exp: self.exp, rank: self.rank, talent_switch_list: self.talent_switch.to_vec(), unlocked_talent_num: self.unlocked_talent_num, cur_weapon_uid: self.weapon_uid.map(|u| u.value()).unwrap_or_default(), ..Default::default() } } }