BlueprintSystem.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. using Content.Shared.IdentityManagement;
  2. using Content.Shared.Interaction;
  3. using Content.Shared.Lathe;
  4. using Content.Shared.Popups;
  5. using Content.Shared.Research.Components;
  6. using Content.Shared.Research.Prototypes;
  7. using Content.Shared.Whitelist;
  8. using Robust.Shared.Containers;
  9. using Robust.Shared.Prototypes;
  10. namespace Content.Shared.Research.Systems;
  11. public sealed class BlueprintSystem : EntitySystem
  12. {
  13. [Dependency] private readonly SharedContainerSystem _container = default!;
  14. [Dependency] private readonly EntityWhitelistSystem _entityWhitelist = default!;
  15. [Dependency] private readonly SharedPopupSystem _popup = default!;
  16. /// <inheritdoc/>
  17. public override void Initialize()
  18. {
  19. SubscribeLocalEvent<BlueprintReceiverComponent, ComponentStartup>(OnStartup);
  20. SubscribeLocalEvent<BlueprintReceiverComponent, AfterInteractUsingEvent>(OnAfterInteract);
  21. SubscribeLocalEvent<BlueprintReceiverComponent, LatheGetRecipesEvent>(OnGetRecipes);
  22. }
  23. private void OnStartup(Entity<BlueprintReceiverComponent> ent, ref ComponentStartup args)
  24. {
  25. _container.EnsureContainer<Container>(ent, ent.Comp.ContainerId);
  26. }
  27. private void OnAfterInteract(Entity<BlueprintReceiverComponent> ent, ref AfterInteractUsingEvent args)
  28. {
  29. if (args.Handled || !args.CanReach || !TryComp<BlueprintComponent>(args.Used, out var blueprintComponent))
  30. return;
  31. args.Handled = TryInsertBlueprint(ent, (args.Used, blueprintComponent), args.User);
  32. }
  33. private void OnGetRecipes(Entity<BlueprintReceiverComponent> ent, ref LatheGetRecipesEvent args)
  34. {
  35. var recipes = GetBlueprintRecipes(ent);
  36. foreach (var recipe in recipes)
  37. {
  38. args.Recipes.Add(recipe);
  39. }
  40. }
  41. public bool TryInsertBlueprint(Entity<BlueprintReceiverComponent> ent, Entity<BlueprintComponent> blueprint, EntityUid? user)
  42. {
  43. if (!CanInsertBlueprint(ent, blueprint, user))
  44. return false;
  45. if (user is not null)
  46. {
  47. var userId = Identity.Entity(user.Value, EntityManager);
  48. var bpId = Identity.Entity(blueprint, EntityManager);
  49. var machineId = Identity.Entity(ent, EntityManager);
  50. var msg = Loc.GetString("blueprint-receiver-popup-insert",
  51. ("user", userId),
  52. ("blueprint", bpId),
  53. ("receiver", machineId));
  54. _popup.PopupPredicted(msg, ent, user);
  55. }
  56. _container.Insert(blueprint.Owner, _container.GetContainer(ent, ent.Comp.ContainerId));
  57. var ev = new TechnologyDatabaseModifiedEvent();
  58. RaiseLocalEvent(ent, ref ev);
  59. return true;
  60. }
  61. public bool CanInsertBlueprint(Entity<BlueprintReceiverComponent> ent, Entity<BlueprintComponent> blueprint, EntityUid? user)
  62. {
  63. if (_entityWhitelist.IsWhitelistFail(ent.Comp.Whitelist, blueprint))
  64. {
  65. return false;
  66. }
  67. if (blueprint.Comp.ProvidedRecipes.Count == 0)
  68. {
  69. Log.Error($"Attempted to insert blueprint {ToPrettyString(blueprint)} with no recipes.");
  70. return false;
  71. }
  72. // Don't add new blueprints if there are no new recipes.
  73. var currentRecipes = GetBlueprintRecipes(ent);
  74. if (currentRecipes.Count != 0 && currentRecipes.IsSupersetOf(blueprint.Comp.ProvidedRecipes))
  75. {
  76. _popup.PopupPredicted(Loc.GetString("blueprint-receiver-popup-recipe-exists"), ent, user);
  77. return false;
  78. }
  79. return _container.CanInsert(blueprint, _container.GetContainer(ent, ent.Comp.ContainerId));
  80. }
  81. public HashSet<ProtoId<LatheRecipePrototype>> GetBlueprintRecipes(Entity<BlueprintReceiverComponent> ent)
  82. {
  83. var contained = _container.GetContainer(ent, ent.Comp.ContainerId);
  84. var recipes = new HashSet<ProtoId<LatheRecipePrototype>>();
  85. foreach (var blueprint in contained.ContainedEntities)
  86. {
  87. if (!TryComp<BlueprintComponent>(blueprint, out var blueprintComponent))
  88. continue;
  89. foreach (var provided in blueprintComponent.ProvidedRecipes)
  90. {
  91. recipes.Add(provided);
  92. }
  93. }
  94. return recipes;
  95. }
  96. }