use data::tables::{self, AvatarBaseID}; use proto::{ItemStatic, PlayerDataBin, Retcode}; use super::game::{FrontendGame, FrontendGameError, GameInstance, LogicError}; use super::item::{ItemModel, ItemUID}; use super::main_city_model::MainCityModel; use super::role::RoleModel; use super::{BasicDataModel, LockModel}; #[derive(Default)] pub struct Player { current_session_id: Option, pub game_instance: GameInstance, pub basic_data_model: BasicDataModel, pub lock_model: LockModel, pub role_model: RoleModel, pub item_model: ItemModel, pub main_city_model: MainCityModel, } impl Player { const MAIN_AVATAR_IDS: [u32; 2] = [2011, 2021]; pub fn save_to_bin(&self) -> PlayerDataBin { PlayerDataBin { basic_data_model: Some(self.basic_data_model.to_bin()), lock_model: Some(self.lock_model.to_bin()), role_model: Some(self.role_model.to_bin()), item_model: Some(self.item_model.to_bin()), main_city_model: Some(self.main_city_model.to_bin()), } } pub fn load_from_bin(bin: PlayerDataBin) -> Self { Self { basic_data_model: bin .basic_data_model .map(BasicDataModel::from_bin) .unwrap_or_default(), lock_model: bin.lock_model.map(LockModel::from_bin).unwrap_or_default(), role_model: bin.role_model.map(RoleModel::from_bin).unwrap_or_default(), item_model: bin.item_model.map(ItemModel::from_bin).unwrap_or_default(), main_city_model: bin .main_city_model .map(MainCityModel::from_bin) .unwrap_or_default(), ..Default::default() } } pub fn on_login(&mut self) { tables::unlock_config_template_tb::iter() .for_each(|tmpl| self.lock_model.add_unlock(tmpl.id)) } pub fn on_first_login(&mut self) { self.item_model .add_resource(ItemStatic::FrontendGold as u32, 1_000_000); self.item_model .add_resource(ItemStatic::GameDiamond as u32, 1_000_000); self.item_model.add_resource(ItemStatic::Energy as u32, 240); } pub fn init_frontend_game(&mut self) -> Result<(), LogicError> { let Some(frontend_avatar_id) = self.basic_data_model.frontend_avatar_id else { return Err(LogicError::from(FrontendGameError::NoFrontendAvatar)); }; let main_city = &self.main_city_model; self.game_instance = GameInstance::Frontend( FrontendGame::new( main_city.section_id, frontend_avatar_id, main_city.main_city_time.clone(), main_city.position.clone(), main_city.rotation.clone(), ) .map_err(LogicError::from)?, ); Ok(()) } pub fn set_frontend_avatar(&mut self, id: AvatarBaseID) -> Result<(), Retcode> { (self.basic_data_model.frontend_avatar_id.is_none()) .then_some(()) .ok_or(Retcode::RetFail)?; (Self::MAIN_AVATAR_IDS.contains(&id.value())) .then_some(()) .ok_or(Retcode::RetFail)?; self.basic_data_model.frontend_avatar_id = Some(id); Ok(()) } pub fn dress_weapon( &mut self, avatar_id: AvatarBaseID, weapon_uid: ItemUID, ) -> Result<(), Retcode> { self.item_model .weapons .iter() .any(|w| w.uid == weapon_uid) .then_some(()) .ok_or(Retcode::RetFail)?; self.role_model .avatar_list .iter_mut() .filter(|a| a.weapon_uid.map(|u| u.value()).unwrap_or_default() == weapon_uid.value()) .for_each(|a| a.weapon_uid = None); let avatar = self .role_model .avatar_list .iter_mut() .find(|a| a.template_id == avatar_id) .ok_or(Retcode::RetFail)?; avatar.weapon_uid = Some(weapon_uid); Ok(()) } pub fn set_current_session(&mut self, id: u64) { self.current_session_id = Some(id); } pub fn current_session_id(&self) -> Option { self.current_session_id } }