1
0

SharedStationSpawningSystem.cs 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. using System.Linq;
  2. using Content.Shared.Hands.Components;
  3. using Content.Shared.Hands.EntitySystems;
  4. using Content.Shared.Inventory;
  5. using Content.Shared.Item;
  6. using Content.Shared.Preferences.Loadouts;
  7. using Content.Shared.Roles;
  8. using Content.Shared.Storage;
  9. using Content.Shared.Storage.EntitySystems;
  10. using Robust.Shared.Collections;
  11. using Robust.Shared.Prototypes;
  12. using Robust.Shared.Random;
  13. using Robust.Shared.Utility;
  14. namespace Content.Shared.Station;
  15. public abstract class SharedStationSpawningSystem : EntitySystem
  16. {
  17. [Dependency] protected readonly IPrototypeManager PrototypeManager = default!;
  18. [Dependency] private readonly IRobustRandom _random = default!;
  19. [Dependency] protected readonly InventorySystem InventorySystem = default!;
  20. [Dependency] private readonly SharedHandsSystem _handsSystem = default!;
  21. [Dependency] private readonly MetaDataSystem _metadata = default!;
  22. [Dependency] private readonly SharedStorageSystem _storage = default!;
  23. [Dependency] private readonly SharedTransformSystem _xformSystem = default!;
  24. private EntityQuery<HandsComponent> _handsQuery;
  25. private EntityQuery<InventoryComponent> _inventoryQuery;
  26. private EntityQuery<StorageComponent> _storageQuery;
  27. private EntityQuery<TransformComponent> _xformQuery;
  28. public override void Initialize()
  29. {
  30. base.Initialize();
  31. _handsQuery = GetEntityQuery<HandsComponent>();
  32. _inventoryQuery = GetEntityQuery<InventoryComponent>();
  33. _storageQuery = GetEntityQuery<StorageComponent>();
  34. _xformQuery = GetEntityQuery<TransformComponent>();
  35. }
  36. /// <summary>
  37. /// Equips the data from a `RoleLoadout` onto an entity.
  38. /// </summary>
  39. public void EquipRoleLoadout(EntityUid entity, RoleLoadout loadout, RoleLoadoutPrototype roleProto)
  40. {
  41. // Order loadout selections by the order they appear on the prototype.
  42. foreach (var group in loadout.SelectedLoadouts.OrderBy(x => roleProto.Groups.FindIndex(e => e == x.Key)))
  43. {
  44. foreach (var items in group.Value)
  45. {
  46. if (!PrototypeManager.TryIndex(items.Prototype, out var loadoutProto))
  47. {
  48. Log.Error($"Unable to find loadout prototype for {items.Prototype}");
  49. continue;
  50. }
  51. EquipStartingGear(entity, loadoutProto, raiseEvent: false);
  52. }
  53. }
  54. EquipRoleName(entity, loadout, roleProto);
  55. }
  56. /// <summary>
  57. /// Applies the role's name as applicable to the entity.
  58. /// </summary>
  59. public void EquipRoleName(EntityUid entity, RoleLoadout loadout, RoleLoadoutPrototype roleProto)
  60. {
  61. string? name = null;
  62. if (roleProto.CanCustomizeName)
  63. {
  64. name = loadout.EntityName;
  65. }
  66. if (string.IsNullOrEmpty(name) && PrototypeManager.TryIndex(roleProto.NameDataset, out var nameData))
  67. {
  68. name = Loc.GetString(_random.Pick(nameData.Values));
  69. }
  70. if (!string.IsNullOrEmpty(name))
  71. {
  72. _metadata.SetEntityName(entity, name);
  73. }
  74. }
  75. public void EquipStartingGear(EntityUid entity, LoadoutPrototype loadout, bool raiseEvent = true)
  76. {
  77. EquipStartingGear(entity, loadout.StartingGear, raiseEvent);
  78. EquipStartingGear(entity, (IEquipmentLoadout) loadout, raiseEvent);
  79. }
  80. /// <summary>
  81. /// <see cref="EquipStartingGear(Robust.Shared.GameObjects.EntityUid,System.Nullable{Robust.Shared.Prototypes.ProtoId{Content.Shared.Roles.StartingGearPrototype}},bool)"/>
  82. /// </summary>
  83. public void EquipStartingGear(EntityUid entity, ProtoId<StartingGearPrototype>? startingGear, bool raiseEvent = true)
  84. {
  85. PrototypeManager.TryIndex(startingGear, out var gearProto);
  86. EquipStartingGear(entity, gearProto, raiseEvent);
  87. }
  88. /// <summary>
  89. /// <see cref="EquipStartingGear(Robust.Shared.GameObjects.EntityUid,System.Nullable{Robust.Shared.Prototypes.ProtoId{Content.Shared.Roles.StartingGearPrototype}},bool)"/>
  90. /// </summary>
  91. public void EquipStartingGear(EntityUid entity, StartingGearPrototype? startingGear, bool raiseEvent = true)
  92. {
  93. EquipStartingGear(entity, (IEquipmentLoadout?) startingGear, raiseEvent);
  94. }
  95. /// <summary>
  96. /// Equips starting gear onto the given entity.
  97. /// </summary>
  98. /// <param name="entity">Entity to load out.</param>
  99. /// <param name="startingGear">Starting gear to use.</param>
  100. /// <param name="raiseEvent">Should we raise the event for equipped. Set to false if you will call this manually</param>
  101. public void EquipStartingGear(EntityUid entity, IEquipmentLoadout? startingGear, bool raiseEvent = true)
  102. {
  103. if (startingGear == null)
  104. return;
  105. var xform = _xformQuery.GetComponent(entity);
  106. if (InventorySystem.TryGetSlots(entity, out var slotDefinitions))
  107. {
  108. foreach (var slot in slotDefinitions)
  109. {
  110. var equipmentStr = startingGear.GetGear(slot.Name);
  111. if (!string.IsNullOrEmpty(equipmentStr))
  112. {
  113. var equipmentEntity = EntityManager.SpawnEntity(equipmentStr, xform.Coordinates);
  114. InventorySystem.TryEquip(entity, equipmentEntity, slot.Name, silent: true, force: true);
  115. }
  116. }
  117. }
  118. if (_handsQuery.TryComp(entity, out var handsComponent))
  119. {
  120. var inhand = startingGear.Inhand;
  121. var coords = xform.Coordinates;
  122. foreach (var prototype in inhand)
  123. {
  124. var inhandEntity = EntityManager.SpawnEntity(prototype, coords);
  125. if (_handsSystem.TryGetEmptyHand(entity, out var emptyHand, handsComponent))
  126. {
  127. _handsSystem.TryPickup(entity, inhandEntity, emptyHand, checkActionBlocker: false, handsComp: handsComponent);
  128. }
  129. }
  130. }
  131. if (startingGear.Storage.Count > 0)
  132. {
  133. var coords = _xformSystem.GetMapCoordinates(entity);
  134. _inventoryQuery.TryComp(entity, out var inventoryComp);
  135. foreach (var (slotName, entProtos) in startingGear.Storage)
  136. {
  137. if (entProtos == null || entProtos.Count == 0)
  138. continue;
  139. if (inventoryComp != null &&
  140. InventorySystem.TryGetSlotEntity(entity, slotName, out var slotEnt, inventoryComponent: inventoryComp) &&
  141. _storageQuery.TryComp(slotEnt, out var storage))
  142. {
  143. foreach (var entProto in entProtos)
  144. {
  145. var spawnedEntity = Spawn(entProto, coords);
  146. _storage.Insert(slotEnt.Value, spawnedEntity, out _, storageComp: storage, playSound: false);
  147. }
  148. }
  149. }
  150. }
  151. if (raiseEvent)
  152. {
  153. var ev = new StartingGearEquippedEvent(entity);
  154. RaiseLocalEvent(entity, ref ev);
  155. }
  156. }
  157. }