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