box drops working and load correct city file
This commit is contained in:
		
							parent
							
								
									a8892467f6
								
							
						
					
					
						commit
						dcc5b57b8e
					
				@ -217,7 +217,7 @@ struct RawMapObject {
 | 
			
		||||
 | 
			
		||||
impl RawMapObject {
 | 
			
		||||
    fn from_byte_stream<R: Read>(cursor: &mut R) -> Result<RawMapObject, std::io::Error> {
 | 
			
		||||
        Ok(RawMapObject {
 | 
			
		||||
        let o = RawMapObject {
 | 
			
		||||
            otype: cursor.read_u16::<LittleEndian>()?,
 | 
			
		||||
            unknown1: cursor.read_u16::<LittleEndian>()?,
 | 
			
		||||
            unknown2: cursor.read_u32::<LittleEndian>()?,
 | 
			
		||||
@ -238,7 +238,11 @@ impl RawMapObject {
 | 
			
		||||
            field5: cursor.read_u32::<LittleEndian>()?,
 | 
			
		||||
            field6: cursor.read_u32::<LittleEndian>()?,
 | 
			
		||||
            field7: cursor.read_u32::<LittleEndian>()?,
 | 
			
		||||
        })
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        println!("{:?}", o);
 | 
			
		||||
 | 
			
		||||
        Ok(o)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -310,6 +314,8 @@ pub enum MapObjectType {
 | 
			
		||||
#[derive(Debug, Copy, Clone)]
 | 
			
		||||
pub struct MapObject {
 | 
			
		||||
    pub object: MapObjectType,
 | 
			
		||||
    pub map: MapArea,
 | 
			
		||||
    pub dropped_item: bool,
 | 
			
		||||
    //id: u32,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -320,7 +326,7 @@ enum MapObjectError {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
impl MapObject {
 | 
			
		||||
    fn from_raw(raw: RawMapObject, episode: Episode) -> Result<MapObject, MapObjectError> {
 | 
			
		||||
    fn from_raw(raw: RawMapObject, episode: Episode, map_area: &MapArea) -> Result<MapObject, MapObjectError> {
 | 
			
		||||
        let object = match (raw, episode) {
 | 
			
		||||
            (RawMapObject {otype: 136, ..}, _) => MapObjectType::Box,
 | 
			
		||||
            (RawMapObject {otype: 145, ..}, _) => MapObjectType::EnemyBox,
 | 
			
		||||
@ -335,8 +341,11 @@ impl MapObject {
 | 
			
		||||
            _ => return Err(MapObjectError::UnknownObjectType(raw.otype, raw))
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        println!("{:#?}", object);
 | 
			
		||||
        Ok(MapObject {
 | 
			
		||||
            object: object,
 | 
			
		||||
            map: map_area.clone(),
 | 
			
		||||
            dropped_item: false,
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -496,7 +505,7 @@ impl MapVariant {
 | 
			
		||||
 | 
			
		||||
    fn obj_file(&self) -> String {
 | 
			
		||||
        match self.map {
 | 
			
		||||
            MapArea::Pioneer2Ep1 => "data/maps/map_city00_00e.dat".into(),
 | 
			
		||||
            MapArea::Pioneer2Ep1 => "data/maps/map_city00_00o.dat".into(),
 | 
			
		||||
            MapArea::Forest1 => format!("data/maps/map_forest01_0{}o.dat", self.minor),
 | 
			
		||||
            MapArea::Forest2 => format!("data/maps/map_forest02_0{}o.dat", self.minor),
 | 
			
		||||
            MapArea::Caves1 => format!("data/maps/map_cave01_0{}_0{}o.dat", self.major, self.minor),
 | 
			
		||||
@ -520,12 +529,12 @@ impl MapVariant {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
fn objects_from_map_data(path: PathBuf, episode: &Episode) -> Vec<Option<MapObject>> {
 | 
			
		||||
fn objects_from_map_data(path: PathBuf, episode: &Episode, map_variant: &MapVariant) -> Vec<Option<MapObject>> {
 | 
			
		||||
    let mut cursor = File::open(path.clone()).unwrap();
 | 
			
		||||
    let mut object_data = Vec::new();
 | 
			
		||||
 | 
			
		||||
    while let Ok(raw_object) = RawMapObject::from_byte_stream(&mut cursor) {
 | 
			
		||||
        let object = MapObject::from_raw(raw_object.clone(), *episode);
 | 
			
		||||
        let object = MapObject::from_raw(raw_object.clone(), *episode, &map_variant.map);
 | 
			
		||||
        object_data.push(object.ok());
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
@ -631,6 +640,7 @@ fn enemy_data_from_map_data(map_variant: &MapVariant, episode: &Episode) -> Vec<
 | 
			
		||||
#[error("")]
 | 
			
		||||
pub enum MapsError {
 | 
			
		||||
    InvalidMonsterId(usize),
 | 
			
		||||
    InvalidObjectId(usize),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug)]
 | 
			
		||||
@ -670,7 +680,7 @@ impl Maps {
 | 
			
		||||
                enemy_data
 | 
			
		||||
            }),
 | 
			
		||||
            object_data: map_variants.iter().map(|map_variant| {
 | 
			
		||||
                objects_from_map_data(map_variant.obj_file().into(), &episode)
 | 
			
		||||
                objects_from_map_data(map_variant.obj_file().into(), &episode, &map_variant)
 | 
			
		||||
            }).flatten().collect(),
 | 
			
		||||
            map_variants: map_variants,
 | 
			
		||||
        };
 | 
			
		||||
@ -682,6 +692,10 @@ impl Maps {
 | 
			
		||||
        self.enemy_data[id].ok_or(MapsError::InvalidMonsterId(id))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn object_by_id(&self, id: usize) -> Result<MapObject, MapsError> {
 | 
			
		||||
        self.object_data[id].ok_or(MapsError::InvalidObjectId(id))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn map_headers(&self) -> [u32; 0x20] {
 | 
			
		||||
        self.map_variants.iter()
 | 
			
		||||
            .enumerate()
 | 
			
		||||
 | 
			
		||||
@ -139,3 +139,56 @@ where
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn request_box_item<EG>(id: ClientId,
 | 
			
		||||
    box_drop_request: &BoxDropRequest,
 | 
			
		||||
    entity_gateway: &mut EG,
 | 
			
		||||
    client_location: &ClientLocation,
 | 
			
		||||
    clients: &mut Clients,
 | 
			
		||||
    rooms: &mut Rooms,
 | 
			
		||||
    item_manager: &mut ItemManager)
 | 
			
		||||
    -> Result<Box<dyn Iterator<Item = (ClientId, SendShipPacket)> + Send>, ShipError>
 | 
			
		||||
where
 | 
			
		||||
EG: EntityGateway
 | 
			
		||||
{
 | 
			
		||||
    let room_id = client_location.get_room(id).map_err(|err| -> ClientLocationError { err.into() })?;
 | 
			
		||||
    let room = rooms.get_mut(room_id.0)
 | 
			
		||||
        .ok_or_else(|| ShipError::InvalidRoom(room_id.0 as u32))?
 | 
			
		||||
        .as_mut()
 | 
			
		||||
        .ok_or_else(|| ShipError::InvalidRoom(room_id.0 as u32))?;
 | 
			
		||||
 | 
			
		||||
    let box_object = room.maps.object_by_id(box_drop_request.object_id as usize)?;
 | 
			
		||||
    if box_object.dropped_item {
 | 
			
		||||
        return Err(ShipError::BoxAlreadyDroppedItem(id, box_drop_request.object_id))
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let clients_in_area = client_location.get_clients_in_room(room_id).map_err(|err| -> ClientLocationError { err.into() })?;
 | 
			
		||||
 | 
			
		||||
    let item_drop_packets = clients_in_area.into_iter()
 | 
			
		||||
        .filter_map(|area_client| {
 | 
			
		||||
            room.drop_table.get_box_drop(&box_object.map, &box_object).map(|item_drop_type| {
 | 
			
		||||
                warn!("drop is? {:?}", item_drop_type);
 | 
			
		||||
                (area_client, item_drop_type)
 | 
			
		||||
            })
 | 
			
		||||
        })
 | 
			
		||||
        .map(|(area_client, item_drop_type)| -> Result<_, ShipError> {
 | 
			
		||||
            let item_drop = ItemDrop {
 | 
			
		||||
                map_area: box_object.map,
 | 
			
		||||
                x: box_drop_request.x,
 | 
			
		||||
                y: 0.0,
 | 
			
		||||
                z: box_drop_request.z,
 | 
			
		||||
                item: item_drop_type,
 | 
			
		||||
            };
 | 
			
		||||
            let client = clients.get_mut(&area_client.client).ok_or(ShipError::ClientNotFound(area_client.client))?;
 | 
			
		||||
            let floor_item = item_manager.drop_item_on_local_floor(entity_gateway, &client.character, item_drop).unwrap(); // TODO: unwrap
 | 
			
		||||
            let item_drop_msg = builder::message::item_drop(box_drop_request.client, box_drop_request.target, &floor_item)?;
 | 
			
		||||
            client.floor_items.push(floor_item);
 | 
			
		||||
            Ok((area_client.client, SendShipPacket::Message(Message::new(GameMessage::ItemDrop(item_drop_msg)))))
 | 
			
		||||
        })
 | 
			
		||||
        .filter_map(|item_drop_pkt| {
 | 
			
		||||
            // TODO: log errors here
 | 
			
		||||
            item_drop_pkt.ok()
 | 
			
		||||
        })
 | 
			
		||||
        .collect::<Vec<_>>(); // TODO: can EntityGateway be Sync?
 | 
			
		||||
 | 
			
		||||
    Ok(Box::new(item_drop_packets.into_iter()))
 | 
			
		||||
}
 | 
			
		||||
@ -50,6 +50,7 @@ pub enum ShipError {
 | 
			
		||||
    DropInvalidItemId(u32),
 | 
			
		||||
    ItemManagerError(#[from] items::ItemManagerError),
 | 
			
		||||
    ItemDropLocationNotSet,
 | 
			
		||||
    BoxAlreadyDroppedItem(ClientId, u16),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Debug)]
 | 
			
		||||
@ -247,6 +248,10 @@ impl<EG: EntityGateway> ShipServerState<EG> {
 | 
			
		||||
            GameMessage::PickupItem(pickup_item) => {
 | 
			
		||||
                handler::direct_message::pickup_item(id, pickup_item, &mut self.entity_gateway, &mut self.client_location, &mut self.clients, &mut self.item_manager).unwrap()
 | 
			
		||||
            },
 | 
			
		||||
            GameMessage::BoxDropRequest(box_drop_request) => {
 | 
			
		||||
                println!("box drop requested!");
 | 
			
		||||
                handler::direct_message::request_box_item(id, box_drop_request, &mut self.entity_gateway, &mut self.client_location, &mut self.clients, &mut self.rooms, &mut self.item_database).unwrap()
 | 
			
		||||
            }
 | 
			
		||||
            _ => {
 | 
			
		||||
                let cmsg = msg.clone();
 | 
			
		||||
                Box::new(self.client_location.get_all_clients_by_client(id).unwrap().into_iter()
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user