SharedFlatpackSystem.cs 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. using Content.Shared.Construction.Components;
  2. using Content.Shared.Administration.Logs;
  3. using Content.Shared.Containers.ItemSlots;
  4. using Content.Shared.Database;
  5. using Content.Shared.Examine;
  6. using Content.Shared.Interaction;
  7. using Content.Shared.Materials;
  8. using Content.Shared.Popups;
  9. using Content.Shared.Tools.Systems;
  10. using Robust.Shared.Audio.Systems;
  11. using Robust.Shared.Containers;
  12. using Robust.Shared.Map.Components;
  13. using Robust.Shared.Network;
  14. using Robust.Shared.Prototypes;
  15. namespace Content.Shared.Construction;
  16. public abstract class SharedFlatpackSystem : EntitySystem
  17. {
  18. [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
  19. [Dependency] private readonly INetManager _net = default!;
  20. [Dependency] protected readonly IPrototypeManager PrototypeManager = default!;
  21. [Dependency] protected readonly SharedAppearanceSystem Appearance = default!;
  22. [Dependency] private readonly SharedAudioSystem _audio = default!;
  23. [Dependency] private readonly SharedContainerSystem _container = default!;
  24. [Dependency] private readonly EntityLookupSystem _entityLookup = default!;
  25. [Dependency] private readonly SharedMapSystem _map = default!;
  26. [Dependency] protected readonly MachinePartSystem MachinePart = default!;
  27. [Dependency] protected readonly SharedMaterialStorageSystem MaterialStorage = default!;
  28. [Dependency] private readonly MetaDataSystem _metaData = default!;
  29. [Dependency] private readonly SharedPopupSystem _popup = default!;
  30. [Dependency] private readonly SharedToolSystem _tool = default!;
  31. /// <inheritdoc/>
  32. public override void Initialize()
  33. {
  34. SubscribeLocalEvent<FlatpackComponent, InteractUsingEvent>(OnFlatpackInteractUsing);
  35. SubscribeLocalEvent<FlatpackComponent, ExaminedEvent>(OnFlatpackExamined);
  36. SubscribeLocalEvent<FlatpackCreatorComponent, ItemSlotInsertAttemptEvent>(OnInsertAttempt);
  37. }
  38. private void OnInsertAttempt(Entity<FlatpackCreatorComponent> ent, ref ItemSlotInsertAttemptEvent args)
  39. {
  40. if (args.Slot.ID != ent.Comp.SlotId || args.Cancelled)
  41. return;
  42. if (HasComp<MachineBoardComponent>(args.Item))
  43. return;
  44. if (TryComp<ComputerBoardComponent>(args.Item, out var computer) && computer.Prototype != null)
  45. return;
  46. args.Cancelled = true;
  47. }
  48. private void OnFlatpackInteractUsing(Entity<FlatpackComponent> ent, ref InteractUsingEvent args)
  49. {
  50. var (uid, comp) = ent;
  51. if (!_tool.HasQuality(args.Used, comp.QualityNeeded) || _container.IsEntityInContainer(ent))
  52. return;
  53. var xform = Transform(ent);
  54. if (xform.GridUid is not { } grid || !TryComp<MapGridComponent>(grid, out var gridComp))
  55. return;
  56. args.Handled = true;
  57. if (comp.Entity == null)
  58. {
  59. Log.Error($"No entity prototype present for flatpack {ToPrettyString(ent)}.");
  60. if (_net.IsServer)
  61. QueueDel(ent);
  62. return;
  63. }
  64. var buildPos = _map.TileIndicesFor(grid, gridComp, xform.Coordinates);
  65. var coords = _map.ToCenterCoordinates(grid, buildPos);
  66. // TODO FLATPAK
  67. // Make this logic smarter. This should eventually allow for shit like building microwaves on tables and such.
  68. // Also: make it ignore ghosts
  69. if (_entityLookup.AnyEntitiesIntersecting(coords, LookupFlags.Dynamic | LookupFlags.Static))
  70. {
  71. // this popup is on the server because the predicts on the intersection is crazy
  72. if (_net.IsServer)
  73. _popup.PopupEntity(Loc.GetString("flatpack-unpack-no-room"), uid, args.User);
  74. return;
  75. }
  76. if (_net.IsServer)
  77. {
  78. var spawn = Spawn(comp.Entity, _map.GridTileToLocal(grid, gridComp, buildPos));
  79. _adminLogger.Add(LogType.Construction,
  80. LogImpact.Low,
  81. $"{ToPrettyString(args.User):player} unpacked {ToPrettyString(spawn):entity} at {xform.Coordinates} from {ToPrettyString(uid):entity}");
  82. QueueDel(uid);
  83. }
  84. _audio.PlayPredicted(comp.UnpackSound, args.Used, args.User);
  85. }
  86. private void OnFlatpackExamined(Entity<FlatpackComponent> ent, ref ExaminedEvent args)
  87. {
  88. if (!args.IsInDetailsRange)
  89. return;
  90. args.PushMarkup(Loc.GetString("flatpack-examine"));
  91. }
  92. protected void SetupFlatpack(Entity<FlatpackComponent?> ent, EntProtoId proto, EntityUid board)
  93. {
  94. if (!Resolve(ent, ref ent.Comp))
  95. return;
  96. ent.Comp.Entity = proto;
  97. var machinePrototype = PrototypeManager.Index<EntityPrototype>(proto);
  98. var meta = MetaData(ent);
  99. _metaData.SetEntityName(ent, Loc.GetString("flatpack-entity-name", ("name", machinePrototype.Name)), meta);
  100. _metaData.SetEntityDescription(ent, Loc.GetString("flatpack-entity-description", ("name", machinePrototype.Name)), meta);
  101. Dirty(ent, meta);
  102. Appearance.SetData(ent, FlatpackVisuals.Machine, MetaData(board).EntityPrototype?.ID ?? string.Empty);
  103. }
  104. /// <param name="machineBoard">The machine board to pack. If null, this implies we are packing a computer board</param>
  105. public Dictionary<string, int> GetFlatpackCreationCost(Entity<FlatpackCreatorComponent> entity, Entity<MachineBoardComponent>? machineBoard)
  106. {
  107. Dictionary<string, int> cost = new();
  108. Dictionary<ProtoId<MaterialPrototype>, int> baseCost;
  109. if (machineBoard is not null)
  110. {
  111. cost = MachinePart.GetMachineBoardMaterialCost(machineBoard.Value, -1);
  112. baseCost = entity.Comp.BaseMachineCost;
  113. }
  114. else
  115. baseCost = entity.Comp.BaseComputerCost;
  116. foreach (var (mat, amount) in baseCost)
  117. {
  118. cost.TryAdd(mat, 0);
  119. cost[mat] -= amount;
  120. }
  121. return cost;
  122. }
  123. }