1
0

GameRuleSystem.Utility.cs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. using System.Diagnostics.CodeAnalysis;
  2. using System.Linq;
  3. using Content.Server.GameTicking.Rules.Components;
  4. using Content.Server.Station.Components;
  5. using Content.Shared.GameTicking.Components;
  6. using Content.Shared.Random.Helpers;
  7. using Robust.Server.GameObjects;
  8. using Robust.Shared.Collections;
  9. using Robust.Shared.Map;
  10. using Robust.Shared.Map.Components;
  11. using Robust.Shared.Random;
  12. namespace Content.Server.GameTicking.Rules;
  13. public abstract partial class GameRuleSystem<T> where T: IComponent
  14. {
  15. protected EntityQueryEnumerator<ActiveGameRuleComponent, T, GameRuleComponent> QueryActiveRules()
  16. {
  17. return EntityQueryEnumerator<ActiveGameRuleComponent, T, GameRuleComponent>();
  18. }
  19. protected EntityQueryEnumerator<DelayedStartRuleComponent, T, GameRuleComponent> QueryDelayedRules()
  20. {
  21. return EntityQueryEnumerator<DelayedStartRuleComponent, T, GameRuleComponent>();
  22. }
  23. /// <summary>
  24. /// Queries all gamerules, regardless of if they're active or not.
  25. /// </summary>
  26. protected EntityQueryEnumerator<T, GameRuleComponent> QueryAllRules()
  27. {
  28. return EntityQueryEnumerator<T, GameRuleComponent>();
  29. }
  30. /// <summary>
  31. /// Utility function for finding a random event-eligible station entity
  32. /// </summary>
  33. protected bool TryGetRandomStation([NotNullWhen(true)] out EntityUid? station, Func<EntityUid, bool>? filter = null)
  34. {
  35. var stations = new ValueList<EntityUid>(Count<StationEventEligibleComponent>());
  36. filter ??= _ => true;
  37. var query = AllEntityQuery<StationEventEligibleComponent>();
  38. while (query.MoveNext(out var uid, out _))
  39. {
  40. if (!filter(uid))
  41. continue;
  42. stations.Add(uid);
  43. }
  44. if (stations.Count == 0)
  45. {
  46. station = null;
  47. return false;
  48. }
  49. // TODO: Engine PR.
  50. station = stations[RobustRandom.Next(stations.Count)];
  51. return true;
  52. }
  53. protected bool TryFindRandomTile(out Vector2i tile,
  54. [NotNullWhen(true)] out EntityUid? targetStation,
  55. out EntityUid targetGrid,
  56. out EntityCoordinates targetCoords)
  57. {
  58. tile = default;
  59. targetStation = EntityUid.Invalid;
  60. targetGrid = EntityUid.Invalid;
  61. targetCoords = EntityCoordinates.Invalid;
  62. if (TryGetRandomStation(out targetStation))
  63. {
  64. return TryFindRandomTileOnStation((targetStation.Value, Comp<StationDataComponent>(targetStation.Value)),
  65. out tile,
  66. out targetGrid,
  67. out targetCoords);
  68. }
  69. return false;
  70. }
  71. protected bool TryFindRandomTileOnStation(Entity<StationDataComponent> station,
  72. out Vector2i tile,
  73. out EntityUid targetGrid,
  74. out EntityCoordinates targetCoords)
  75. {
  76. tile = default;
  77. targetCoords = EntityCoordinates.Invalid;
  78. targetGrid = EntityUid.Invalid;
  79. // Weight grid choice by tilecount
  80. var weights = new Dictionary<Entity<MapGridComponent>, float>();
  81. foreach (var possibleTarget in station.Comp.Grids)
  82. {
  83. if (!TryComp<MapGridComponent>(possibleTarget, out var comp))
  84. continue;
  85. weights.Add((possibleTarget, comp), _map.GetAllTiles(possibleTarget, comp).Count());
  86. }
  87. if (weights.Count == 0)
  88. {
  89. targetGrid = EntityUid.Invalid;
  90. return false;
  91. }
  92. (targetGrid, var gridComp) = RobustRandom.Pick(weights);
  93. var found = false;
  94. var aabb = gridComp.LocalAABB;
  95. for (var i = 0; i < 10; i++)
  96. {
  97. var randomX = RobustRandom.Next((int) aabb.Left, (int) aabb.Right);
  98. var randomY = RobustRandom.Next((int) aabb.Bottom, (int) aabb.Top);
  99. tile = new Vector2i(randomX, randomY);
  100. if (_atmosphere.IsTileSpace(targetGrid, Transform(targetGrid).MapUid, tile)
  101. || _atmosphere.IsTileAirBlocked(targetGrid, tile, mapGridComp: gridComp))
  102. {
  103. continue;
  104. }
  105. found = true;
  106. targetCoords = _map.GridTileToLocal(targetGrid, gridComp, tile);
  107. break;
  108. }
  109. return found;
  110. }
  111. protected void ForceEndSelf(EntityUid uid, GameRuleComponent? component = null)
  112. {
  113. GameTicker.EndGameRule(uid, component);
  114. }
  115. }