/// <summary>
        /// Returns a string describing this protect result.
        /// </summary>
        /// <param name="protect">The protect result.</param>
        public static string Describe <TSource>(this ProtectActionResult <TSource> protect)
        {
            var target = protect.Target;

            if (target.IsDead)
            {
                return(null);
            }

            if (protect.IsSelfInflicted)
            {
                return(protect.Source switch
                {
                    Item item => $"{target.Name}'s {item.Name} protected them!",
                    _ => $"{target.Name} became protected!",
                });
        /// <summary>
        /// Adds an item to the protect queue, which protects the character from the next action.
        /// </summary>
        /// <param name="user">The character who protected this character.</param>
        /// <typeparam name="TSource">The type of the source of the incoming protect action.</typeparam>
        public virtual ProtectActionResult <TSource> AddProtect <TSource>(Character user)
        {
            ProtectActionResult <TSource> result;

            if (CanProtectFrom(user))
            {
                var protectUser = ConsumeProtect();

                result = new ProtectActionResult <TSource>
                {
                    Applied         = false,
                    User            = user,
                    Target          = this,
                    TargetProtected = true,
                    ProtectUser     = protectUser,
                    Tags            = new HashSet <string>(),
                };
            }
            else if (ProtectCount >= ProtectLimit)
            {
                result = new ProtectActionResult <TSource>
                {
                    Applied = false,
                    User    = user,
                    Target  = this,
                    Tags    = new HashSet <string>(),
                };
            }
            else
            {
                ProtectQueue.Add(user);

                result = new ProtectActionResult <TSource>
                {
                    Applied         = true,
                    User            = user,
                    Target          = this,
                    TargetProtected = false,
                    Tags            = new HashSet <string>(),
                };
            }

            return(result);
        }