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.

772 lines
27 KiB

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