Browse Source

box drops working and load correct city file

pbs
Andy Newjack 4 years ago
parent
commit
dcc5b57b8e
  1. 28
      src/ship/map.rs
  2. 53
      src/ship/packet/handler/direct_message.rs
  3. 5
      src/ship/ship.rs

28
src/ship/map.rs

@ -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()

53
src/ship/packet/handler/direct_message.rs

@ -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()))
}

5
src/ship/ship.rs

@ -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…
Cancel
Save