You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

677 lines
24 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. use elseware::common::serverstate::{ClientId, ServerState};
  2. use elseware::entity::gateway::{EntityGateway, InMemoryGateway};
  3. use elseware::entity::item;
  4. use elseware::ship::ship::{ShipServerState, RecvShipPacket};
  5. use elseware::ship::items::{ClientItemId, ActiveItemEntityId, HeldItemType, FloorItemType};
  6. use libpso::packet::ship::*;
  7. use libpso::packet::messages::*;
  8. #[path = "common.rs"]
  9. mod common;
  10. use common::*;
  11. #[async_std::test]
  12. async fn test_pick_up_item_stack_of_items_already_in_inventory() {
  13. let mut entity_gateway = InMemoryGateway::new();
  14. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  15. let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  16. entity_gateway.create_item(
  17. item::NewItemEntity {
  18. item: item::ItemDetail::Tool(
  19. item::tool::Tool {
  20. tool: item::tool::ToolType::Monomate
  21. }
  22. ),
  23. location: item::ItemLocation::Inventory {
  24. character_id: char1.id,
  25. slot: 0,
  26. equipped: false,
  27. }
  28. }).await;
  29. for (slot, tool) in vec![item::tool::ToolType::Monomate, item::tool::ToolType::Monofluid].into_iter().enumerate() {
  30. for _ in 0..5 {
  31. entity_gateway.create_item(
  32. item::NewItemEntity {
  33. item: item::ItemDetail::Tool(
  34. item::tool::Tool {
  35. tool: tool
  36. }
  37. ),
  38. location: item::ItemLocation::Inventory {
  39. character_id: char2.id,
  40. slot: slot,
  41. equipped: false,
  42. }
  43. }).await;
  44. }
  45. }
  46. let mut ship = ShipServerState::new(entity_gateway.clone());
  47. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  48. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  49. join_lobby(&mut ship, ClientId(1)).await;
  50. join_lobby(&mut ship, ClientId(2)).await;
  51. create_room(&mut ship, ClientId(1), "room", "").await;
  52. join_room(&mut ship, ClientId(2), 0).await;
  53. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::PlayerDropItem(PlayerDropItem {
  54. client: 0,
  55. target: 0,
  56. unknown1: 0,
  57. area: 0,
  58. item_id: 0x210000,
  59. x: 0.0,
  60. y: 0.0,
  61. z: 0.0,
  62. })))).await.unwrap().for_each(drop);
  63. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  64. client: 0,
  65. target: 0,
  66. item_id: 0x210000,
  67. area: 0,
  68. unknown: [0; 3]
  69. })))).await.unwrap().for_each(drop);
  70. let p1_inventory = ship.item_manager.get_character_inventory(&char1).unwrap();
  71. assert!(p1_inventory.count() == 1);
  72. let inventory_item = p1_inventory.slot(0).unwrap();
  73. assert!(inventory_item.entity_id == ActiveItemEntityId::Stacked(vec![item::ItemEntityId(1), item::ItemEntityId(2), item::ItemEntityId(3), item::ItemEntityId(4), item::ItemEntityId(5), item::ItemEntityId(6)]));
  74. assert!(inventory_item.item == HeldItemType::Stacked(item::tool::Tool {tool: item::tool::ToolType::Monomate}, 6));
  75. }
  76. #[async_std::test]
  77. async fn test_pick_up_item_stack_of_items_not_already_held() {
  78. let mut entity_gateway = InMemoryGateway::new();
  79. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  80. let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  81. entity_gateway.create_item(
  82. item::NewItemEntity {
  83. item: item::ItemDetail::Tool(
  84. item::tool::Tool {
  85. tool: item::tool::ToolType::Monomate
  86. }
  87. ),
  88. location: item::ItemLocation::Inventory {
  89. character_id: char2.id,
  90. slot: 0,
  91. equipped: false,
  92. }
  93. }).await;
  94. let mut ship = ShipServerState::new(entity_gateway.clone());
  95. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  96. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  97. join_lobby(&mut ship, ClientId(1)).await;
  98. join_lobby(&mut ship, ClientId(2)).await;
  99. create_room(&mut ship, ClientId(1), "room", "").await;
  100. join_room(&mut ship, ClientId(2), 0).await;
  101. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::PlayerDropItem(PlayerDropItem {
  102. client: 0,
  103. target: 0,
  104. unknown1: 0,
  105. area: 0,
  106. item_id: 0x210000,
  107. x: 0.0,
  108. y: 0.0,
  109. z: 0.0,
  110. })))).await.unwrap().for_each(drop);
  111. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  112. client: 0,
  113. target: 0,
  114. item_id: 0x210000,
  115. area: 0,
  116. unknown: [0; 3]
  117. })))).await.unwrap().for_each(drop);
  118. let p1_inventory = ship.item_manager.get_character_inventory(&char1).unwrap();
  119. assert!(p1_inventory.count() == 1);
  120. let inventory_item = p1_inventory.slot(0).unwrap();
  121. assert!(inventory_item.entity_id == ActiveItemEntityId::Stacked(vec![item::ItemEntityId(1)]));
  122. assert!(inventory_item.item == HeldItemType::Stacked(item::tool::Tool {tool: item::tool::ToolType::Monomate}, 1));
  123. }
  124. #[async_std::test]
  125. async fn test_pick_up_meseta_when_inventory_full() {
  126. let mut entity_gateway = InMemoryGateway::new();
  127. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  128. let (_user2, mut char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  129. for slot in 0..30 {
  130. entity_gateway.create_item(
  131. item::NewItemEntity {
  132. item: item::ItemDetail::Weapon(
  133. item::weapon::Weapon {
  134. weapon: item::weapon::WeaponType::Saber,
  135. grind: 0,
  136. special: None,
  137. attrs: [None, None, None],
  138. tekked: true,
  139. }
  140. ),
  141. location: item::ItemLocation::Inventory {
  142. character_id: char1.id,
  143. slot: slot,
  144. equipped: false,
  145. }
  146. }).await;
  147. }
  148. char2.meseta = 300;
  149. entity_gateway.save_character(&char2).await;
  150. let mut ship = ShipServerState::new(entity_gateway.clone());
  151. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  152. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  153. join_lobby(&mut ship, ClientId(1)).await;
  154. join_lobby(&mut ship, ClientId(2)).await;
  155. create_room(&mut ship, ClientId(1), "room", "").await;
  156. join_room(&mut ship, ClientId(2), 0).await;
  157. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::DropCoordinates(DropCoordinates {
  158. client: 0,
  159. target: 0,
  160. item_id: 0xFFFFFFFF,
  161. map_area: 0,
  162. x: 0.0,
  163. z: 0.0,
  164. })))).await.unwrap().for_each(drop);
  165. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::PlayerSplitItemStack(PlayerSplitItemStack {
  166. client: 0,
  167. target: 0,
  168. item_id: 0xFFFFFFFF,
  169. amount: 23,
  170. })))).await.unwrap().for_each(drop);
  171. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  172. client: 0,
  173. target: 0,
  174. item_id: 0xF0000001,
  175. area: 0,
  176. unknown: [0; 3]
  177. })))).await.unwrap().for_each(drop);
  178. let p1_inventory = ship.item_manager.get_character_inventory(&char1).unwrap();
  179. assert!(p1_inventory.count() == 30);
  180. let c1 = ship.clients.get(&ClientId(1)).unwrap();
  181. let c2 = ship.clients.get(&ClientId(2)).unwrap();
  182. assert!(c1.character.meseta == 23);
  183. assert!(c2.character.meseta == 277);
  184. }
  185. #[async_std::test]
  186. async fn test_pick_up_partial_stacked_item_when_inventory_is_otherwise_full() {
  187. let mut entity_gateway = InMemoryGateway::new();
  188. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  189. let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  190. for slot in 0..29 {
  191. entity_gateway.create_item(
  192. item::NewItemEntity {
  193. item: item::ItemDetail::Weapon(
  194. item::weapon::Weapon {
  195. weapon: item::weapon::WeaponType::Saber,
  196. grind: 0,
  197. special: None,
  198. attrs: [None, None, None],
  199. tekked: true,
  200. }
  201. ),
  202. location: item::ItemLocation::Inventory {
  203. character_id: char1.id,
  204. slot: slot,
  205. equipped: false,
  206. }
  207. }).await;
  208. }
  209. entity_gateway.create_item(
  210. item::NewItemEntity {
  211. item: item::ItemDetail::Tool(
  212. item::tool::Tool {
  213. tool: item::tool::ToolType::Monomate,
  214. }
  215. ),
  216. location: item::ItemLocation::Inventory {
  217. character_id: char1.id,
  218. slot: 29,
  219. equipped: false,
  220. }
  221. }).await;
  222. entity_gateway.create_item(
  223. item::NewItemEntity {
  224. item: item::ItemDetail::Tool(
  225. item::tool::Tool {
  226. tool: item::tool::ToolType::Monomate,
  227. }
  228. ),
  229. location: item::ItemLocation::Inventory {
  230. character_id: char2.id,
  231. slot: 0,
  232. equipped: false,
  233. }
  234. }).await;
  235. let mut ship = ShipServerState::new(entity_gateway.clone());
  236. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  237. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  238. join_lobby(&mut ship, ClientId(1)).await;
  239. join_lobby(&mut ship, ClientId(2)).await;
  240. create_room(&mut ship, ClientId(1), "room", "").await;
  241. join_room(&mut ship, ClientId(2), 0).await;
  242. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::PlayerDropItem(PlayerDropItem {
  243. client: 0,
  244. target: 0,
  245. unknown1: 0,
  246. area: 0,
  247. item_id: 0x210000,
  248. x: 0.0,
  249. y: 0.0,
  250. z: 0.0,
  251. })))).await.unwrap().for_each(drop);
  252. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  253. client: 0,
  254. target: 0,
  255. item_id: 0x210000,
  256. area: 0,
  257. unknown: [0; 3]
  258. })))).await.unwrap().for_each(drop);
  259. let p1_inventory = ship.item_manager.get_character_inventory(&char1).unwrap();
  260. assert!(p1_inventory.count() == 30);
  261. let monomates = p1_inventory.slot(29).unwrap();
  262. assert!(monomates.item == HeldItemType::Stacked(item::tool::Tool {tool: item::tool::ToolType::Monomate}, 2));
  263. }
  264. #[async_std::test]
  265. async fn test_can_not_pick_up_item_when_inventory_full() {
  266. let mut entity_gateway = InMemoryGateway::new();
  267. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  268. let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  269. for slot in 0..30 {
  270. entity_gateway.create_item(
  271. item::NewItemEntity {
  272. item: item::ItemDetail::Weapon(
  273. item::weapon::Weapon {
  274. weapon: item::weapon::WeaponType::Saber,
  275. grind: 0,
  276. special: None,
  277. attrs: [None, None, None],
  278. tekked: true,
  279. }
  280. ),
  281. location: item::ItemLocation::Inventory {
  282. character_id: char1.id,
  283. slot: slot,
  284. equipped: false,
  285. }
  286. }).await;
  287. }
  288. entity_gateway.create_item(
  289. item::NewItemEntity {
  290. item: item::ItemDetail::Weapon(
  291. item::weapon::Weapon {
  292. weapon: item::weapon::WeaponType::Handgun,
  293. grind: 0,
  294. special: None,
  295. attrs: [None, None, None],
  296. tekked: true,
  297. }
  298. ),
  299. location: item::ItemLocation::Inventory {
  300. character_id: char2.id,
  301. slot: 0,
  302. equipped: false,
  303. }
  304. }).await;
  305. let mut ship = ShipServerState::new(entity_gateway.clone());
  306. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  307. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  308. join_lobby(&mut ship, ClientId(1)).await;
  309. join_lobby(&mut ship, ClientId(2)).await;
  310. create_room(&mut ship, ClientId(1), "room", "").await;
  311. join_room(&mut ship, ClientId(2), 0).await;
  312. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::PlayerDropItem(PlayerDropItem {
  313. client: 0,
  314. target: 0,
  315. unknown1: 0,
  316. area: 0,
  317. item_id: 0x210000,
  318. x: 0.0,
  319. y: 0.0,
  320. z: 0.0,
  321. })))).await.unwrap().for_each(drop);
  322. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  323. client: 0,
  324. target: 0,
  325. item_id: 0x210000,
  326. area: 0,
  327. unknown: [0; 3]
  328. })))).await.unwrap().for_each(drop);
  329. let p1_inventory = ship.item_manager.get_character_inventory(&char1).unwrap();
  330. assert!(p1_inventory.count() == 30);
  331. let floor_item = ship.item_manager.get_floor_item_by_id(&char1, ClientItemId(0x210000)).unwrap();
  332. assert!(floor_item.item_id == ClientItemId(0x210000));
  333. }
  334. #[async_std::test]
  335. async fn test_can_not_drop_more_meseta_than_is_held() {
  336. let mut entity_gateway = InMemoryGateway::new();
  337. let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  338. char1.meseta = 300;
  339. entity_gateway.save_character(&char1).await;
  340. let mut ship = ShipServerState::new(entity_gateway.clone());
  341. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  342. join_lobby(&mut ship, ClientId(1)).await;
  343. create_room(&mut ship, ClientId(1), "room", "").await;
  344. ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::DropCoordinates(DropCoordinates {
  345. client: 0,
  346. target: 0,
  347. item_id: 0xFFFFFFFF,
  348. map_area: 0,
  349. x: 0.0,
  350. z: 0.0,
  351. })))).await.unwrap().for_each(drop);
  352. let split_attempt = ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::PlayerSplitItemStack(PlayerSplitItemStack {
  353. client: 0,
  354. target: 0,
  355. item_id: 0xFFFFFFFF,
  356. amount: 301,
  357. })))).await;
  358. assert!(split_attempt.is_err());
  359. let c1 = ship.clients.get(&ClientId(1)).unwrap();
  360. assert!(c1.character.meseta == 300);
  361. assert!(ship.item_manager.get_floor_item_by_id(&char1, ClientItemId(0xF0000001)).is_err())
  362. }
  363. #[async_std::test]
  364. async fn test_pick_up_stack_that_would_exceed_stack_limit() {
  365. let mut entity_gateway = InMemoryGateway::new();
  366. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  367. let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  368. for _ in 0..6 {
  369. entity_gateway.create_item(
  370. item::NewItemEntity {
  371. item: item::ItemDetail::Tool(
  372. item::tool::Tool {
  373. tool: item::tool::ToolType::Monomate,
  374. }
  375. ),
  376. location: item::ItemLocation::Inventory {
  377. character_id: char1.id,
  378. slot: 0,
  379. equipped: false,
  380. }
  381. }).await;
  382. }
  383. for _ in 0..6 {
  384. entity_gateway.create_item(
  385. item::NewItemEntity {
  386. item: item::ItemDetail::Tool(
  387. item::tool::Tool {
  388. tool: item::tool::ToolType::Monomate,
  389. }
  390. ),
  391. location: item::ItemLocation::Inventory {
  392. character_id: char2.id,
  393. slot: 0,
  394. equipped: false,
  395. }
  396. }).await;
  397. }
  398. let mut ship = ShipServerState::new(entity_gateway.clone());
  399. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  400. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  401. join_lobby(&mut ship, ClientId(1)).await;
  402. join_lobby(&mut ship, ClientId(2)).await;
  403. create_room(&mut ship, ClientId(1), "room", "").await;
  404. join_room(&mut ship, ClientId(2), 0).await;
  405. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::PlayerDropItem(PlayerDropItem {
  406. client: 0,
  407. target: 0,
  408. unknown1: 0,
  409. area: 0,
  410. item_id: 0x210000,
  411. x: 0.0,
  412. y: 0.0,
  413. z: 0.0,
  414. })))).await.unwrap().for_each(drop);
  415. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  416. client: 0,
  417. target: 0,
  418. item_id: 0x210000,
  419. area: 0,
  420. unknown: [0; 3]
  421. })))).await.unwrap().for_each(drop);
  422. let p1_inventory = ship.item_manager.get_character_inventory(&char1).unwrap();
  423. let monomates = p1_inventory.slot(0).unwrap();
  424. assert!(monomates.item == HeldItemType::Stacked(item::tool::Tool {tool: item::tool::ToolType::Monomate}, 6));
  425. let floor_monomates = ship.item_manager.get_floor_item_by_id(&char1, ClientItemId(0x210000)).unwrap();
  426. assert!(floor_monomates.item == FloorItemType::Stacked(item::tool::Tool {tool: item::tool::ToolType::Monomate}, 6));
  427. }
  428. #[async_std::test]
  429. async fn test_can_not_pick_up_meseta_when_full() {
  430. let mut entity_gateway = InMemoryGateway::new();
  431. let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  432. let (_user2, mut char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  433. char1.meseta = 999999;
  434. entity_gateway.save_character(&char1).await;
  435. char2.meseta = 300;
  436. entity_gateway.save_character(&char2).await;
  437. let mut ship = ShipServerState::new(entity_gateway.clone());
  438. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  439. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  440. join_lobby(&mut ship, ClientId(1)).await;
  441. join_lobby(&mut ship, ClientId(2)).await;
  442. create_room(&mut ship, ClientId(1), "room", "").await;
  443. join_room(&mut ship, ClientId(2), 0).await;
  444. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::DropCoordinates(DropCoordinates {
  445. client: 0,
  446. target: 0,
  447. item_id: 0xFFFFFFFF,
  448. map_area: 0,
  449. x: 0.0,
  450. z: 0.0,
  451. })))).await.unwrap().for_each(drop);
  452. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::PlayerSplitItemStack(PlayerSplitItemStack {
  453. client: 0,
  454. target: 0,
  455. item_id: 0xFFFFFFFF,
  456. amount: 23,
  457. })))).await.unwrap().for_each(drop);
  458. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  459. client: 0,
  460. target: 0,
  461. item_id: 0xF0000001,
  462. area: 0,
  463. unknown: [0; 3]
  464. })))).await.unwrap().for_each(drop);
  465. let c1 = ship.clients.get(&ClientId(1)).unwrap();
  466. let c2 = ship.clients.get(&ClientId(2)).unwrap();
  467. assert!(c1.character.meseta == 999999);
  468. assert!(c2.character.meseta == 277);
  469. let floor_meseta = ship.item_manager.get_floor_item_by_id(&char1, ClientItemId(0xF0000001)).unwrap();
  470. assert!(floor_meseta.item == FloorItemType::Meseta(item::Meseta(23)));
  471. }
  472. #[async_std::test]
  473. async fn test_meseta_caps_at_999999_when_trying_to_pick_up_more() {
  474. let mut entity_gateway = InMemoryGateway::new();
  475. let (_user1, mut char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  476. let (_user2, mut char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  477. char1.meseta = 999998;
  478. entity_gateway.save_character(&char1).await;
  479. char2.meseta = 300;
  480. entity_gateway.save_character(&char2).await;
  481. let mut ship = ShipServerState::new(entity_gateway.clone());
  482. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  483. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  484. join_lobby(&mut ship, ClientId(1)).await;
  485. join_lobby(&mut ship, ClientId(2)).await;
  486. create_room(&mut ship, ClientId(1), "room", "").await;
  487. join_room(&mut ship, ClientId(2), 0).await;
  488. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::DropCoordinates(DropCoordinates {
  489. client: 0,
  490. target: 0,
  491. item_id: 0xFFFFFFFF,
  492. map_area: 0,
  493. x: 0.0,
  494. z: 0.0,
  495. })))).await.unwrap().for_each(drop);
  496. ship.handle(ClientId(2), &RecvShipPacket::Message(Message::new(GameMessage::PlayerSplitItemStack(PlayerSplitItemStack {
  497. client: 0,
  498. target: 0,
  499. item_id: 0xFFFFFFFF,
  500. amount: 23,
  501. })))).await.unwrap().for_each(drop);
  502. ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  503. client: 0,
  504. target: 0,
  505. item_id: 0xF0000001,
  506. area: 0,
  507. unknown: [0; 3]
  508. })))).await.unwrap().for_each(drop);
  509. let c1 = ship.clients.get(&ClientId(1)).unwrap();
  510. let c2 = ship.clients.get(&ClientId(2)).unwrap();
  511. assert!(c1.character.meseta == 999999);
  512. assert!(c2.character.meseta == 277);
  513. let floor_meseta = ship.item_manager.get_floor_item_by_id(&char1, ClientItemId(0xF0000001));
  514. assert!(floor_meseta.is_err());
  515. }
  516. #[async_std::test]
  517. async fn test_player_drops_partial_stack_and_other_player_picks_it_up() {
  518. let mut entity_gateway = InMemoryGateway::new();
  519. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a").await;
  520. let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a").await;
  521. for _ in 0..5 {
  522. entity_gateway.create_item(
  523. item::NewItemEntity {
  524. item: item::ItemDetail::Tool(
  525. item::tool::Tool {
  526. tool: item::tool::ToolType::Monomate,
  527. }
  528. ),
  529. location: item::ItemLocation::Inventory {
  530. character_id: char1.id,
  531. slot: 0,
  532. equipped: false,
  533. }
  534. }).await;
  535. }
  536. let mut ship = ShipServerState::new(entity_gateway.clone());
  537. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  538. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  539. join_lobby(&mut ship, ClientId(1)).await;
  540. join_lobby(&mut ship, ClientId(2)).await;
  541. create_room(&mut ship, ClientId(1), "room", "").await;
  542. join_room(&mut ship, ClientId(2), 0).await;
  543. ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::DropCoordinates(DropCoordinates {
  544. client: 0,
  545. target: 0,
  546. item_id: 0x10000,
  547. map_area: 0,
  548. x: 0.0,
  549. z: 0.0,
  550. })))).await.unwrap().for_each(drop);
  551. ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::PlayerSplitItemStack(PlayerSplitItemStack {
  552. client: 0,
  553. target: 0,
  554. item_id: 0x10000,
  555. amount: 2,
  556. })))).await.unwrap().for_each(drop);
  557. ship.handle(ClientId(2), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  558. client: 0,
  559. target: 0,
  560. item_id: 0xF0000001,
  561. area: 0,
  562. unknown: [0; 3]
  563. })))).await.unwrap().for_each(drop);
  564. let p1_inventory = ship.item_manager.get_character_inventory(&char1).unwrap();
  565. assert!(p1_inventory.count() == 1);
  566. let inventory_item = p1_inventory.slot(0).unwrap();
  567. assert!(inventory_item.item == HeldItemType::Stacked(item::tool::Tool {tool: item::tool::ToolType::Monomate}, 3));
  568. let p2_inventory = ship.item_manager.get_character_inventory(&char2).unwrap();
  569. assert!(p2_inventory.count() == 1);
  570. let inventory_item = p2_inventory.slot(0).unwrap();
  571. assert!(inventory_item.item == HeldItemType::Stacked(item::tool::Tool {tool: item::tool::ToolType::Monomate}, 2));
  572. }