JaneDoe-ZS/nap_gameserver/src/logic/game/frontend.rs

105 lines
3.1 KiB
Rust

use data::tables::{AvatarBaseID, MainCityBgmConfigID, SectionConfigID};
use proto::*;
use thiserror::Error;
use crate::logic::{
math::Vector3f,
scene::{SceneUnit, SceneUnitManager},
time::MainCityTime,
ESceneType,
};
use super::NapGameMode;
pub struct FrontendGame {
section_id: SectionConfigID,
frontend_avatar_id: AvatarBaseID,
main_city_bgm: MainCityBgmConfigID,
scene_unit_mgr: SceneUnitManager,
camera_x: u32,
camera_y: u32,
entry_transform: String,
main_city_time: MainCityTime,
avatar_pos: Vector3f,
avatar_rot: Vector3f,
}
#[derive(Error, Debug)]
pub enum FrontendGameError {
#[error("player's frontend avatar is None")]
NoFrontendAvatar,
}
impl FrontendGame {
const DEFAULT_BGM_ID: u32 = 1005;
pub fn new(
section_id: SectionConfigID,
avatar_id: AvatarBaseID,
main_city_time: MainCityTime,
avatar_pos: Vector3f,
avatar_rot: Vector3f,
) -> Result<Self, FrontendGameError> {
let instance = Self {
section_id,
main_city_time,
main_city_bgm: MainCityBgmConfigID::new_unchecked(Self::DEFAULT_BGM_ID),
scene_unit_mgr: SceneUnitManager::new(section_id),
frontend_avatar_id: avatar_id,
camera_x: 0xFFFFFFFF,
camera_y: 0xFFFFFFFF,
entry_transform: section_id.template().primary_entry_name.clone(),
avatar_pos,
avatar_rot,
};
tracing::info!("creating new frontend game (section={section_id}, avatar={avatar_id})");
Ok(instance)
}
pub fn set_entry_transform(&mut self, transform_name: String) {
self.entry_transform = transform_name;
}
}
impl NapGameMode for FrontendGame {
fn scene_info(&self) -> Option<SceneInfo> {
Some(SceneInfo {
scene_type: self.scene_type() as u32,
hall_scene_info: Some(HallSceneInfo {
section_id: self.section_id.value(),
frontend_avatar_id: self.frontend_avatar_id.value(),
main_city_bgm_id: self.main_city_bgm.value(),
camera_x: self.camera_x,
camera_y: self.camera_y,
transform: self
.avatar_pos
.is_zero()
.then_some(self.entry_transform.clone())
.unwrap_or_default(),
day_of_week: self.main_city_time.day_of_week.value(),
time_of_day: self.main_city_time.time_of_day.value(),
position: (!self.avatar_pos.is_zero()).then_some(Transform {
position: self.avatar_pos.to_vec(),
rotation: self.avatar_rot.to_vec(),
}),
scene_unit_list: self
.scene_unit_mgr
.unit_vec
.iter()
.map(SceneUnit::protocol_info)
.collect(),
..Default::default()
}),
..Default::default()
})
}
fn dungeon_info(&self) -> Option<DungeonInfo> {
None
}
fn scene_type(&self) -> ESceneType {
ESceneType::Hall
}
}