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.

210 lines
9.5 KiB

  1. use elseware::common::serverstate::{ClientId, ServerState};
  2. use elseware::entity::gateway::{EntityGateway, InMemoryGateway};
  3. use elseware::entity::character::SectionID;
  4. use elseware::common::leveltable::CharacterLevelTable;
  5. use elseware::ship::ship::{ShipServerState, SendShipPacket, RecvShipPacket};
  6. use elseware::ship::room::{Episode, Difficulty};
  7. use elseware::ship::monster::MonsterType;
  8. use elseware::ship::location::RoomId;
  9. use elseware::ship::drops::{DropTable, MonsterDropStats, MonsterDropType};
  10. use elseware::ship::drops::rare_drop_table::{RareDropTable, RareDropRate, RareDropItem};
  11. use elseware::ship::map::{Maps, MapVariant, MapArea, MapVariantMode, MapEnemy};
  12. use elseware::entity::item::weapon::WeaponType;
  13. use libpso::packet::ship::*;
  14. use libpso::packet::messages::*;
  15. #[path = "common.rs"]
  16. mod common;
  17. use common::*;
  18. #[async_std::test]
  19. async fn test_enemy_drops_item() {
  20. let mut entity_gateway = InMemoryGateway::default();
  21. let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await;
  22. let mut ship = Box::new(ShipServerState::builder()
  23. .gateway(entity_gateway.clone())
  24. .map_builder(Box::new(|_room_mode, _event| {
  25. Maps::new(
  26. vec![MapVariant::new(MapArea::Forest2, MapVariantMode::Online)],
  27. vec![Some(MapEnemy::new(MonsterType::Hildebear, MapArea::Forest2))],
  28. Vec::new(),
  29. )
  30. }))
  31. .drop_table_builder(Box::new(|episode, difficulty, section_id| {
  32. DropTable::builder()
  33. .monster_stat(MonsterType::Hildebear, MonsterDropStats {
  34. dar: 100,
  35. drop_type: MonsterDropType::Weapon,
  36. min_meseta: 0,
  37. max_meseta: 0,
  38. })
  39. .rare_table(RareDropTable::builder()
  40. .rate(MonsterType::Hildebear, RareDropRate {
  41. rate: 1.0,
  42. item: RareDropItem::Weapon(WeaponType::DarkFlow)
  43. })
  44. .build(episode, difficulty, section_id))
  45. .build(episode, difficulty, section_id)
  46. }))
  47. .build());
  48. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  49. join_lobby(&mut ship, ClientId(1)).await;
  50. create_room(&mut ship, ClientId(1), "room", "").await;
  51. let pkt = ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::RequestItem(RequestItem {
  52. client: 0,
  53. target: 0,
  54. map_area: 2,
  55. pt_index: 0,
  56. enemy_id: 0,
  57. x: 0.0,
  58. z: 0.0,
  59. y: 0.0,
  60. })))).await.unwrap();
  61. match &pkt[0].1 {
  62. SendShipPacket::Message(Message{msg: GameMessage::ItemDrop(item_drop)}) => {
  63. assert_eq!(item_drop.item_id, 0x810001);
  64. assert_eq!(item_drop.item_bytes[1], 0x9D);
  65. },
  66. _ => panic!(),
  67. }
  68. }
  69. #[async_std::test]
  70. async fn test_enemy_drops_item_for_two_players() {
  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 ship = Box::new(ShipServerState::builder()
  75. .gateway(entity_gateway.clone())
  76. .map_builder(Box::new(|_room_mode, _event| {
  77. Maps::new(
  78. vec![MapVariant::new(MapArea::Forest2, MapVariantMode::Online)],
  79. vec![Some(MapEnemy::new(MonsterType::Hildebear, MapArea::Forest2))],
  80. Vec::new(),
  81. )
  82. }))
  83. .drop_table_builder(Box::new(|episode, difficulty, section_id| {
  84. DropTable::builder()
  85. .monster_stat(MonsterType::Hildebear, MonsterDropStats {
  86. dar: 100,
  87. drop_type: MonsterDropType::Weapon,
  88. min_meseta: 0,
  89. max_meseta: 0,
  90. })
  91. .rare_table(RareDropTable::builder()
  92. .rate(MonsterType::Hildebear, RareDropRate {
  93. rate: 1.0,
  94. item: RareDropItem::Weapon(WeaponType::DarkFlow)
  95. })
  96. .build(episode, difficulty, section_id))
  97. .build(episode, difficulty, section_id)
  98. }))
  99. .build());
  100. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  101. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  102. join_lobby(&mut ship, ClientId(1)).await;
  103. join_lobby(&mut ship, ClientId(2)).await;
  104. create_room(&mut ship, ClientId(1), "room", "").await;
  105. join_room(&mut ship, ClientId(2), 0).await;
  106. let pkt = ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::RequestItem(RequestItem {
  107. client: 0,
  108. target: 0,
  109. map_area: 2,
  110. pt_index: 0,
  111. enemy_id: 0,
  112. x: 0.0,
  113. z: 0.0,
  114. y: 0.0,
  115. })))).await.unwrap();
  116. assert_eq!(pkt[0].0, ClientId(1));
  117. match &pkt[0].1 {
  118. SendShipPacket::Message(Message{msg: GameMessage::ItemDrop(item_drop)}) => {
  119. assert_eq!(item_drop.item_id, 0x810001);
  120. assert_eq!(item_drop.item_bytes[1], 0x9D);
  121. },
  122. _ => panic!(),
  123. }
  124. assert_eq!(pkt[1].0, ClientId(2));
  125. match &pkt[1].1 {
  126. SendShipPacket::Message(Message{msg: GameMessage::ItemDrop(item_drop)}) => {
  127. assert_eq!(item_drop.item_id, 0x810002);
  128. assert_eq!(item_drop.item_bytes[1], 0x9D);
  129. },
  130. _ => panic!(),
  131. }
  132. }
  133. #[async_std::test]
  134. async fn test_enemy_drops_item_for_two_players_and_pick_up() {
  135. let mut entity_gateway = InMemoryGateway::default();
  136. let (_user1, _char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await;
  137. let (_user2, _char2) = new_user_character(&mut entity_gateway, "a2", "a", 1).await;
  138. let mut ship = Box::new(ShipServerState::builder()
  139. .gateway(entity_gateway.clone())
  140. .map_builder(Box::new(|_room_mode, _event| {
  141. Maps::new(
  142. vec![MapVariant::new(MapArea::Forest2, MapVariantMode::Online)],
  143. vec![Some(MapEnemy::new(MonsterType::Hildebear, MapArea::Forest2))],
  144. Vec::new(),
  145. )
  146. }))
  147. .drop_table_builder(Box::new(|episode, difficulty, section_id| {
  148. DropTable::builder()
  149. .monster_stat(MonsterType::Hildebear, MonsterDropStats {
  150. dar: 100,
  151. drop_type: MonsterDropType::Weapon,
  152. min_meseta: 0,
  153. max_meseta: 0,
  154. })
  155. .rare_table(RareDropTable::builder()
  156. .rate(MonsterType::Hildebear, RareDropRate {
  157. rate: 1.0,
  158. item: RareDropItem::Weapon(WeaponType::DarkFlow)
  159. })
  160. .build(episode, difficulty, section_id))
  161. .build(episode, difficulty, section_id)
  162. }))
  163. .build());
  164. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  165. log_in_char(&mut ship, ClientId(2), "a2", "a").await;
  166. join_lobby(&mut ship, ClientId(1)).await;
  167. join_lobby(&mut ship, ClientId(2)).await;
  168. create_room(&mut ship, ClientId(1), "room", "").await;
  169. join_room(&mut ship, ClientId(2), 0).await;
  170. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::RequestItem(RequestItem {
  171. client: 0,
  172. target: 0,
  173. map_area: 2,
  174. pt_index: 0,
  175. enemy_id: 0,
  176. x: 0.0,
  177. z: 0.0,
  178. y: 0.0,
  179. })))).await.unwrap();
  180. ship.handle(ClientId(2), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  181. client: 0,
  182. target: 0,
  183. item_id: 0x810002,
  184. map_area: 0,
  185. unknown: [0; 3]
  186. })))).await.unwrap();
  187. ship.handle(ClientId(1), RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::PickupItem(PickupItem {
  188. client: 0,
  189. target: 0,
  190. item_id: 0x810001,
  191. map_area: 0,
  192. unknown: [0; 3]
  193. })))).await.unwrap();
  194. }