diff --git a/src/bin/main.rs b/src/bin/main.rs index cf6f702..4fa2a60 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -89,6 +89,24 @@ fn main() { equipped: true, } }).await; + entity_gateway.create_item( + NewItemEntity { + item: ItemDetail::Weapon( + item::weapon::Weapon { + weapon: item::weapon::WeaponType::Autogun, + grind: 5, + special: Some(item::weapon::WeaponSpecial::Hell), + attrs: [Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Hit, value: 70}), + Some(item::weapon::WeaponAttribute{attr: item::weapon::Attribute::Dark, value: 80}), + None,], + tekked: false, + } + ), + location: ItemLocation::Bank { + character_id: character.id, + name: item::BankName("".to_string()), + } + }).await; } let patch = async_std::task::spawn(async { diff --git a/src/ship/items/manager.rs b/src/ship/items/manager.rs index b51afce..e586e69 100644 --- a/src/ship/items/manager.rs +++ b/src/ship/items/manager.rs @@ -438,7 +438,7 @@ impl ItemManager { -> Result { let room_id = self.character_room.get(&character.id).ok_or(ItemManagerError::NoCharacter(character.id))?; let shared_floor = self.room_floor.get_mut(&room_id).ok_or(ItemManagerError::NoCharacter(character.id))?; - if character.meseta <= amount { + if character.meseta < amount { return Err(ItemManagerError::CouldNotDropMeseta) } character.meseta -= amount; diff --git a/src/ship/map.rs b/src/ship/map.rs index 7bdc779..f37ebbf 100644 --- a/src/ship/map.rs +++ b/src/ship/map.rs @@ -374,11 +374,11 @@ pub enum MapArea { #[derive(Error, Debug)] #[error("")] pub enum MapAreaError { - UnknownMapArea(u32), + UnknownMapArea(u16), } impl MapArea { - pub fn from_value(episode: &Episode, area: u32) -> Result { + pub fn from_value(episode: &Episode, area: u16) -> Result { match (episode, area) { (Episode::One, 0) => Ok(MapArea::Pioneer2Ep1), (Episode::One, 1) => Ok(MapArea::Forest1), diff --git a/src/ship/packet/builder/message.rs b/src/ship/packet/builder/message.rs index 1fc85da..331b833 100644 --- a/src/ship/packet/builder/message.rs +++ b/src/ship/packet/builder/message.rs @@ -12,7 +12,7 @@ pub fn item_drop(client: u8, target: u8, item_drop: &FloorItem) -> Result Resu target: 0, client_id: area_client.local_client.id(), unknown: 0, - area: item.map_area().area_value(), + map_area: item.map_area().area_value(), unknown2: 0, item_id: item.item_id().0, }) diff --git a/src/ship/packet/handler/message.rs b/src/ship/packet/handler/message.rs index 4df5e62..5b2622f 100644 --- a/src/ship/packet/handler/message.rs +++ b/src/ship/packet/handler/message.rs @@ -82,7 +82,7 @@ where .ok_or_else(|| ShipError::InvalidRoom(room_id.0 as u32))? .as_mut() .ok_or_else(|| ShipError::InvalidRoom(room_id.0 as u32))?; - let area = MapArea::from_value(&room.mode.episode(), player_drop_item.area as u32)?; + let area = MapArea::from_value(&room.mode.episode(), player_drop_item.map_area)?; item_manager.player_drop_item_on_shared_floor(entity_gateway, &client.character, ClientItemId(player_drop_item.item_id), (area, player_drop_item.x, player_drop_item.y, player_drop_item.z)).await?; let clients_in_area = client_location.get_clients_in_room(room_id).map_err(|err| -> ClientLocationError { err.into() })?; let pdi = player_drop_item.clone(); @@ -178,14 +178,14 @@ pub fn update_player_position(id: ClientId, GameMessage::PlayerChangedMap(p) => {client.x = p.x; client.y = p.y; client.z = p.z;}, GameMessage::PlayerChangedMap2(p) => {client.area = MapArea::from_value(&room.mode.episode(), p.map_area).ok();}, GameMessage::TellOtherPlayerMyLocation(p) => {client.x = p.x; client.y = p.y; client.z = p.z; client.area = MapArea::from_value(&room.mode.episode(), p.map_area).ok();}, - GameMessage::PlayerWarpingToFloor(p) => {client.area = MapArea::from_value(&room.mode.episode(), p.area as u32).ok();}, + GameMessage::PlayerWarpingToFloor(p) => {client.area = MapArea::from_value(&room.mode.episode(), p.area as u16).ok();}, GameMessage::PlayerTeleported(p) => {client.x = p.x; client.y = p.y; client.z = p.z;}, GameMessage::PlayerStopped(p) => {client.x = p.x; client.y = p.y; client.z = p.z;}, GameMessage::PlayerLoadedIn(p) => {client.x = p.x; client.y = p.y; client.z = p.z;}, GameMessage::PlayerWalking(p) => {client.x = p.x; client.z = p.z;}, GameMessage::PlayerRunning(p) => {client.x = p.x; client.z = p.z;}, GameMessage::PlayerWarped(p) => {client.x = p.x; client.y = p.y;}, - GameMessage::PlayerChangedFloor(p) => {client.area = MapArea::from_value(&room.mode.episode(), p.map).ok();}, + // GameMessage::PlayerChangedFloor(p) => {client.area = MapArea::from_value(&room.mode.episode(), p.map).ok();}, GameMessage::InitializeSpeechNpc(p) => {client.x = p.x; client.z = p.z;} _ => {}, } diff --git a/src/ship/quests.rs b/src/ship/quests.rs index f7dfd6e..74072e0 100644 --- a/src/ship/quests.rs +++ b/src/ship/quests.rs @@ -62,7 +62,8 @@ enum DatBlock { fn read_dat_section_header(cursor: &mut T, episode: &Episode) -> Result { let header = cursor.read_u32::()?; let _offset = cursor.read_u32::()?; - let area = cursor.read_u32::()?; + let area = cursor.read_u16::()?; + let _unknown1 = cursor.read_u16::()?; let length = cursor.read_u32::()?; let map_area = MapArea::from_value(episode, area)?; diff --git a/tests/test_item_pickup.rs b/tests/test_item_pickup.rs index 4e70915..f582d25 100644 --- a/tests/test_item_pickup.rs +++ b/tests/test_item_pickup.rs @@ -63,7 +63,7 @@ async fn test_pick_up_item_stack_of_items_already_in_inventory() { client: 0, target: 0, unknown1: 0, - area: 0, + map_area: 0, item_id: 0x210000, x: 0.0, y: 0.0, @@ -74,7 +74,7 @@ async fn test_pick_up_item_stack_of_items_already_in_inventory() { client: 0, target: 0, item_id: 0x210000, - area: 0, + map_area: 0, unknown: [0; 3] })))).await.unwrap().for_each(drop); @@ -130,7 +130,7 @@ async fn test_pick_up_item_stack_of_items_not_already_held() { client: 0, target: 0, unknown1: 0, - area: 0, + map_area: 0, item_id: 0x210000, x: 0.0, y: 0.0, @@ -141,7 +141,7 @@ async fn test_pick_up_item_stack_of_items_not_already_held() { client: 0, target: 0, item_id: 0x210000, - area: 0, + map_area: 0, unknown: [0; 3] })))).await.unwrap().for_each(drop); @@ -200,6 +200,7 @@ async fn test_pick_up_meseta_when_inventory_full() { target: 0, item_id: 0xFFFFFFFF, map_area: 0, + room: 0, x: 0.0, z: 0.0, })))).await.unwrap().for_each(drop); @@ -215,7 +216,7 @@ async fn test_pick_up_meseta_when_inventory_full() { client: 0, target: 0, item_id: 0xF0000001, - area: 0, + map_area: 0, unknown: [0; 3] })))).await.unwrap().for_each(drop); @@ -298,7 +299,7 @@ async fn test_pick_up_partial_stacked_item_when_inventory_is_otherwise_full() { client: 0, target: 0, unknown1: 0, - area: 0, + map_area: 0, item_id: 0x210000, x: 0.0, y: 0.0, @@ -309,7 +310,7 @@ async fn test_pick_up_partial_stacked_item_when_inventory_is_otherwise_full() { client: 0, target: 0, item_id: 0x210000, - area: 0, + map_area: 0, unknown: [0; 3] })))).await.unwrap().for_each(drop); @@ -385,7 +386,7 @@ async fn test_can_not_pick_up_item_when_inventory_full() { client: 0, target: 0, unknown1: 0, - area: 0, + map_area: 0, item_id: 0x210000, x: 0.0, y: 0.0, @@ -396,7 +397,7 @@ async fn test_can_not_pick_up_item_when_inventory_full() { client: 0, target: 0, item_id: 0x210000, - area: 0, + map_area: 0, unknown: [0; 3] })))).await.unwrap().for_each(drop); @@ -410,7 +411,7 @@ async fn test_can_not_pick_up_item_when_inventory_full() { client: 0, target: 0, item_id: 0x210000, - area: 0, + map_area: 0, unknown: [0; 3] })))).await.unwrap().for_each(drop); @@ -439,6 +440,7 @@ async fn test_can_not_drop_more_meseta_than_is_held() { target: 0, item_id: 0xFFFFFFFF, map_area: 0, + room: 0, x: 0.0, z: 0.0, })))).await.unwrap().for_each(drop); @@ -508,7 +510,7 @@ async fn test_pick_up_stack_that_would_exceed_stack_limit() { client: 0, target: 0, unknown1: 0, - area: 0, + map_area: 0, item_id: 0x210000, x: 0.0, y: 0.0, @@ -519,7 +521,7 @@ async fn test_pick_up_stack_that_would_exceed_stack_limit() { client: 0, target: 0, item_id: 0x210000, - area: 0, + map_area: 0, unknown: [0; 3] })))).await.unwrap().collect::>(); assert!(packets.len() == 0); @@ -558,6 +560,7 @@ async fn test_can_not_pick_up_meseta_when_full() { target: 0, item_id: 0xFFFFFFFF, map_area: 0, + room: 0, x: 0.0, z: 0.0, })))).await.unwrap().for_each(drop); @@ -573,7 +576,7 @@ async fn test_can_not_pick_up_meseta_when_full() { client: 0, target: 0, item_id: 0xF0000001, - area: 0, + map_area: 0, unknown: [0; 3] })))).await.unwrap().collect::>(); println!("pkts {:?}", packets); @@ -614,6 +617,7 @@ async fn test_meseta_caps_at_999999_when_trying_to_pick_up_more() { target: 0, item_id: 0xFFFFFFFF, map_area: 0, + room: 0, x: 0.0, z: 0.0, })))).await.unwrap().for_each(drop); @@ -629,7 +633,7 @@ async fn test_meseta_caps_at_999999_when_trying_to_pick_up_more() { client: 0, target: 0, item_id: 0xF0000001, - area: 0, + map_area: 0, unknown: [0; 3] })))).await.unwrap().for_each(drop); @@ -679,6 +683,7 @@ async fn test_player_drops_partial_stack_and_other_player_picks_it_up() { target: 0, item_id: 0x10000, map_area: 0, + room: 0, x: 0.0, z: 0.0, })))).await.unwrap().for_each(drop); @@ -694,7 +699,7 @@ async fn test_player_drops_partial_stack_and_other_player_picks_it_up() { client: 0, target: 0, item_id: 0xF0000001, - area: 0, + map_area: 0, unknown: [0; 3] })))).await.unwrap().for_each(drop);