1
0

BuckleTest.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  1. using System.Numerics;
  2. using Content.Server.Body.Systems;
  3. using Content.Shared.Buckle;
  4. using Content.Shared.ActionBlocker;
  5. using Content.Shared.Body.Components;
  6. using Content.Shared.Body.Part;
  7. using Content.Shared.Buckle.Components;
  8. using Content.Shared.Hands.Components;
  9. using Content.Shared.Hands.EntitySystems;
  10. using Content.Shared.Standing;
  11. using Robust.Shared.GameObjects;
  12. namespace Content.IntegrationTests.Tests.Buckle
  13. {
  14. [TestFixture]
  15. [TestOf(typeof(BuckleComponent))]
  16. [TestOf(typeof(StrapComponent))]
  17. public sealed partial class BuckleTest
  18. {
  19. private const string BuckleDummyId = "BuckleDummy";
  20. private const string StrapDummyId = "StrapDummy";
  21. private const string ItemDummyId = "ItemDummy";
  22. [TestPrototypes]
  23. private const string Prototypes = $@"
  24. - type: entity
  25. name: {BuckleDummyId}
  26. id: {BuckleDummyId}
  27. components:
  28. - type: Buckle
  29. - type: Hands
  30. - type: ComplexInteraction
  31. - type: InputMover
  32. - type: Body
  33. prototype: Human
  34. - type: StandingState
  35. - type: entity
  36. name: {StrapDummyId}
  37. id: {StrapDummyId}
  38. components:
  39. - type: Strap
  40. - type: entity
  41. name: {ItemDummyId}
  42. id: {ItemDummyId}
  43. components:
  44. - type: Item
  45. ";
  46. [Test]
  47. public async Task BuckleUnbuckleCooldownRangeTest()
  48. {
  49. await using var pair = await PoolManager.GetServerClient();
  50. var server = pair.Server;
  51. var testMap = await pair.CreateTestMap();
  52. var coordinates = testMap.GridCoords;
  53. var entityManager = server.ResolveDependency<IEntityManager>();
  54. var actionBlocker = entityManager.System<ActionBlockerSystem>();
  55. var buckleSystem = entityManager.System<SharedBuckleSystem>();
  56. var standingState = entityManager.System<StandingStateSystem>();
  57. var xformSystem = entityManager.System<SharedTransformSystem>();
  58. EntityUid human = default;
  59. EntityUid chair = default;
  60. BuckleComponent buckle = null;
  61. StrapComponent strap = null;
  62. await server.WaitAssertion(() =>
  63. {
  64. human = entityManager.SpawnEntity(BuckleDummyId, coordinates);
  65. chair = entityManager.SpawnEntity(StrapDummyId, coordinates);
  66. // Default state, unbuckled
  67. Assert.That(entityManager.TryGetComponent(human, out buckle));
  68. Assert.Multiple(() =>
  69. {
  70. Assert.That(buckle, Is.Not.Null);
  71. Assert.That(buckle.BuckledTo, Is.Null);
  72. Assert.That(buckle.Buckled, Is.False);
  73. Assert.That(actionBlocker.CanMove(human));
  74. Assert.That(actionBlocker.CanChangeDirection(human));
  75. Assert.That(standingState.Down(human));
  76. Assert.That(standingState.Stand(human));
  77. });
  78. // Default state, no buckled entities, strap
  79. Assert.That(entityManager.TryGetComponent(chair, out strap));
  80. Assert.Multiple(() =>
  81. {
  82. Assert.That(strap, Is.Not.Null);
  83. Assert.That(strap.BuckledEntities, Is.Empty);
  84. });
  85. // Side effects of buckling
  86. Assert.That(buckleSystem.TryBuckle(human, human, chair, buckle));
  87. Assert.Multiple(() =>
  88. {
  89. Assert.That(buckle.BuckledTo, Is.Not.Null);
  90. Assert.That(buckle.Buckled);
  91. Assert.That(actionBlocker.CanMove(human), Is.False);
  92. Assert.That(actionBlocker.CanChangeDirection(human));
  93. Assert.That(standingState.Down(human), Is.False);
  94. Assert.That(
  95. (xformSystem.GetWorldPosition(human) - xformSystem.GetWorldPosition(chair)).LengthSquared,
  96. Is.LessThanOrEqualTo(0)
  97. );
  98. // Side effects of buckling for the strap
  99. Assert.That(strap.BuckledEntities, Does.Contain(human));
  100. });
  101. #pragma warning disable NUnit2045 // Interdependent asserts.
  102. // Trying to buckle while already buckled fails
  103. Assert.That(buckleSystem.TryBuckle(human, human, chair, buckle), Is.False);
  104. // Trying to unbuckle too quickly fails
  105. Assert.That(buckleSystem.TryUnbuckle(human, human, buckleComp: buckle), Is.False);
  106. Assert.That(buckle.Buckled);
  107. Assert.That(buckleSystem.TryUnbuckle(human, human), Is.False);
  108. Assert.That(buckle.Buckled);
  109. #pragma warning restore NUnit2045
  110. });
  111. // Wait enough ticks for the unbuckling cooldown to run out
  112. await server.WaitRunTicks(60);
  113. await server.WaitAssertion(() =>
  114. {
  115. #pragma warning disable NUnit2045 // Interdependent asserts.
  116. Assert.That(buckle.Buckled);
  117. // Still buckled
  118. #pragma warning restore NUnit2045
  119. // Unbuckle
  120. Assert.That(buckleSystem.TryUnbuckle(human, human, buckleComp: buckle));
  121. Assert.Multiple(() =>
  122. {
  123. Assert.That(buckle.BuckledTo, Is.Null);
  124. Assert.That(buckle.Buckled, Is.False);
  125. Assert.That(actionBlocker.CanMove(human));
  126. Assert.That(actionBlocker.CanChangeDirection(human));
  127. Assert.That(standingState.Down(human));
  128. // Unbuckle, strap
  129. Assert.That(strap.BuckledEntities, Is.Empty);
  130. });
  131. #pragma warning disable NUnit2045 // Interdependent asserts.
  132. // Re-buckling has no cooldown
  133. Assert.That(buckleSystem.TryBuckle(human, human, chair, buckleComp: buckle));
  134. Assert.That(buckle.Buckled);
  135. // On cooldown
  136. Assert.That(buckleSystem.TryUnbuckle(human, human, buckleComp: buckle), Is.False);
  137. Assert.That(buckle.Buckled);
  138. Assert.That(buckleSystem.TryUnbuckle(human, human), Is.False);
  139. Assert.That(buckle.Buckled);
  140. Assert.That(buckleSystem.TryUnbuckle(human, human), Is.False);
  141. Assert.That(buckle.Buckled);
  142. #pragma warning restore NUnit2045
  143. });
  144. // Wait enough ticks for the unbuckling cooldown to run out
  145. await server.WaitRunTicks(60);
  146. await server.WaitAssertion(() =>
  147. {
  148. #pragma warning disable NUnit2045 // Interdependent asserts.
  149. // Still buckled
  150. Assert.That(buckle.Buckled);
  151. // Unbuckle
  152. Assert.That(buckleSystem.TryUnbuckle(human, human, buckleComp: buckle));
  153. Assert.That(buckle.Buckled, Is.False);
  154. #pragma warning restore NUnit2045
  155. // Move away from the chair
  156. var oldWorldPosition = xformSystem.GetWorldPosition(chair);
  157. xformSystem.SetWorldPosition(human, oldWorldPosition + new Vector2(1000, 1000));
  158. // Out of range
  159. #pragma warning disable NUnit2045 // Interdependent asserts.
  160. Assert.That(buckleSystem.TryBuckle(human, human, chair, buckleComp: buckle), Is.False);
  161. Assert.That(buckleSystem.TryUnbuckle(human, human, buckleComp: buckle), Is.False);
  162. #pragma warning restore NUnit2045
  163. // Move near the chair
  164. oldWorldPosition = xformSystem.GetWorldPosition(chair);
  165. xformSystem.SetWorldPosition(human, oldWorldPosition + new Vector2(0.5f, 0));
  166. // In range
  167. #pragma warning disable NUnit2045 // Interdependent asserts.
  168. Assert.That(buckleSystem.TryBuckle(human, human, chair, buckleComp: buckle));
  169. Assert.That(buckle.Buckled);
  170. Assert.That(buckleSystem.TryUnbuckle(human, human, buckleComp: buckle), Is.False);
  171. Assert.That(buckle.Buckled);
  172. #pragma warning restore NUnit2045
  173. // Force unbuckle
  174. buckleSystem.Unbuckle(human, human);
  175. Assert.Multiple(() =>
  176. {
  177. Assert.That(buckle.Buckled, Is.False);
  178. Assert.That(actionBlocker.CanMove(human));
  179. Assert.That(actionBlocker.CanChangeDirection(human));
  180. Assert.That(standingState.Down(human));
  181. });
  182. // Re-buckle
  183. Assert.That(buckleSystem.TryBuckle(human, human, chair, buckleComp: buckle));
  184. // Move away from the chair
  185. oldWorldPosition = xformSystem.GetWorldPosition(chair);
  186. xformSystem.SetWorldPosition(human, oldWorldPosition + new Vector2(1, 0));
  187. });
  188. await server.WaitRunTicks(1);
  189. await server.WaitAssertion(() =>
  190. {
  191. // No longer buckled
  192. Assert.Multiple(() =>
  193. {
  194. Assert.That(buckle.Buckled, Is.False);
  195. Assert.That(buckle.BuckledTo, Is.Null);
  196. Assert.That(strap.BuckledEntities, Is.Empty);
  197. });
  198. });
  199. await pair.CleanReturnAsync();
  200. }
  201. [Test]
  202. public async Task BuckledDyingDropItemsTest()
  203. {
  204. await using var pair = await PoolManager.GetServerClient();
  205. var server = pair.Server;
  206. var testMap = await pair.CreateTestMap();
  207. var coordinates = testMap.GridCoords;
  208. EntityUid human = default;
  209. BuckleComponent buckle = null;
  210. HandsComponent hands = null;
  211. BodyComponent body = null;
  212. await server.WaitIdleAsync();
  213. var entityManager = server.ResolveDependency<IEntityManager>();
  214. var handsSys = entityManager.EntitySysManager.GetEntitySystem<SharedHandsSystem>();
  215. var buckleSystem = entityManager.EntitySysManager.GetEntitySystem<SharedBuckleSystem>();
  216. var xformSystem = entityManager.System<SharedTransformSystem>();
  217. await server.WaitAssertion(() =>
  218. {
  219. human = entityManager.SpawnEntity(BuckleDummyId, coordinates);
  220. var chair = entityManager.SpawnEntity(StrapDummyId, coordinates);
  221. // Component sanity check
  222. Assert.Multiple(() =>
  223. {
  224. Assert.That(entityManager.TryGetComponent(human, out buckle));
  225. Assert.That(entityManager.HasComponent<StrapComponent>(chair));
  226. Assert.That(entityManager.TryGetComponent(human, out hands));
  227. Assert.That(entityManager.TryGetComponent(human, out body));
  228. });
  229. // Buckle
  230. Assert.That(buckleSystem.TryBuckle(human, human, chair, buckleComp: buckle));
  231. Assert.Multiple(() =>
  232. {
  233. Assert.That(buckle.BuckledTo, Is.Not.Null);
  234. Assert.That(buckle.Buckled);
  235. });
  236. // Put an item into every hand
  237. for (var i = 0; i < hands.Count; i++)
  238. {
  239. var akms = entityManager.SpawnEntity(ItemDummyId, coordinates);
  240. Assert.That(handsSys.TryPickupAnyHand(human, akms));
  241. }
  242. });
  243. await server.WaitRunTicks(10);
  244. await server.WaitAssertion(() =>
  245. {
  246. // Still buckled
  247. Assert.That(buckle.Buckled);
  248. // With items in all hands
  249. foreach (var hand in hands.Hands.Values)
  250. {
  251. Assert.That(hand.HeldEntity, Is.Not.Null);
  252. }
  253. var bodySystem = entityManager.System<BodySystem>();
  254. var legs = bodySystem.GetBodyChildrenOfType(human, BodyPartType.Leg, body);
  255. // Break our guy's kneecaps
  256. foreach (var leg in legs)
  257. {
  258. entityManager.DeleteEntity(leg.Id);
  259. }
  260. });
  261. await server.WaitRunTicks(10);
  262. await server.WaitAssertion(() =>
  263. {
  264. // Still buckled
  265. Assert.That(buckle.Buckled);
  266. // Now with no item in any hand
  267. foreach (var hand in hands.Hands.Values)
  268. {
  269. Assert.That(hand.HeldEntity, Is.Null);
  270. }
  271. buckleSystem.Unbuckle(human, human);
  272. Assert.That(buckle.Buckled, Is.False);
  273. });
  274. await pair.CleanReturnAsync();
  275. }
  276. [Test]
  277. public async Task ForceUnbuckleBuckleTest()
  278. {
  279. await using var pair = await PoolManager.GetServerClient();
  280. var server = pair.Server;
  281. var testMap = await pair.CreateTestMap();
  282. var coordinates = testMap.GridCoords;
  283. var entityManager = server.ResolveDependency<IEntityManager>();
  284. var buckleSystem = entityManager.System<SharedBuckleSystem>();
  285. var xformSystem = entityManager.System<SharedTransformSystem>();
  286. EntityUid human = default;
  287. EntityUid chair = default;
  288. BuckleComponent buckle = null;
  289. await server.WaitAssertion(() =>
  290. {
  291. human = entityManager.SpawnEntity(BuckleDummyId, coordinates);
  292. chair = entityManager.SpawnEntity(StrapDummyId, coordinates);
  293. // Component sanity check
  294. Assert.Multiple(() =>
  295. {
  296. Assert.That(entityManager.TryGetComponent(human, out buckle));
  297. Assert.That(entityManager.HasComponent<StrapComponent>(chair));
  298. });
  299. // Buckle
  300. Assert.That(buckleSystem.TryBuckle(human, human, chair, buckleComp: buckle));
  301. Assert.Multiple(() =>
  302. {
  303. Assert.That(buckle.BuckledTo, Is.Not.Null);
  304. Assert.That(buckle.Buckled);
  305. });
  306. // Move the buckled entity away
  307. var oldWorldPosition = xformSystem.GetWorldPosition(chair);
  308. xformSystem.SetWorldPosition(human, oldWorldPosition + new Vector2(100, 0));
  309. });
  310. await PoolManager.WaitUntil(server, () => !buckle.Buckled, 10);
  311. Assert.That(buckle.Buckled, Is.False);
  312. await server.WaitAssertion(() =>
  313. {
  314. // Move the now unbuckled entity back onto the chair
  315. var oldWorldPosition = xformSystem.GetWorldPosition(chair);
  316. xformSystem.SetWorldPosition(human, oldWorldPosition);
  317. // Buckle
  318. Assert.That(buckleSystem.TryBuckle(human, human, chair, buckleComp: buckle));
  319. Assert.Multiple(() =>
  320. {
  321. Assert.That(buckle.BuckledTo, Is.Not.Null);
  322. Assert.That(buckle.Buckled);
  323. });
  324. });
  325. await server.WaitRunTicks(60);
  326. await server.WaitAssertion(() =>
  327. {
  328. // Still buckled
  329. Assert.Multiple(() =>
  330. {
  331. Assert.That(buckle.BuckledTo, Is.Not.Null);
  332. Assert.That(buckle.Buckled);
  333. });
  334. });
  335. await pair.CleanReturnAsync();
  336. }
  337. }
  338. }