private void OnHealingUse(EntityUid uid, HealingComponent component, UseInHandEvent args)
    {
        if (args.Handled)
        {
            return;
        }

        args.Handled = true;
        Heal(uid, args.User, args.User, component);
    }
    private void OnHealingAfterInteract(EntityUid uid, HealingComponent component, AfterInteractEvent args)
    {
        if (args.Handled || !args.CanReach || args.Target == null)
        {
            return;
        }

        args.Handled = true;
        Heal(uid, args.User, args.Target.Value, component);
    }
    private void Heal(EntityUid uid, EntityUid user, EntityUid target, HealingComponent component)
    {
        if (component.CancelToken != null)
        {
            component.CancelToken?.Cancel();
            component.CancelToken = null;
            return;
        }

        if (!TryComp <DamageableComponent>(target, out var targetDamage))
        {
            return;
        }

        if (component.DamageContainerID is not null && !component.DamageContainerID.Equals(targetDamage.DamageContainerID))
        {
            return;
        }

        if (user != target &&
            !_interactionSystem.InRangeUnobstructed(user, target, popup: true))
        {
            return;
        }

        if (TryComp <SharedStackComponent>(component.Owner, out var stack) && stack.Count < 1)
        {
            return;
        }

        component.CancelToken = new CancellationTokenSource();

        if (component.HealingBeginSound != null)
        {
            SoundSystem.Play(Filter.Pvs(uid, entityManager: EntityManager), component.HealingBeginSound.GetSound(), uid, AudioHelpers.WithVariation(0.125f).WithVolume(-5f));
        }

        _doAfter.DoAfter(new DoAfterEventArgs(user, component.Delay, component.CancelToken.Token, target)
        {
            BreakOnUserMove   = true,
            BreakOnTargetMove = true,
            // Didn't break on damage as they may be trying to prevent it and
            // not being able to heal your own ticking damage would be frustrating.
            BreakOnStun         = true,
            NeedHand            = true,
            TargetFinishedEvent = new HealingCompleteEvent
            {
                User      = user,
                Component = component,
            },
            BroadcastCancelledEvent = new HealingCancelledEvent
            {
                Component = component,
            },
            // Juusstt in case damageble gets removed it avoids having to re-cancel the token. Won't need this when DoAfterEvent<T> gets added.
            PostCheck = () =>
            {
                component.CancelToken = null;
                return(true);
            },
        });
    }