DiggingSystem.cs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. using Content.Shared.Interaction;
  2. using Content.Shared.DoAfter;
  3. using Content.Server.DoAfter;
  4. using Content.Shared.Maps;
  5. using Content.Shared.Popups;
  6. using Robust.Shared.Map;
  7. using Robust.Shared.Map.Components;
  8. using Content.Shared.Farming;
  9. using System.Linq;
  10. namespace Content.Server.Farming;
  11. public sealed partial class DiggingSystem : EntitySystem
  12. {
  13. [Dependency] private readonly SharedTransformSystem _transform = default!;
  14. [Dependency] private readonly SharedMapSystem _map = default!;
  15. [Dependency] private readonly ITileDefinitionManager _tileManager = default!;
  16. [Dependency] private readonly DoAfterSystem _doAfter = default!;
  17. [Dependency] private readonly SharedPopupSystem _popup = default!;
  18. // Maps digging state
  19. private readonly Dictionary<string, string> _digProgression = new()
  20. {
  21. { "FloorDirt", "FloorDirtDigged_1" },
  22. { "FloorDirtDigged_1", "FloorDirtDigged_2" },
  23. { "FloorDirtDigged_2", "FloorDirtDigged_3" },
  24. { "FloorSand", "FloorSand" }
  25. };
  26. public override void Initialize()
  27. {
  28. base.Initialize();
  29. SubscribeLocalEvent<DiggingComponent, AfterInteractEvent>(OnAfterInteract);
  30. SubscribeLocalEvent<DiggingComponent, DigDoAfterEvent>(OnDoAfter);
  31. }
  32. private void OnAfterInteract(Entity<DiggingComponent> ent, ref AfterInteractEvent args)
  33. {
  34. if (args.Handled || args.Target != null || !args.CanReach)
  35. return;
  36. var comp = ent.Comp;
  37. var user = args.User;
  38. var clickLocation = args.ClickLocation;
  39. var gridUid = _transform.GetGrid(clickLocation);
  40. if (!gridUid.HasValue || !TryComp<MapGridComponent>(gridUid.Value, out var grid))
  41. return;
  42. var snapPos = grid.TileIndicesFor(clickLocation);
  43. var tileRef = _map.GetTileRef(gridUid.Value, grid, snapPos);
  44. var tileDef = (ContentTileDefinition)_tileManager[tileRef.Tile.TypeId];
  45. // Checks if tile can be dug
  46. if (!_digProgression.TryGetValue(tileDef.ID, out var nextTileId))
  47. {
  48. return; // Tile already fully dug
  49. }
  50. var delay = TimeSpan.FromSeconds(comp.DigTime);
  51. var netGridUid = GetNetEntity(gridUid.Value);
  52. var doAfterArgs = new DoAfterArgs(EntityManager, user, delay, new DigDoAfterEvent(netGridUid, snapPos, nextTileId), ent)
  53. {
  54. BreakOnMove = true,
  55. BreakOnDamage = true,
  56. NeedHand = true
  57. };
  58. if (_doAfter.TryStartDoAfter(doAfterArgs))
  59. {
  60. _popup.PopupEntity("You start digging the soil.", ent, user);
  61. args.Handled = true;
  62. }
  63. }
  64. private void OnDoAfter(Entity<DiggingComponent> ent, ref DigDoAfterEvent args)
  65. {
  66. if (args.Cancelled || args.Handled)
  67. return;
  68. var gridUid = GetEntity(args.GridUid);
  69. if (!TryComp<MapGridComponent>(gridUid, out var grid))
  70. return;
  71. var snapPos = args.SnapPos;
  72. var nextTileId = args.NextTileId;
  73. var tileRef = _map.GetTileRef(gridUid, grid, snapPos);
  74. var tileDef = (ContentTileDefinition)_tileManager[tileRef.Tile.TypeId];
  75. var expectedTileId = _digProgression.FirstOrDefault(x => x.Value == nextTileId).Key;
  76. if (tileDef.ID != expectedTileId)
  77. {
  78. return;
  79. }
  80. // Updates tile to the next digging state
  81. var nextTile = _tileManager[nextTileId];
  82. _map.SetTile(gridUid, grid, snapPos, new Tile(nextTile.TileId));
  83. var coordinates = grid.GridTileToLocal(snapPos);
  84. var result = "MaterialDirt1";
  85. if (tileDef.ID == "FloorSand")
  86. {
  87. result = "MaterialSand1";
  88. }
  89. Spawn(result, coordinates);
  90. _popup.PopupEntity("You finish digging the soil.", ent, args.User);
  91. args.Handled = true;
  92. }
  93. }