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.

777 lines
28 KiB

5 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
3 years ago
4 years ago
5 years ago
5 years ago
5 years ago
4 years ago
3 years ago
5 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
3 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
3 years ago
5 years ago
4 years ago
5 years ago
5 years ago
5 years ago
5 years ago
3 years ago
4 years ago
5 years ago
5 years ago
5 years ago
4 years ago
3 years ago
5 years ago
3 years ago
4 years ago
5 years ago
5 years ago
5 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. amount: 23,
  223. })))).await.unwrap();
  224. ship.handle(ClientId(2), RecvShipPacket::Message(Message::new(GameMessage::PlayerNoLongerHasItem(PlayerNoLongerHasItem {
  225. client: 0,
  226. target: 0,
  227. item_id: 0xFFFFFFFF,
  228. amount: 23,
  229. })))).await.unwrap();
  230. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  231. client: 0,
  232. target: 0,
  233. item_id: 0x00810001,
  234. map_area: 0,
  235. unknown: [0; 3]
  236. })))).await.unwrap();
  237. let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  238. assert_eq!(inventory_items.items.len(), 30);
  239. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  240. let c2_meseta = entity_gateway.get_character_meseta(&char2.id).await.unwrap();
  241. assert!(c1_meseta.0 == 23);
  242. assert!(c2_meseta.0 == 277);
  243. }
  244. #[async_std::test]
  245. async fn test_pick_up_partial_stacked_item_when_inventory_is_otherwise_full() {
  246. let mut entity_gateway = InMemoryGateway::default();
  247. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await;
  248. let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await;
  249. let mut p1_inv = Vec::new();
  250. for _slot in 0..29usize {
  251. p1_inv.push(entity_gateway.create_item(
  252. item::NewItemEntity {
  253. item: item::ItemDetail::Weapon(
  254. item::weapon::Weapon {
  255. weapon: item::weapon::WeaponType::Saber,
  256. grind: 0,
  257. special: None,
  258. attrs: [None, None, None],
  259. tekked: true,
  260. }
  261. ),
  262. }).await.unwrap().into());
  263. }
  264. p1_inv.push(item::InventoryItemEntity::Stacked(vec![entity_gateway.create_item(
  265. item::NewItemEntity {
  266. item: item::ItemDetail::Tool(
  267. item::tool::Tool {
  268. tool: item::tool::ToolType::Monomate,
  269. }
  270. ),
  271. }).await.unwrap()]));
  272. let mut p2_monomates = Vec::new();
  273. p2_monomates.push(entity_gateway.create_item(
  274. item::NewItemEntity {
  275. item: item::ItemDetail::Tool(
  276. item::tool::Tool {
  277. tool: item::tool::ToolType::Monomate,
  278. }
  279. ),
  280. }).await.unwrap());
  281. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap();
  282. entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(vec![p2_monomates])).await.unwrap();
  283. let mut ship = Box::new(ShipServerState::builder()
  284. .gateway(entity_gateway.clone())
  285. .build());
  286. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  287. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  288. join_lobby(&mut ship, ClientId(1)).await;
  289. join_lobby(&mut ship, ClientId(2)).await;
  290. create_room(&mut ship, ClientId(1), "room", "").await;
  291. join_room(&mut ship, ClientId(2), 0).await;
  292. ship.handle(ClientId(2), RecvShipPacket::Message(Message::new(GameMessage::PlayerDropItem(PlayerDropItem {
  293. client: 0,
  294. target: 0,
  295. unknown1: 0,
  296. map_area: 0,
  297. item_id: 0x210000,
  298. x: 0.0,
  299. y: 0.0,
  300. z: 0.0,
  301. })))).await.unwrap();
  302. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  303. client: 0,
  304. target: 0,
  305. item_id: 0x210000,
  306. map_area: 0,
  307. unknown: [0; 3]
  308. })))).await.unwrap();
  309. let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  310. assert_eq!(inventory_items.items.len(), 30);
  311. inventory_items.items[29].with_stacked(|items| {
  312. assert_eq!(items.len(), 2);
  313. }).unwrap();
  314. }
  315. #[async_std::test]
  316. async fn test_can_not_pick_up_item_when_inventory_full() {
  317. let mut entity_gateway = InMemoryGateway::default();
  318. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await;
  319. let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await;
  320. let mut p1_inv = Vec::new();
  321. for _slot in 0..30usize {
  322. p1_inv.push(entity_gateway.create_item(
  323. item::NewItemEntity {
  324. item: item::ItemDetail::Weapon(
  325. item::weapon::Weapon {
  326. weapon: item::weapon::WeaponType::Saber,
  327. grind: 0,
  328. special: None,
  329. attrs: [None, None, None],
  330. tekked: true,
  331. }
  332. ),
  333. }).await.unwrap());
  334. }
  335. let mut p2_inv = Vec::new();
  336. p2_inv.push(entity_gateway.create_item(
  337. item::NewItemEntity {
  338. item: item::ItemDetail::Weapon(
  339. item::weapon::Weapon {
  340. weapon: item::weapon::WeaponType::Handgun,
  341. grind: 0,
  342. special: None,
  343. attrs: [None, None, None],
  344. tekked: true,
  345. }
  346. ),
  347. }).await.unwrap());
  348. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap();
  349. entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(p2_inv)).await.unwrap();
  350. let mut ship = Box::new(ShipServerState::builder()
  351. .gateway(entity_gateway.clone())
  352. .build());
  353. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  354. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  355. join_lobby(&mut ship, ClientId(1)).await;
  356. join_lobby(&mut ship, ClientId(2)).await;
  357. create_room(&mut ship, ClientId(1), "room", "").await;
  358. join_room(&mut ship, ClientId(2), 0).await;
  359. ship.handle(ClientId(2), RecvShipPacket::Message(Message::new(GameMessage::PlayerDropItem(PlayerDropItem {
  360. client: 0,
  361. target: 0,
  362. unknown1: 0,
  363. map_area: 0,
  364. item_id: 0x210000,
  365. x: 0.0,
  366. y: 0.0,
  367. z: 0.0,
  368. })))).await.unwrap();
  369. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  370. client: 0,
  371. target: 0,
  372. item_id: 0x210000,
  373. map_area: 0,
  374. unknown: [0; 3]
  375. })))).await.unwrap();
  376. let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  377. assert_eq!(p1_items.items.len(), 30);
  378. let p2_items = entity_gateway.get_character_inventory(&char2.id).await.unwrap();
  379. assert_eq!(p2_items.items.len(), 0);
  380. ship.handle(ClientId(2), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  381. client: 0,
  382. target: 0,
  383. item_id: 0x210000,
  384. map_area: 0,
  385. unknown: [0; 3]
  386. })))).await.unwrap();
  387. let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  388. assert_eq!(p1_items.items.len(), 30);
  389. let p2_items = entity_gateway.get_character_inventory(&char2.id).await.unwrap();
  390. assert_eq!(p2_items.items.len(), 1);
  391. }
  392. #[async_std::test]
  393. async fn test_can_not_drop_more_meseta_than_is_held() {
  394. let mut entity_gateway = InMemoryGateway::default();
  395. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await;
  396. entity_gateway.set_character_meseta(&char1.id, item::Meseta(300)).await.unwrap();
  397. let mut ship = Box::new(ShipServerState::builder()
  398. .gateway(entity_gateway.clone())
  399. .build());
  400. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  401. join_lobby(&mut ship, ClientId(1)).await;
  402. create_room(&mut ship, ClientId(1), "room", "").await;
  403. ship.handle(ClientId(1), RecvShipPacket::Message(Message::new(GameMessage::DropCoordinates(DropCoordinates {
  404. client: 0,
  405. target: 0,
  406. item_id: 0xFFFFFFFF,
  407. map_area: 0,
  408. room: 0,
  409. x: 0.0,
  410. z: 0.0,
  411. amount: 301,
  412. })))).await.unwrap();
  413. let split_attempt = ship.handle(ClientId(1), RecvShipPacket::Message(Message::new(GameMessage::PlayerNoLongerHasItem(PlayerNoLongerHasItem {
  414. client: 0,
  415. target: 0,
  416. item_id: 0xFFFFFFFF,
  417. amount: 301,
  418. })))).await;
  419. assert!(split_attempt.is_err());
  420. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  421. assert!(c1_meseta.0 == 300);
  422. }
  423. #[async_std::test]
  424. async fn test_pick_up_stack_that_would_exceed_stack_limit() {
  425. let mut entity_gateway = InMemoryGateway::default();
  426. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await;
  427. let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await;
  428. let mut p1_monomates = Vec::new();
  429. for _ in 0..6usize {
  430. p1_monomates.push(entity_gateway.create_item(
  431. item::NewItemEntity {
  432. item: item::ItemDetail::Tool(
  433. item::tool::Tool {
  434. tool: item::tool::ToolType::Monomate,
  435. }
  436. ),
  437. }).await.unwrap());
  438. }
  439. let mut p2_monomates = Vec::new();
  440. for _ in 0..6usize {
  441. p2_monomates.push(entity_gateway.create_item(
  442. item::NewItemEntity {
  443. item: item::ItemDetail::Tool(
  444. item::tool::Tool {
  445. tool: item::tool::ToolType::Monomate,
  446. }
  447. ),
  448. }).await.unwrap());
  449. }
  450. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![p1_monomates])).await.unwrap();
  451. entity_gateway.set_character_inventory(&char2.id, &item::InventoryEntity::new(vec![p2_monomates])).await.unwrap();
  452. let mut ship = Box::new(ShipServerState::builder()
  453. .gateway(entity_gateway.clone())
  454. .build());
  455. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  456. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  457. join_lobby(&mut ship, ClientId(1)).await;
  458. join_lobby(&mut ship, ClientId(2)).await;
  459. create_room(&mut ship, ClientId(1), "room", "").await;
  460. join_room(&mut ship, ClientId(2), 0).await;
  461. ship.handle(ClientId(2), RecvShipPacket::Message(Message::new(GameMessage::PlayerDropItem(PlayerDropItem {
  462. client: 0,
  463. target: 0,
  464. unknown1: 0,
  465. map_area: 0,
  466. item_id: 0x210000,
  467. x: 0.0,
  468. y: 0.0,
  469. z: 0.0,
  470. })))).await.unwrap();
  471. let packets = ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  472. client: 0,
  473. target: 0,
  474. item_id: 0x210000,
  475. map_area: 0,
  476. unknown: [0; 3]
  477. })))).await.unwrap();
  478. assert!(packets.len() == 0);
  479. let p1_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  480. assert_eq!(p1_items.items.len(), 1);
  481. p1_items.items[0].with_stacked(|items| {
  482. assert_eq!(items.len(), 6);
  483. }).unwrap();
  484. let p2_items = entity_gateway.get_character_inventory(&char2.id).await.unwrap();
  485. assert_eq!(p2_items.items.len(), 0);
  486. }
  487. #[async_std::test]
  488. async fn test_can_not_pick_up_meseta_when_full() {
  489. let mut entity_gateway = InMemoryGateway::default();
  490. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await;
  491. let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await;
  492. entity_gateway.set_character_meseta(&char1.id, item::Meseta(999999)).await.unwrap();
  493. entity_gateway.set_character_meseta(&char2.id, item::Meseta(300)).await.unwrap();
  494. let mut ship = Box::new(ShipServerState::builder()
  495. .gateway(entity_gateway.clone())
  496. .build());
  497. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  498. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  499. join_lobby(&mut ship, ClientId(1)).await;
  500. join_lobby(&mut ship, ClientId(2)).await;
  501. create_room(&mut ship, ClientId(1), "room", "").await;
  502. join_room(&mut ship, ClientId(2), 0).await;
  503. ship.handle(ClientId(2), RecvShipPacket::Message(Message::new(GameMessage::DropCoordinates(DropCoordinates {
  504. client: 0,
  505. target: 0,
  506. item_id: 0xFFFFFFFF,
  507. map_area: 0,
  508. room: 0,
  509. x: 0.0,
  510. z: 0.0,
  511. amount: 23,
  512. })))).await.unwrap();
  513. ship.handle(ClientId(2), RecvShipPacket::Message(Message::new(GameMessage::PlayerNoLongerHasItem(PlayerNoLongerHasItem {
  514. client: 0,
  515. target: 0,
  516. item_id: 0xFFFFFFFF,
  517. amount: 23,
  518. })))).await.unwrap();
  519. let packets = ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  520. client: 0,
  521. target: 0,
  522. item_id: 0x00810001,
  523. map_area: 0,
  524. unknown: [0; 3]
  525. })))).await.unwrap();
  526. assert!(packets.len() == 0);
  527. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  528. let c2_meseta = entity_gateway.get_character_meseta(&char2.id).await.unwrap();
  529. assert!(c1_meseta.0 == 999999);
  530. assert!(c2_meseta.0 == 277);
  531. }
  532. #[async_std::test]
  533. async fn test_meseta_caps_at_999999_when_trying_to_pick_up_more() {
  534. let mut entity_gateway = InMemoryGateway::default();
  535. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await;
  536. let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await;
  537. entity_gateway.set_character_meseta(&char1.id, item::Meseta(999998)).await.unwrap();
  538. entity_gateway.set_character_meseta(&char2.id, item::Meseta(300)).await.unwrap();
  539. let mut ship = Box::new(ShipServerState::builder()
  540. .gateway(entity_gateway.clone())
  541. .build());
  542. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  543. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  544. join_lobby(&mut ship, ClientId(1)).await;
  545. join_lobby(&mut ship, ClientId(2)).await;
  546. create_room(&mut ship, ClientId(1), "room", "").await;
  547. join_room(&mut ship, ClientId(2), 0).await;
  548. ship.handle(ClientId(2), RecvShipPacket::Message(Message::new(GameMessage::DropCoordinates(DropCoordinates {
  549. client: 0,
  550. target: 0,
  551. item_id: 0xFFFFFFFF,
  552. map_area: 0,
  553. room: 0,
  554. x: 0.0,
  555. z: 0.0,
  556. amount: 23,
  557. })))).await.unwrap();
  558. ship.handle(ClientId(2), RecvShipPacket::Message(Message::new(GameMessage::PlayerNoLongerHasItem(PlayerNoLongerHasItem {
  559. client: 0,
  560. target: 0,
  561. item_id: 0xFFFFFFFF,
  562. amount: 23,
  563. })))).await.unwrap();
  564. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  565. client: 0,
  566. target: 0,
  567. item_id: 0x00810001,
  568. map_area: 0,
  569. unknown: [0; 3]
  570. })))).await.unwrap();
  571. let c1_meseta = entity_gateway.get_character_meseta(&char1.id).await.unwrap();
  572. let c2_meseta = entity_gateway.get_character_meseta(&char2.id).await.unwrap();
  573. assert!(c1_meseta.0 == 999999);
  574. assert!(c2_meseta.0 == 277);
  575. }
  576. #[async_std::test]
  577. async fn test_player_drops_partial_stack_and_other_player_picks_it_up() {
  578. let mut entity_gateway = InMemoryGateway::default();
  579. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await;
  580. let (_user2, char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await;
  581. let mut monomates = Vec::new();
  582. for _ in 0..5usize {
  583. monomates.push(entity_gateway.create_item(
  584. item::NewItemEntity {
  585. item: item::ItemDetail::Tool(
  586. item::tool::Tool {
  587. tool: item::tool::ToolType::Monomate,
  588. }
  589. ),
  590. }).await.unwrap());
  591. }
  592. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(vec![monomates])).await.unwrap();
  593. let mut ship = Box::new(ShipServerState::builder()
  594. .gateway(entity_gateway.clone())
  595. .build());
  596. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  597. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  598. join_lobby(&mut ship, ClientId(1)).await;
  599. join_lobby(&mut ship, ClientId(2)).await;
  600. create_room(&mut ship, ClientId(1), "room", "").await;
  601. join_room(&mut ship, ClientId(2), 0).await;
  602. ship.handle(ClientId(1), RecvShipPacket::Message(Message::new(GameMessage::DropCoordinates(DropCoordinates {
  603. client: 0,
  604. target: 0,
  605. item_id: 0x10000,
  606. map_area: 0,
  607. room: 0,
  608. x: 0.0,
  609. z: 0.0,
  610. amount: 2,
  611. })))).await.unwrap();
  612. ship.handle(ClientId(1), RecvShipPacket::Message(Message::new(GameMessage::PlayerNoLongerHasItem(PlayerNoLongerHasItem {
  613. client: 0,
  614. target: 0,
  615. item_id: 0x10000,
  616. amount: 2,
  617. })))).await.unwrap();
  618. ship.handle(ClientId(2), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  619. client: 0,
  620. target: 0,
  621. item_id: 0x10001,
  622. map_area: 0,
  623. unknown: [0; 3]
  624. })))).await.unwrap();
  625. let inventory_items = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  626. assert_eq!(inventory_items.items.len(), 1);
  627. inventory_items.items[0].with_stacked(|items| {
  628. assert_eq!(items.iter().map(|i| i.id).collect::<Vec<_>>(),
  629. vec![item::ItemEntityId(3), item::ItemEntityId(4), item::ItemEntityId(5)]);
  630. }).unwrap();
  631. let inventory_items = entity_gateway.get_character_inventory(&char2.id).await.unwrap();
  632. assert_eq!(inventory_items.items.len(), 1);
  633. inventory_items.items[0].with_stacked(|items| {
  634. assert_eq!(items.iter().map(|i| i.id).collect::<Vec<_>>(),
  635. vec![item::ItemEntityId(1), item::ItemEntityId(2)]);
  636. }).unwrap();
  637. }
  638. /*
  639. #[async_std::test]
  640. async fn test_try_and_pick_up_individual_item_twice() {
  641. panic!()
  642. }
  643. #[async_std::test]
  644. async fn test_try_and_pick_up_stacked_item_twice() {
  645. panic!()
  646. }
  647. #[async_std::test]
  648. async fn test_try_and_pick_up_meseta_twice() {
  649. panic!()
  650. }
  651. */