InteractionSystemTests.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. #nullable enable annotations
  2. using System.Numerics;
  3. using Content.Server.Interaction;
  4. using Content.Shared.Hands.Components;
  5. using Content.Shared.Hands.EntitySystems;
  6. using Content.Shared.Interaction;
  7. using Content.Shared.Interaction.Components;
  8. using Content.Shared.Item;
  9. using Robust.Shared.Containers;
  10. using Robust.Shared.GameObjects;
  11. using Robust.Shared.Map;
  12. using Robust.Shared.Maths;
  13. using Robust.Shared.Reflection;
  14. namespace Content.IntegrationTests.Tests.Interaction.Click
  15. {
  16. [TestFixture]
  17. [TestOf(typeof(InteractionSystem))]
  18. public sealed class InteractionSystemTests
  19. {
  20. [TestPrototypes]
  21. private const string Prototypes = @"
  22. - type: entity
  23. id: DummyDebugWall
  24. components:
  25. - type: Physics
  26. bodyType: Dynamic
  27. - type: Fixtures
  28. fixtures:
  29. fix1:
  30. shape:
  31. !type:PhysShapeAabb
  32. bounds: ""-0.25,-0.25,0.25,0.25""
  33. layer:
  34. - MobMask
  35. mask:
  36. - MobMask
  37. ";
  38. [Test]
  39. public async Task InteractionTest()
  40. {
  41. await using var pair = await PoolManager.GetServerClient();
  42. var server = pair.Server;
  43. var sEntities = server.ResolveDependency<IEntityManager>();
  44. var mapManager = server.ResolveDependency<IMapManager>();
  45. var sysMan = server.ResolveDependency<IEntitySystemManager>();
  46. var handSys = sysMan.GetEntitySystem<SharedHandsSystem>();
  47. var map = await pair.CreateTestMap();
  48. var mapId = map.MapId;
  49. var coords = map.MapCoords;
  50. await server.WaitIdleAsync();
  51. EntityUid user = default;
  52. EntityUid target = default;
  53. EntityUid item = default;
  54. await server.WaitAssertion(() =>
  55. {
  56. user = sEntities.SpawnEntity(null, coords);
  57. sEntities.EnsureComponent<HandsComponent>(user);
  58. sEntities.EnsureComponent<ComplexInteractionComponent>(user);
  59. handSys.AddHand(user, "hand", HandLocation.Left);
  60. target = sEntities.SpawnEntity(null, coords);
  61. item = sEntities.SpawnEntity(null, coords);
  62. sEntities.EnsureComponent<ItemComponent>(item);
  63. });
  64. await server.WaitRunTicks(1);
  65. var entitySystemManager = server.ResolveDependency<IEntitySystemManager>();
  66. InteractionSystem interactionSystem = default!;
  67. TestInteractionSystem testInteractionSystem = default!;
  68. Assert.Multiple(() =>
  69. {
  70. Assert.That(entitySystemManager.TryGetEntitySystem(out interactionSystem));
  71. Assert.That(entitySystemManager.TryGetEntitySystem(out testInteractionSystem));
  72. });
  73. var interactUsing = false;
  74. var interactHand = false;
  75. await server.WaitAssertion(() =>
  76. {
  77. testInteractionSystem.InteractUsingEvent = (ev) => { Assert.That(ev.Target, Is.EqualTo(target)); interactUsing = true; };
  78. testInteractionSystem.InteractHandEvent = (ev) => { Assert.That(ev.Target, Is.EqualTo(target)); interactHand = true; };
  79. interactionSystem.UserInteraction(user, sEntities.GetComponent<TransformComponent>(target).Coordinates, target);
  80. Assert.Multiple(() =>
  81. {
  82. Assert.That(interactUsing, Is.False);
  83. Assert.That(interactHand);
  84. });
  85. Assert.That(handSys.TryPickup(user, item));
  86. interactionSystem.UserInteraction(user, sEntities.GetComponent<TransformComponent>(target).Coordinates, target);
  87. Assert.That(interactUsing);
  88. });
  89. testInteractionSystem.ClearHandlers();
  90. await pair.CleanReturnAsync();
  91. }
  92. [Test]
  93. public async Task InteractionObstructionTest()
  94. {
  95. await using var pair = await PoolManager.GetServerClient();
  96. var server = pair.Server;
  97. var sEntities = server.ResolveDependency<IEntityManager>();
  98. var mapManager = server.ResolveDependency<IMapManager>();
  99. var sysMan = server.ResolveDependency<IEntitySystemManager>();
  100. var handSys = sysMan.GetEntitySystem<SharedHandsSystem>();
  101. var map = await pair.CreateTestMap();
  102. var mapId = map.MapId;
  103. var coords = map.MapCoords;
  104. await server.WaitIdleAsync();
  105. EntityUid user = default;
  106. EntityUid target = default;
  107. EntityUid item = default;
  108. EntityUid wall = default;
  109. await server.WaitAssertion(() =>
  110. {
  111. user = sEntities.SpawnEntity(null, coords);
  112. sEntities.EnsureComponent<HandsComponent>(user);
  113. handSys.AddHand(user, "hand", HandLocation.Left);
  114. target = sEntities.SpawnEntity(null, new MapCoordinates(new Vector2(1.9f, 0), mapId));
  115. item = sEntities.SpawnEntity(null, coords);
  116. sEntities.EnsureComponent<ItemComponent>(item);
  117. wall = sEntities.SpawnEntity("DummyDebugWall", new MapCoordinates(new Vector2(1, 0), sEntities.GetComponent<TransformComponent>(user).MapID));
  118. });
  119. await server.WaitRunTicks(1);
  120. var entitySystemManager = server.ResolveDependency<IEntitySystemManager>();
  121. InteractionSystem interactionSystem = default!;
  122. TestInteractionSystem testInteractionSystem = default!;
  123. Assert.Multiple(() =>
  124. {
  125. Assert.That(entitySystemManager.TryGetEntitySystem(out interactionSystem));
  126. Assert.That(entitySystemManager.TryGetEntitySystem(out testInteractionSystem));
  127. });
  128. var interactUsing = false;
  129. var interactHand = false;
  130. await server.WaitAssertion(() =>
  131. {
  132. testInteractionSystem.InteractUsingEvent = (ev) => { Assert.That(ev.Target, Is.EqualTo(target)); interactUsing = true; };
  133. testInteractionSystem.InteractHandEvent = (ev) => { Assert.That(ev.Target, Is.EqualTo(target)); interactHand = true; };
  134. interactionSystem.UserInteraction(user, sEntities.GetComponent<TransformComponent>(target).Coordinates, target);
  135. Assert.Multiple(() =>
  136. {
  137. Assert.That(interactUsing, Is.False);
  138. Assert.That(interactHand, Is.False);
  139. });
  140. Assert.That(handSys.TryPickup(user, item));
  141. interactionSystem.UserInteraction(user, sEntities.GetComponent<TransformComponent>(target).Coordinates, target);
  142. Assert.That(interactUsing, Is.False);
  143. });
  144. testInteractionSystem.ClearHandlers();
  145. await pair.CleanReturnAsync();
  146. }
  147. [Test]
  148. public async Task InteractionInRangeTest()
  149. {
  150. await using var pair = await PoolManager.GetServerClient();
  151. var server = pair.Server;
  152. var sEntities = server.ResolveDependency<IEntityManager>();
  153. var mapManager = server.ResolveDependency<IMapManager>();
  154. var sysMan = server.ResolveDependency<IEntitySystemManager>();
  155. var handSys = sysMan.GetEntitySystem<SharedHandsSystem>();
  156. var map = await pair.CreateTestMap();
  157. var mapId = map.MapId;
  158. var coords = map.MapCoords;
  159. await server.WaitIdleAsync();
  160. EntityUid user = default;
  161. EntityUid target = default;
  162. EntityUid item = default;
  163. await server.WaitAssertion(() =>
  164. {
  165. user = sEntities.SpawnEntity(null, coords);
  166. sEntities.EnsureComponent<HandsComponent>(user);
  167. sEntities.EnsureComponent<ComplexInteractionComponent>(user);
  168. handSys.AddHand(user, "hand", HandLocation.Left);
  169. target = sEntities.SpawnEntity(null, new MapCoordinates(new Vector2(SharedInteractionSystem.InteractionRange - 0.1f, 0), mapId));
  170. item = sEntities.SpawnEntity(null, coords);
  171. sEntities.EnsureComponent<ItemComponent>(item);
  172. });
  173. await server.WaitRunTicks(1);
  174. var entitySystemManager = server.ResolveDependency<IEntitySystemManager>();
  175. InteractionSystem interactionSystem = default!;
  176. TestInteractionSystem testInteractionSystem = default!;
  177. Assert.Multiple(() =>
  178. {
  179. Assert.That(entitySystemManager.TryGetEntitySystem(out interactionSystem));
  180. Assert.That(entitySystemManager.TryGetEntitySystem(out testInteractionSystem));
  181. });
  182. var interactUsing = false;
  183. var interactHand = false;
  184. await server.WaitAssertion(() =>
  185. {
  186. testInteractionSystem.InteractUsingEvent = (ev) => { Assert.That(ev.Target, Is.EqualTo(target)); interactUsing = true; };
  187. testInteractionSystem.InteractHandEvent = (ev) => { Assert.That(ev.Target, Is.EqualTo(target)); interactHand = true; };
  188. interactionSystem.UserInteraction(user, sEntities.GetComponent<TransformComponent>(target).Coordinates, target);
  189. Assert.Multiple(() =>
  190. {
  191. Assert.That(interactUsing, Is.False);
  192. Assert.That(interactHand);
  193. });
  194. Assert.That(handSys.TryPickup(user, item));
  195. interactionSystem.UserInteraction(user, sEntities.GetComponent<TransformComponent>(target).Coordinates, target);
  196. Assert.That(interactUsing);
  197. });
  198. testInteractionSystem.ClearHandlers();
  199. await pair.CleanReturnAsync();
  200. }
  201. [Test]
  202. public async Task InteractionOutOfRangeTest()
  203. {
  204. await using var pair = await PoolManager.GetServerClient();
  205. var server = pair.Server;
  206. var sEntities = server.ResolveDependency<IEntityManager>();
  207. var mapManager = server.ResolveDependency<IMapManager>();
  208. var sysMan = server.ResolveDependency<IEntitySystemManager>();
  209. var handSys = sysMan.GetEntitySystem<SharedHandsSystem>();
  210. var map = await pair.CreateTestMap();
  211. var mapId = map.MapId;
  212. var coords = map.MapCoords;
  213. await server.WaitIdleAsync();
  214. EntityUid user = default;
  215. EntityUid target = default;
  216. EntityUid item = default;
  217. await server.WaitAssertion(() =>
  218. {
  219. user = sEntities.SpawnEntity(null, coords);
  220. sEntities.EnsureComponent<HandsComponent>(user);
  221. handSys.AddHand(user, "hand", HandLocation.Left);
  222. target = sEntities.SpawnEntity(null, new MapCoordinates(new Vector2(SharedInteractionSystem.InteractionRange + 0.01f, 0), mapId));
  223. item = sEntities.SpawnEntity(null, coords);
  224. sEntities.EnsureComponent<ItemComponent>(item);
  225. });
  226. await server.WaitRunTicks(1);
  227. var entitySystemManager = server.ResolveDependency<IEntitySystemManager>();
  228. InteractionSystem interactionSystem = default!;
  229. TestInteractionSystem testInteractionSystem = default!;
  230. Assert.Multiple(() =>
  231. {
  232. Assert.That(entitySystemManager.TryGetEntitySystem(out interactionSystem));
  233. Assert.That(entitySystemManager.TryGetEntitySystem(out testInteractionSystem));
  234. });
  235. var interactUsing = false;
  236. var interactHand = false;
  237. await server.WaitAssertion(() =>
  238. {
  239. testInteractionSystem.InteractUsingEvent = (ev) => { Assert.That(ev.Target, Is.EqualTo(target)); interactUsing = true; };
  240. testInteractionSystem.InteractHandEvent = (ev) => { Assert.That(ev.Target, Is.EqualTo(target)); interactHand = true; };
  241. interactionSystem.UserInteraction(user, sEntities.GetComponent<TransformComponent>(target).Coordinates, target);
  242. Assert.Multiple(() =>
  243. {
  244. Assert.That(interactUsing, Is.False);
  245. Assert.That(interactHand, Is.False);
  246. });
  247. Assert.That(handSys.TryPickup(user, item));
  248. interactionSystem.UserInteraction(user, sEntities.GetComponent<TransformComponent>(target).Coordinates, target);
  249. Assert.That(interactUsing, Is.False);
  250. });
  251. testInteractionSystem.ClearHandlers();
  252. await pair.CleanReturnAsync();
  253. }
  254. [Test]
  255. public async Task InsideContainerInteractionBlockTest()
  256. {
  257. await using var pair = await PoolManager.GetServerClient();
  258. var server = pair.Server;
  259. var sEntities = server.ResolveDependency<IEntityManager>();
  260. var mapManager = server.ResolveDependency<IMapManager>();
  261. var sysMan = server.ResolveDependency<IEntitySystemManager>();
  262. var handSys = sysMan.GetEntitySystem<SharedHandsSystem>();
  263. var conSystem = sysMan.GetEntitySystem<SharedContainerSystem>();
  264. var map = await pair.CreateTestMap();
  265. var mapId = map.MapId;
  266. var coords = map.MapCoords;
  267. await server.WaitIdleAsync();
  268. EntityUid user = default;
  269. EntityUid target = default;
  270. EntityUid item = default;
  271. EntityUid containerEntity = default;
  272. BaseContainer container = null;
  273. await server.WaitAssertion(() =>
  274. {
  275. user = sEntities.SpawnEntity(null, coords);
  276. sEntities.EnsureComponent<HandsComponent>(user);
  277. sEntities.EnsureComponent<ComplexInteractionComponent>(user);
  278. handSys.AddHand(user, "hand", HandLocation.Left);
  279. target = sEntities.SpawnEntity(null, coords);
  280. item = sEntities.SpawnEntity(null, coords);
  281. sEntities.EnsureComponent<ItemComponent>(item);
  282. containerEntity = sEntities.SpawnEntity(null, coords);
  283. container = conSystem.EnsureContainer<Container>(containerEntity, "InteractionTestContainer");
  284. });
  285. await server.WaitRunTicks(1);
  286. var entitySystemManager = server.ResolveDependency<IEntitySystemManager>();
  287. InteractionSystem interactionSystem = default!;
  288. TestInteractionSystem testInteractionSystem = default!;
  289. Assert.Multiple(() =>
  290. {
  291. Assert.That(entitySystemManager.TryGetEntitySystem(out interactionSystem));
  292. Assert.That(entitySystemManager.TryGetEntitySystem(out testInteractionSystem));
  293. });
  294. await server.WaitIdleAsync();
  295. var interactUsing = false;
  296. var interactHand = false;
  297. await server.WaitAssertion(() =>
  298. {
  299. #pragma warning disable NUnit2045 // Interdependent assertions.
  300. Assert.That(conSystem.Insert(user, container));
  301. Assert.That(sEntities.GetComponent<TransformComponent>(user).ParentUid, Is.EqualTo(containerEntity));
  302. #pragma warning restore NUnit2045
  303. testInteractionSystem.InteractUsingEvent = (ev) => { Assert.That(ev.Target, Is.EqualTo(containerEntity)); interactUsing = true; };
  304. testInteractionSystem.InteractHandEvent = (ev) => { Assert.That(ev.Target, Is.EqualTo(containerEntity)); interactHand = true; };
  305. interactionSystem.UserInteraction(user, sEntities.GetComponent<TransformComponent>(target).Coordinates, target);
  306. Assert.Multiple(() =>
  307. {
  308. Assert.That(interactUsing, Is.False);
  309. Assert.That(interactHand, Is.False);
  310. });
  311. interactionSystem.UserInteraction(user, sEntities.GetComponent<TransformComponent>(containerEntity).Coordinates, containerEntity);
  312. Assert.Multiple(() =>
  313. {
  314. Assert.That(interactUsing, Is.False);
  315. Assert.That(interactHand);
  316. });
  317. Assert.That(handSys.TryPickup(user, item));
  318. interactionSystem.UserInteraction(user, sEntities.GetComponent<TransformComponent>(target).Coordinates, target);
  319. Assert.That(interactUsing, Is.False);
  320. interactionSystem.UserInteraction(user, sEntities.GetComponent<TransformComponent>(containerEntity).Coordinates, containerEntity);
  321. Assert.That(interactUsing, Is.True);
  322. });
  323. testInteractionSystem.ClearHandlers();
  324. await pair.CleanReturnAsync();
  325. }
  326. public sealed class TestInteractionSystem : EntitySystem
  327. {
  328. public EntityEventHandler<InteractUsingEvent>? InteractUsingEvent;
  329. public EntityEventHandler<InteractHandEvent>? InteractHandEvent;
  330. public override void Initialize()
  331. {
  332. base.Initialize();
  333. SubscribeLocalEvent<InteractUsingEvent>((e) => InteractUsingEvent?.Invoke(e));
  334. SubscribeLocalEvent<InteractHandEvent>((e) => InteractHandEvent?.Invoke(e));
  335. }
  336. public void ClearHandlers()
  337. {
  338. InteractUsingEvent = null;
  339. InteractHandEvent = null;
  340. }
  341. }
  342. }
  343. }