SetOutfitCommand.cs 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. using Content.Server.Administration.UI;
  2. using Content.Server.EUI;
  3. using Content.Server.Hands.Systems;
  4. using Content.Server.Preferences.Managers;
  5. using Content.Shared.Access.Components;
  6. using Content.Shared.Administration;
  7. using Content.Shared.Clothing;
  8. using Content.Shared.Hands.Components;
  9. using Content.Shared.Humanoid;
  10. using Content.Shared.Inventory;
  11. using Content.Shared.PDA;
  12. using Content.Shared.Preferences;
  13. using Content.Shared.Preferences.Loadouts;
  14. using Content.Shared.Roles;
  15. using Content.Shared.Station;
  16. using Robust.Shared.Console;
  17. using Robust.Shared.Player;
  18. using Robust.Shared.Prototypes;
  19. namespace Content.Server.Administration.Commands
  20. {
  21. [AdminCommand(AdminFlags.Admin)]
  22. public sealed class SetOutfitCommand : IConsoleCommand
  23. {
  24. [Dependency] private readonly IEntityManager _entities = default!;
  25. public string Command => "setoutfit";
  26. public string Description => Loc.GetString("set-outfit-command-description", ("requiredComponent", nameof(InventoryComponent)));
  27. public string Help => Loc.GetString("set-outfit-command-help-text", ("command", Command));
  28. public void Execute(IConsoleShell shell, string argStr, string[] args)
  29. {
  30. if (args.Length < 1)
  31. {
  32. shell.WriteLine(Loc.GetString("shell-wrong-arguments-number"));
  33. return;
  34. }
  35. if (!int.TryParse(args[0], out var entInt))
  36. {
  37. shell.WriteLine(Loc.GetString("shell-entity-uid-must-be-number"));
  38. return;
  39. }
  40. var nent = new NetEntity(entInt);
  41. if (!_entities.TryGetEntity(nent, out var target))
  42. {
  43. shell.WriteLine(Loc.GetString("shell-invalid-entity-id"));
  44. return;
  45. }
  46. if (!_entities.HasComponent<InventoryComponent>(target))
  47. {
  48. shell.WriteLine(Loc.GetString("shell-target-entity-does-not-have-message", ("missing", "inventory")));
  49. return;
  50. }
  51. if (args.Length == 1)
  52. {
  53. if (shell.Player is not { } player)
  54. {
  55. shell.WriteError(Loc.GetString("set-outfit-command-is-not-player-error"));
  56. return;
  57. }
  58. var eui = IoCManager.Resolve<EuiManager>();
  59. var ui = new SetOutfitEui(nent);
  60. eui.OpenEui(ui, player);
  61. return;
  62. }
  63. if (!SetOutfit(target.Value, args[1], _entities))
  64. shell.WriteLine(Loc.GetString("set-outfit-command-invalid-outfit-id-error"));
  65. }
  66. public static bool SetOutfit(EntityUid target, string gear, IEntityManager entityManager, Action<EntityUid, EntityUid>? onEquipped = null)
  67. {
  68. if (!entityManager.TryGetComponent(target, out InventoryComponent? inventoryComponent))
  69. return false;
  70. var prototypeManager = IoCManager.Resolve<IPrototypeManager>();
  71. if (!prototypeManager.TryIndex<StartingGearPrototype>(gear, out var startingGear))
  72. return false;
  73. HumanoidCharacterProfile? profile = null;
  74. ICommonSession? session = null;
  75. // Check if we are setting the outfit of a player to respect the preferences
  76. if (entityManager.TryGetComponent(target, out ActorComponent? actorComponent))
  77. {
  78. session = actorComponent.PlayerSession;
  79. var userId = actorComponent.PlayerSession.UserId;
  80. var preferencesManager = IoCManager.Resolve<IServerPreferencesManager>();
  81. var prefs = preferencesManager.GetPreferences(userId);
  82. profile = prefs.SelectedCharacter as HumanoidCharacterProfile;
  83. }
  84. var invSystem = entityManager.System<InventorySystem>();
  85. if (invSystem.TryGetSlots(target, out var slots))
  86. {
  87. foreach (var slot in slots)
  88. {
  89. invSystem.TryUnequip(target, slot.Name, true, true, false, inventoryComponent);
  90. var gearStr = ((IEquipmentLoadout) startingGear).GetGear(slot.Name);
  91. if (gearStr == string.Empty)
  92. {
  93. continue;
  94. }
  95. var equipmentEntity = entityManager.SpawnEntity(gearStr, entityManager.GetComponent<TransformComponent>(target).Coordinates);
  96. if (slot.Name == "id" &&
  97. entityManager.TryGetComponent(equipmentEntity, out PdaComponent? pdaComponent) &&
  98. entityManager.TryGetComponent<IdCardComponent>(pdaComponent.ContainedId, out var id))
  99. {
  100. id.FullName = entityManager.GetComponent<MetaDataComponent>(target).EntityName;
  101. }
  102. invSystem.TryEquip(target, equipmentEntity, slot.Name, silent: true, force: true, inventory: inventoryComponent);
  103. onEquipped?.Invoke(target, equipmentEntity);
  104. }
  105. }
  106. if (entityManager.TryGetComponent(target, out HandsComponent? handsComponent))
  107. {
  108. var handsSystem = entityManager.System<HandsSystem>();
  109. var coords = entityManager.GetComponent<TransformComponent>(target).Coordinates;
  110. foreach (var prototype in startingGear.Inhand)
  111. {
  112. var inhandEntity = entityManager.SpawnEntity(prototype, coords);
  113. handsSystem.TryPickup(target, inhandEntity, checkActionBlocker: false, handsComp: handsComponent);
  114. }
  115. }
  116. // See if this starting gear is associated with a job
  117. var jobs = prototypeManager.EnumeratePrototypes<JobPrototype>();
  118. foreach (var job in jobs)
  119. {
  120. if (job.StartingGear != gear)
  121. continue;
  122. var jobProtoId = LoadoutSystem.GetJobPrototype(job.ID);
  123. if (!prototypeManager.TryIndex<RoleLoadoutPrototype>(jobProtoId, out var jobProto))
  124. break;
  125. // Don't require a player, so this works on Urists
  126. profile ??= entityManager.TryGetComponent<HumanoidAppearanceComponent>(target, out var comp)
  127. ? HumanoidCharacterProfile.DefaultWithSpecies(comp.Species)
  128. : new HumanoidCharacterProfile();
  129. // Try to get the user's existing loadout for the role
  130. profile.Loadouts.TryGetValue(jobProtoId, out var roleLoadout);
  131. if (roleLoadout == null)
  132. {
  133. // If they don't have a loadout for the role, make a default one
  134. roleLoadout = new RoleLoadout(jobProtoId);
  135. roleLoadout.SetDefault(profile, session, prototypeManager);
  136. }
  137. // Equip the target with the job loadout
  138. var stationSpawning = entityManager.System<SharedStationSpawningSystem>();
  139. stationSpawning.EquipRoleLoadout(target, roleLoadout, jobProto);
  140. }
  141. return true;
  142. }
  143. }
  144. }