1
0

InteractionTest.EntitySpecifierCollection.cs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. #nullable enable
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using Content.Shared.Stacks;
  5. using Robust.Shared.GameObjects;
  6. using Robust.Shared.Prototypes;
  7. using Robust.Shared.Utility;
  8. using static Robust.UnitTesting.RobustIntegrationTest;
  9. namespace Content.IntegrationTests.Tests.Interaction;
  10. public abstract partial class InteractionTest
  11. {
  12. /// <summary>
  13. /// Data structure for representing a collection of <see cref="EntitySpecifier"/>s.
  14. /// </summary>
  15. protected sealed class EntitySpecifierCollection
  16. {
  17. public Dictionary<string, int> Entities = new();
  18. /// <summary>
  19. /// If true, a check has been performed to see if the prototypes correspond to entity prototypes with a stack
  20. /// component, in which case the specifier was converted into a stack-specifier
  21. /// </summary>
  22. public bool Converted;
  23. public EntitySpecifierCollection()
  24. {
  25. Converted = true;
  26. }
  27. public EntitySpecifierCollection(IEnumerable<EntitySpecifier> ents)
  28. {
  29. Converted = true;
  30. foreach (var ent in ents)
  31. {
  32. Add(ent);
  33. }
  34. }
  35. public static implicit operator EntitySpecifierCollection(string prototype)
  36. {
  37. var result = new EntitySpecifierCollection();
  38. result.Add(prototype, 1);
  39. return result;
  40. }
  41. public static implicit operator EntitySpecifierCollection((string, int) tuple)
  42. {
  43. var result = new EntitySpecifierCollection();
  44. result.Add(tuple.Item1, tuple.Item2);
  45. return result;
  46. }
  47. public void Remove(EntitySpecifier spec)
  48. {
  49. Add(new EntitySpecifier(spec.Prototype, -spec.Quantity, spec.Converted));
  50. }
  51. public void Add(EntitySpecifier spec)
  52. {
  53. Add(spec.Prototype, spec.Quantity, spec.Converted);
  54. }
  55. public void Add(string id, int quantity, bool converted = false)
  56. {
  57. Converted &= converted;
  58. if (!Entities.TryGetValue(id, out var existing))
  59. {
  60. if (quantity != 0)
  61. Entities.Add(id, quantity);
  62. return;
  63. }
  64. var newQuantity = quantity + existing;
  65. if (newQuantity == 0)
  66. Entities.Remove(id);
  67. else
  68. Entities[id] = newQuantity;
  69. }
  70. public void Add(EntitySpecifierCollection collection)
  71. {
  72. var converted = Converted && collection.Converted;
  73. foreach (var (id, quantity) in collection.Entities)
  74. {
  75. Add(id, quantity);
  76. }
  77. Converted = converted;
  78. }
  79. public void Remove(EntitySpecifierCollection collection)
  80. {
  81. var converted = Converted && collection.Converted;
  82. foreach (var (id, quantity) in collection.Entities)
  83. {
  84. Add(id, -quantity);
  85. }
  86. Converted = converted;
  87. }
  88. public EntitySpecifierCollection Clone()
  89. {
  90. return new EntitySpecifierCollection()
  91. {
  92. Entities = Entities.ShallowClone(),
  93. Converted = Converted
  94. };
  95. }
  96. /// <summary>
  97. /// Convert applicable entity prototypes into stack prototypes.
  98. /// </summary>
  99. public async Task ConvertToStacks(IPrototypeManager protoMan, IComponentFactory factory, ServerIntegrationInstance server)
  100. {
  101. if (Converted)
  102. return;
  103. HashSet<string> toRemove = new();
  104. List<(string, int)> toAdd = new();
  105. foreach (var (id, quantity) in Entities)
  106. {
  107. if (protoMan.HasIndex<StackPrototype>(id))
  108. continue;
  109. if (!protoMan.TryIndex<EntityPrototype>(id, out var entProto))
  110. {
  111. Assert.Fail($"Unknown prototype: {id}");
  112. continue;
  113. }
  114. StackComponent? stack = null;
  115. await server.WaitPost(() =>
  116. {
  117. entProto.TryGetComponent(factory.GetComponentName(typeof(StackComponent)), out stack);
  118. });
  119. if (stack == null)
  120. continue;
  121. toRemove.Add(id);
  122. toAdd.Add((stack.StackTypeId, quantity));
  123. }
  124. foreach (var id in toRemove)
  125. {
  126. Entities.Remove(id);
  127. }
  128. foreach (var (id, quantity) in toAdd)
  129. {
  130. Add(id, quantity);
  131. }
  132. Converted = true;
  133. }
  134. }
  135. protected EntitySpecifierCollection ToEntityCollection(IEnumerable<EntityUid> entities)
  136. {
  137. var collection = new EntitySpecifierCollection(entities
  138. .Select(ToEntitySpecifier)
  139. .OfType<EntitySpecifier>());
  140. Assert.That(collection.Converted);
  141. return collection;
  142. }
  143. }