use libpso::packet::ship::*; use crate::common::serverstate::ClientId; use crate::common::leveltable::CharacterLevelTable; use crate::ship::ship::{ShipError, ClientState, Clients}; use crate::ship::location::{ClientLocation, RoomId, AreaClient, ClientLocationError}; use crate::ship::room::RoomState; use crate::ship::items::ItemManager; use crate::ship::packet::builder::{player_header, player_info}; use std::convert::TryInto; pub fn join_room(id: ClientId, clients: &Clients, client_location: &ClientLocation, room_id: RoomId, room: &RoomState) -> Result { let all_clients = client_location.get_clients_in_room(room_id).map_err(|err| -> ClientLocationError { err.into() })?; let players = all_clients.iter() .enumerate() .fold(Ok([PlayerHeader::default(); 4]), |acc, (i, c)| -> Result<_, ShipError> { let header_client = clients.get(&c.client).ok_or(ShipError::ClientNotFound(id))?; let header_area_client = client_location.get_local_client(id).map_err(|err| -> ClientLocationError { err.into() })?; acc.map(|mut a| { a[i] = player_header(0x10000, header_client, &header_area_client); a }) })?; let area_client = client_location.get_local_client(id).map_err(|err| -> ClientLocationError { err.into() })?; let leader = client_location.get_room_leader(room_id).map_err(|err| -> ClientLocationError { err.into() })?; Ok(JoinRoom { flag: all_clients.len() as u32, maps: room.maps.map_headers(), players, client: area_client.local_client.id(), leader: leader.local_client.id(), one: 1, difficulty: room.mode.difficulty().into(), battle: room.mode.battle(), event: 0, section: room.section_id.into(), challenge: room.mode.challenge(), random_seed: room.random_seed, episode: room.mode.episode().into(), one2: 1, single_player: room.mode.single_player(), unknown: 0, }) } pub fn add_to_room(_id: ClientId, client: &ClientState, area_client: &AreaClient, leader: &AreaClient, item_manager: &ItemManager, level_table: &CharacterLevelTable, _room_id: RoomId, ) -> Result { Ok(AddToRoom { flag: 1, client: area_client.local_client.id(), leader: leader.local_client.id(), one: 0, // TODO: ???????? lobby: 0xFF, block: 0, event: 0, padding: 0, playerinfo: player_info(0x10000, client, area_client, item_manager, level_table), }) } pub fn build_rare_monster_list(rare_monster_vec: Vec) -> RareMonsterList { RareMonsterList { ids: rare_monster_vec.try_into().unwrap_or([0xFFFFu16; 16]), } }