use std::{ cell::RefCell, collections::BTreeMap, rc::{Rc, Weak}, }; use data::math_def::Vector3; use proto::{DungeonProductBin, EnterType, PlayerSceneCompBin, SceneProductBin, VisionType}; use tokio::sync::OnceCell; use crate::player::Player; use super::{PlayerWorld, Scene}; #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default)] #[allow(non_camel_case_types)] pub enum EnterSceneState { #[default] ENTER_SCENE_NONE, ENTER_SCENE_NOTIFY, ENTER_SCENE_READY, ENTER_SCENE_INIT, ENTER_SCENE_DONE, ENTER_SCENE_POST, } #[derive(Default)] pub struct PlayerSceneComp { player: OnceCell>, pub own_world: Rc>, pub cur_scene_owner_uid: u32, pub my_prev_scene_id: u32, pub my_prev_pos: Vector3, pub my_prev_rot: Vector3, pub my_cur_scene_id: u32, pub monster_seen_list: Vec, //pub mark_point_list: Vec, pub world_product_map: BTreeMap, pub my_cur_area_id: u32, pub dungeon_product_map: BTreeMap, pub my_cur_player_scene_id: u32, pub my_cur_home_scene_id: u32, pub cur_scene_id: u32, pub cur_scene_wtr: Weak>, pub dest_scene_id: u32, pub dest_pos: Vector3, pub dest_rot: Vector3, pub dest_enter_type: EnterType, pub dest_vision_type: VisionType, pub dest_world_ptr: Option>>, pub dest_scene_wtr: Weak>, pub enter_scene_state: EnterSceneState, pub enter_scene_token: u32, } impl PlayerSceneComp { pub fn set_player(&self, player: Rc) { self.own_world.borrow_mut().set_player(player.clone()); self.player.set(Rc::downgrade(&player)).unwrap(); } pub fn init(&mut self) { self.own_world.borrow_mut().init(); } pub fn pre_login(&mut self, is_relogin: bool) { self.own_world.borrow_mut().pre_player_login(is_relogin); } pub fn on_login(&mut self, _is_new_player: bool) { self.reset_dest_scene(); } pub fn on_first_login(&mut self) { let mut world = self.own_world.borrow_mut(); let main_world_scene = world.scene_map.get_mut(&3).unwrap(); main_world_scene .borrow_mut() .base_mut() .set_player_last_valid_location_on_first_login(); } pub fn set_dest_scene(&mut self, scene_wtr: Weak>) { if let Some(scene) = scene_wtr.upgrade() { self.dest_scene_id = scene.borrow().base().scene_id; self.dest_scene_wtr = scene_wtr; } else { self.dest_scene_wtr = Weak::new(); self.dest_scene_id = 0; } } pub fn get_dest_scene(&self) -> Option>> { self.dest_scene_wtr.upgrade() } pub fn get_cur_scene(&self) -> Option>> { self.cur_scene_wtr.upgrade() } fn reset_dest_scene(&mut self) { self.dest_scene_wtr = Weak::new(); self.dest_scene_id = 0; self.dest_pos.reset(); self.dest_rot.reset(); } pub fn from_bin(bin: PlayerSceneCompBin) -> Self { Self { player: OnceCell::new(), own_world: Rc::new(RefCell::new(PlayerWorld::from_bin( bin.world.unwrap_or_default(), ))), cur_scene_owner_uid: bin.cur_scene_owner_uid, my_prev_scene_id: bin.my_prev_scene_id, my_prev_pos: Vector3::from_bin(bin.my_prev_pos.unwrap_or_default()), my_prev_rot: Vector3::from_bin(bin.my_prev_rot.unwrap_or_default()), my_cur_scene_id: bin.my_cur_scene_id, monster_seen_list: bin.monster_seen_list, world_product_map: bin.world_product_map.into_iter().collect(), my_cur_area_id: bin.my_cur_area_id, dungeon_product_map: bin.dungeon_product_map.into_iter().collect(), my_cur_player_scene_id: bin.my_cur_player_scene_id, my_cur_home_scene_id: bin.my_cur_home_scene_id, ..Default::default() } } pub fn to_bin(&self) -> PlayerSceneCompBin { PlayerSceneCompBin { world: Some(self.own_world.borrow().to_bin()), cur_scene_owner_uid: self.cur_scene_owner_uid.clone(), my_prev_scene_id: self.my_prev_scene_id.clone(), my_prev_pos: Some(self.my_prev_pos.to_bin()), my_prev_rot: Some(self.my_prev_rot.to_bin()), my_cur_scene_id: self.my_cur_scene_id.clone(), monster_seen_list: self.monster_seen_list.clone(), world_product_map: self.world_product_map.clone().into_iter().collect(), my_cur_area_id: self.my_cur_area_id.clone(), dungeon_product_map: self.dungeon_product_map.clone().into_iter().collect(), my_cur_player_scene_id: self.my_cur_player_scene_id.clone(), my_cur_home_scene_id: self.my_cur_home_scene_id.clone(), ..Default::default() } } }