private void OnDoafterSuccess(EntityUid uid, GatherableComponent component, GatheringDoafterSuccess ev)
    {
        if (!TryComp(ev.Tool, out GatheringToolComponent? tool))
        {
            return;
        }

        // Complete the gathering process
        _damageableSystem.TryChangeDamage(ev.Resource, tool.Damage);
        SoundSystem.Play(tool.GatheringSound.GetSound(), Filter.Pvs(ev.Resource, entityManager: EntityManager), ev.Resource);
        tool.GatheringEntities.Remove(ev.Resource);

        // Spawn the loot!
        if (component.MappedLoot == null)
        {
            return;
        }

        var playerPos = Transform(ev.Player).MapPosition;

        foreach (var(tag, table) in component.MappedLoot)
        {
            if (tag != "All")
            {
                if (!_tagSystem.HasTag(tool.Owner, tag))
                {
                    continue;
                }
            }
            var getLoot   = _prototypeManager.Index <EntityLootTablePrototype>(table);
            var spawnLoot = getLoot.GetSpawns();
            var spawnPos  = playerPos.Offset(_random.NextVector2(0.3f));
            Spawn(spawnLoot[0], spawnPos);
        }
    }
    private void OnInteractUsing(EntityUid uid, GatherableComponent component, InteractUsingEvent args)
    {
        if (!TryComp <GatheringToolComponent>(args.Used, out var tool) ||
            component.ToolWhitelist?.IsValid(args.Used) == false ||
            tool.GatheringEntities.TryGetValue(uid, out var cancelToken))
        {
            return;
        }

        // Can't gather too many entities at once.
        if (tool.MaxGatheringEntities < tool.GatheringEntities.Count + 1)
        {
            return;
        }

        cancelToken = new CancellationTokenSource();
        tool.GatheringEntities[uid] = cancelToken;

        var doAfter = new DoAfterEventArgs(args.User, tool.GatheringTime, cancelToken.Token, uid)
        {
            BreakOnDamage           = true,
            BreakOnStun             = true,
            BreakOnTargetMove       = true,
            BreakOnUserMove         = true,
            MovementThreshold       = 0.25f,
            BroadcastCancelledEvent = new GatheringDoafterCancel {
                Tool = args.Used, Resource = uid
            },
            TargetFinishedEvent = new GatheringDoafterSuccess {
                Tool = args.Used, Resource = uid, Player = args.User
            }
        };

        _doAfterSystem.DoAfter(doAfter);
    }