JaneDoe-ZS/nap_gameserver/src/logic/player/player.rs

133 lines
4.2 KiB
Rust

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<u64>,
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<u64> {
self.current_session_id
}
}