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()) }); } }