private void OnStatusEffectsRemoved(object sender, CombatLoggableEventArgs args)
 {
     StatusEffectsRemoved?.Invoke(sender, args);
 }
        /// <summary>
        /// Applies damage and healing from status effects affecting a character at the start of its turn.
        /// If there are no turns remaining on the status, the status is removed. If the character dies from
        /// status effect damage, the character died event is invoked.
        /// </summary>
        /// <param name="character">The character starting its turn.</param>
        private void StartOfTurnEffects(Character character)
        {
            var removeStatuses = new List <AppliedStatus>();
            int startingHealth = character.CurrentHealth;
            int totalDamage    = 0;

            // Calculate damage and apply healing from each status effect
            foreach (var status in _appliedStatuses[character])
            {
                int damage = DamageCalculator.GetTotalDamage(status.TotalDamage, character);
                totalDamage += damage;
                int healAmount  = status.HealAmount;
                int percentHeal = character.CurrentMaxHealth * status.HealPercentage / 100;
                if (_random.Next(1, 101) <= status.CritChance)
                {
                    totalDamage = totalDamage * status.CritMultiplier / 100;
                    healAmount  = healAmount * status.CritMultiplier / 100;
                }

                character.CurrentHealth += percentHeal;
                character.CurrentHealth += healAmount;

                _threatController.ApplyThreat(status.Applicator,
                                              character,
                                              damage + healAmount + percentHeal,
                                              status.BaseStatus.Threat,
                                              status.BaseStatus.ThreatMultiplier);

                if (character.CurrentHealth > character.CurrentMaxHealth)
                {
                    character.CurrentHealth = character.CurrentMaxHealth;
                }
                status.TurnsRemaining--;
                if (status.TurnsRemaining == 0)
                {
                    removeStatuses.Add(status);
                }
            }
            character.CurrentHealth += totalDamage;

            int modifiedHealth = character.CurrentHealth - startingHealth;
            var names          = _appliedStatuses[character].Select(status => status.BaseStatus.Name).ToList();

            if (modifiedHealth != 0)
            {
                CharactersHealthChanged?.Invoke(this, new CharactersHealthChangedEventArgs()
                {
                    PostCharactersChanged = new Dictionary <int, int>()
                    {
                        { character.Id, character.CurrentHealth }
                    },
                    PreCharactersChanged = new Dictionary <int, int>()
                    {
                        { character.Id, startingHealth }
                    },
                    ChangeAmount = new Dictionary <int, int>()
                    {
                        { character.Id, modifiedHealth }
                    },
                    LogMessage = CombatMessenger.GetHealthChangedByStatusMessage(names, character.Name, modifiedHealth)
                });
            }

            var statusNames = removeStatuses.Select(st => st.BaseStatus.Name).ToList();

            // If a status is queued for removal, remove from the character's buff and debuff lists
            foreach (var status in removeStatuses)
            {
                if (status.BaseStatus.IsDebuff)
                {
                    character.Debuffs.Remove(status.BaseStatus);
                }
                else
                {
                    character.Buffs.Remove(status.BaseStatus);
                }
                RemoveStatusEffects(status, character);
            }
            _appliedStatuses[character].RemoveAll(status => removeStatuses.Contains(status));

            if (removeStatuses.Any())
            {
                StatusEffectsRemoved?.Invoke(this, new CombatLoggableEventArgs()
                {
                    LogMessage = CombatMessenger.GetRemoveStatusMessage(statusNames, character.Name)
                });
            }

            // Invoke characters dying event if a character died as a result of this status effect.
            if (character.CurrentHealth <= 0)
            {
                character.CurrentHealth = 0;
                RemoveAllStatuses(character);
                var characters = new List <Character>()
                {
                    character
                };
                CharactersDied?.Invoke(this, new CharactersDiedEventArgs()
                {
                    DyingCharacters = characters,
                    LogMessage      = CombatMessenger.GetCharactersDiedMessage(characters.Select(chr => chr.Name).ToList())
                });
            }
        }