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.

232 lines
8.2 KiB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
  1. /* TODO:
  2. 1. test to check if sjs/lame/limiter drop with Some() kill counter enabled
  3. 2. test to make sure other items drop with None kill counter
  4. 3. test kill counters get incremented per kill
  5. 4. test unsealing item:
  6. - client item id does not change
  7. - unsealed item no longer has kill counter
  8. 5. test reject unsealing item if not enough kills (can this even happen?)
  9. */
  10. use elseware::common::serverstate::{ClientId, ServerState};
  11. use elseware::entity::gateway::{EntityGateway, InMemoryGateway};
  12. use elseware::ship::ship::{ShipServerState, RecvShipPacket, SendShipPacket};
  13. use elseware::entity::character::SectionID;
  14. use elseware::ship::room::Difficulty;
  15. use elseware::ship::monster::MonsterType;
  16. use elseware::entity::item;
  17. use libpso::packet::ship::*;
  18. use libpso::packet::messages::*;
  19. #[path = "common.rs"]
  20. mod common;
  21. use common::*;
  22. #[async_std::test]
  23. async fn test_item_drops_with_kill_counter() {
  24. let mut entity_gateway = InMemoryGateway::default();
  25. let (_user1, mut char1) = new_user_character_with_sid(&mut entity_gateway, "a1", "a", SectionID::Skyly).await;
  26. char1.exp = 80000000;
  27. entity_gateway.save_character(&char1).await.unwrap();
  28. let mut ship = Box::new(ShipServerState::builder()
  29. .gateway(entity_gateway.clone())
  30. .build());
  31. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  32. join_lobby(&mut ship, ClientId(1)).await;
  33. create_ep2_room_with_difficulty(&mut ship, ClientId(1), "room", "", Difficulty::Ultimate).await;
  34. let room = ship.blocks.0[0].rooms[0].as_mut().unwrap();
  35. room.toggle_redbox_mode(); // enable redbox mode for sjs
  36. let gigue_id = room.maps.get_enemy_id_by_monster_type(MonsterType::GiGue).unwrap();
  37. let packets = ship.handle(ClientId(1), &RecvShipPacket::DirectMessage(DirectMessage::new(0, GameMessage::RequestItem(RequestItem {
  38. client: 0,
  39. target: 0,
  40. map_area: 9, // seaside
  41. pt_index: 55, // gigue ? (taken from ingame logs)
  42. enemy_id: gigue_id,
  43. x: 0.0,
  44. y: 0.0,
  45. z: 0.0,
  46. })))).await.unwrap().collect::<Vec<_>>(); // this should return 1 packet (ItemDrop)?
  47. assert!(packets.len() == 1);
  48. match &packets[0].1 {
  49. SendShipPacket::Message(Message {msg: GameMessage::ItemDrop(item_drop)}) => {
  50. assert_eq!(item_drop.item_bytes[10], 0x80)
  51. }
  52. _ => panic!("SJS didn't drop with the expected value! attr[2] should be 0x80 (128) for 0 kills")
  53. }
  54. }
  55. #[async_std::test]
  56. async fn test_all_equipped_kill_counters_increase_per_kill() {
  57. let mut entity_gateway = InMemoryGateway::default();
  58. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await;
  59. let mut ship = Box::new(ShipServerState::builder()
  60. .gateway(entity_gateway.clone())
  61. .build());
  62. let mut p1_inv = Vec::new();
  63. p1_inv.push(entity_gateway.create_item(
  64. item::NewItemEntity {
  65. item: item::ItemDetail::Weapon(
  66. item::weapon::Weapon {
  67. weapon: item::weapon::WeaponType::SealedJSword,
  68. grind: 0,
  69. special: None,
  70. attrs: [None,
  71. None,
  72. None,],
  73. tekked: true,
  74. kills: Some(0),
  75. }
  76. ),
  77. }).await.unwrap());
  78. p1_inv.push(entity_gateway.create_item(
  79. item::NewItemEntity {
  80. item: item::ItemDetail::Unit(
  81. item::unit::Unit {
  82. unit: item::unit::UnitType::Limiter,
  83. modifier: None,
  84. kills: Some(0),
  85. }
  86. ),
  87. }).await.unwrap());
  88. let equipped = item::EquippedEntity {
  89. weapon: Some(p1_inv[0].id),
  90. armor: None,
  91. shield: None,
  92. unit: [Some(p1_inv[1].id), None, None, None],
  93. mag: None,
  94. };
  95. entity_gateway.set_character_equips(&char1.id, &equipped).await.unwrap();
  96. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap();
  97. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  98. join_lobby(&mut ship, ClientId(1)).await;
  99. create_room(&mut ship, ClientId(1), "room", "").await;
  100. let enemy_id = {
  101. let room = ship.blocks.0[0].rooms[0].as_ref().unwrap();
  102. let enemy_id = (0..).filter_map(|i| {
  103. room.maps.enemy_by_id(i).ok().and_then(|enemy| {
  104. if enemy.monster == MonsterType::Booma {
  105. Some(i)
  106. }
  107. else {
  108. None
  109. }
  110. })
  111. }).next().unwrap();
  112. enemy_id
  113. };
  114. ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::KillMonster(KillMonster{
  115. client: enemy_id as u8,
  116. target: 16,
  117. map_area: 1,
  118. data: [8,0],
  119. })))).await.unwrap().for_each(drop);
  120. let equipped_items = entity_gateway.get_character_equips(&char1.id).await.unwrap();
  121. let inventory = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  122. let w = inventory.items.iter().find(|x| x.individual().unwrap().id == equipped_items.weapon.unwrap()).unwrap().individual().unwrap();
  123. let u = inventory.items.iter().find(|x| x.individual().unwrap().id == equipped_items.unit[0].unwrap()).unwrap().individual().unwrap();
  124. assert!(w.item.as_client_bytes()[11] == u.item.as_client_bytes()[11]);
  125. }
  126. #[async_std::test]
  127. async fn test_non_equipped_kill_counter_does_not_increase() {
  128. let mut entity_gateway = InMemoryGateway::default();
  129. let (_user1, char1) = new_user_character(&mut entity_gateway, "a1", "a", 1).await;
  130. let mut ship = Box::new(ShipServerState::builder()
  131. .gateway(entity_gateway.clone())
  132. .build());
  133. let mut p1_inv = Vec::new();
  134. p1_inv.push(entity_gateway.create_item(
  135. item::NewItemEntity {
  136. item: item::ItemDetail::Weapon(
  137. item::weapon::Weapon {
  138. weapon: item::weapon::WeaponType::SealedJSword,
  139. grind: 0,
  140. special: None,
  141. attrs: [None,
  142. None,
  143. None,],
  144. tekked: true,
  145. kills: Some(0),
  146. }
  147. ),
  148. }).await.unwrap());
  149. p1_inv.push(entity_gateway.create_item(
  150. item::NewItemEntity {
  151. item: item::ItemDetail::Unit(
  152. item::unit::Unit {
  153. unit: item::unit::UnitType::Limiter,
  154. modifier: None,
  155. kills: Some(0),
  156. }
  157. ),
  158. }).await.unwrap());
  159. let equipped = item::EquippedEntity {
  160. weapon: Some(p1_inv[0].id),
  161. armor: None,
  162. shield: None,
  163. unit: [None; 4],
  164. mag: None,
  165. };
  166. entity_gateway.set_character_equips(&char1.id, &equipped).await.unwrap();
  167. entity_gateway.set_character_inventory(&char1.id, &item::InventoryEntity::new(p1_inv)).await.unwrap();
  168. log_in_char(&mut ship, ClientId(1), "a1", "a").await;
  169. join_lobby(&mut ship, ClientId(1)).await;
  170. create_room(&mut ship, ClientId(1), "room", "").await;
  171. let enemy_id = {
  172. let room = ship.blocks.0[0].rooms[0].as_ref().unwrap();
  173. let enemy_id = (0..).filter_map(|i| {
  174. room.maps.enemy_by_id(i).ok().and_then(|enemy| {
  175. if enemy.monster == MonsterType::Booma {
  176. Some(i)
  177. }
  178. else {
  179. None
  180. }
  181. })
  182. }).next().unwrap();
  183. enemy_id
  184. };
  185. ship.handle(ClientId(1), &RecvShipPacket::Message(Message::new(GameMessage::KillMonster(KillMonster{
  186. client: enemy_id as u8,
  187. target: 16,
  188. map_area: 1,
  189. data: [8,0],
  190. })))).await.unwrap().for_each(drop);
  191. let equipped_items = entity_gateway.get_character_equips(&char1.id).await.unwrap();
  192. let inventory = entity_gateway.get_character_inventory(&char1.id).await.unwrap();
  193. let w = inventory.items.iter().find(|x| x.individual().unwrap().id == equipped_items.weapon.unwrap()).unwrap().individual().unwrap();
  194. let u = inventory.items.iter().find(|x| x.individual().unwrap().id == item::ItemEntityId(2)).unwrap().individual().unwrap();
  195. assert!(w.item.as_client_bytes()[11] == 1);
  196. assert!(u.item.as_client_bytes()[11] == 0);
  197. }