GatherableSystem.cs 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. using Content.Server.Destructible;
  2. using Content.Server.Gatherable.Components;
  3. using Content.Shared.Interaction;
  4. using Content.Shared.Tag;
  5. using Content.Shared.Weapons.Melee.Events;
  6. using Content.Shared.Whitelist;
  7. using Robust.Server.GameObjects;
  8. using Robust.Shared.Audio.Systems;
  9. using Robust.Shared.Prototypes;
  10. using Robust.Shared.Random;
  11. namespace Content.Server.Gatherable;
  12. public sealed partial class GatherableSystem : EntitySystem
  13. {
  14. [Dependency] private readonly IPrototypeManager _proto = default!;
  15. [Dependency] private readonly IRobustRandom _random = default!;
  16. [Dependency] private readonly DestructibleSystem _destructible = default!;
  17. [Dependency] private readonly SharedAudioSystem _audio = default!;
  18. [Dependency] private readonly TagSystem _tagSystem = default!;
  19. [Dependency] private readonly TransformSystem _transform = default!;
  20. [Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!;
  21. public override void Initialize()
  22. {
  23. base.Initialize();
  24. SubscribeLocalEvent<GatherableComponent, ActivateInWorldEvent>(OnActivate);
  25. SubscribeLocalEvent<GatherableComponent, AttackedEvent>(OnAttacked);
  26. InitializeProjectile();
  27. }
  28. private void OnAttacked(Entity<GatherableComponent> gatherable, ref AttackedEvent args)
  29. {
  30. if (_whitelistSystem.IsWhitelistFailOrNull(gatherable.Comp.ToolWhitelist, args.Used))
  31. return;
  32. Gather(gatherable, args.User);
  33. }
  34. private void OnActivate(Entity<GatherableComponent> gatherable, ref ActivateInWorldEvent args)
  35. {
  36. if (args.Handled || !args.Complex)
  37. return;
  38. if (_whitelistSystem.IsWhitelistFailOrNull(gatherable.Comp.ToolWhitelist, args.User))
  39. return;
  40. Gather(gatherable, args.User);
  41. args.Handled = true;
  42. }
  43. public void Gather(EntityUid gatheredUid, EntityUid? gatherer = null, GatherableComponent? component = null)
  44. {
  45. if (!Resolve(gatheredUid, ref component))
  46. return;
  47. if (TryComp<SoundOnGatherComponent>(gatheredUid, out var soundComp))
  48. {
  49. _audio.PlayPvs(soundComp.Sound, Transform(gatheredUid).Coordinates);
  50. }
  51. // Complete the gathering process
  52. _destructible.DestroyEntity(gatheredUid);
  53. // Spawn the loot!
  54. if (component.Loot == null)
  55. return;
  56. var pos = _transform.GetMapCoordinates(gatheredUid);
  57. foreach (var (tag, table) in component.Loot)
  58. {
  59. if (tag != "All")
  60. {
  61. if (gatherer != null && !_tagSystem.HasTag(gatherer.Value, tag))
  62. continue;
  63. }
  64. var getLoot = _proto.Index(table);
  65. var spawnLoot = getLoot.GetSpawns(_random);
  66. foreach (var loot in spawnLoot)
  67. {
  68. var spawnPos = pos.Offset(_random.NextVector2(component.GatherOffset));
  69. Spawn(loot, spawnPos);
  70. }
  71. }
  72. }
  73. }