/// <summary> /// Applies a status effect to a group of characters. /// </summary> /// <param name="applicator">The character applying the status effect.</param> /// <param name="status">The status effect being applied.</param> /// <param name="characters">The characters the status effect is being applied to.</param> public void ApplyStatus(Character applicator, StatusEffect status, IEnumerable <Character> characters) { foreach (var character in characters) { ApplyStatus(applicator, status, character, false); } StatusEffectApplied?.Invoke(this, new StatusEffectAppliedEventArgs() { AffectedCharacterIds = new List <int>(characters.Select(chr => chr.Id)), LogMessage = CombatMessenger.GetAffectedByStatusMessage(status.Name, characters.Select(chr => chr.Name).ToList()) }); }
private void OnStatusEffectApplied(object sender, StatusEffectAppliedEventArgs args) { StatusEffectApplied?.Invoke(sender, args); }
/// <summary> /// Applys a delayed status effect to a group of characters. /// </summary> /// <param name="status">The delayed status to apply.</param> private void ApplyStatus(DelayedStatus status) { var livingTargets = new List <Character>( AllCharacters.Where( character => status.Targets.Contains(character.Position))); livingTargets.RemoveAll(target => target.CurrentHealth <= 0); foreach (var target in livingTargets) { if (!_appliedStatuses.ContainsKey(target)) { _appliedStatuses[target] = new List <AppliedStatus>(); } // If the the same type of status is already on a character if (_appliedStatuses[target].Any(applied => applied.BaseStatus == status.BaseStatus)) { var matchingStatus = _appliedStatuses[target].First(applied => applied.BaseStatus == status.BaseStatus); // If the status is stackable, refresh the duration and apply another layer of effects if (status.BaseStatus.Stackable && matchingStatus.StackCount < status.BaseStatus.StackSize) { matchingStatus.Applicator = status.Applicator; matchingStatus.TurnsRemaining = status.BaseStatus.Duration; matchingStatus.TotalDamage += status.TotalDamage; matchingStatus.HealAmount += status.HealAmount; matchingStatus.HealPercentage += status.HealPercentage; ApplyStatusEffects(status.BaseStatus, target); matchingStatus.StackCount++; } // If the status is stackable but has reached its stack limit, refresh the duration only else if (status.BaseStatus.Stackable) { matchingStatus.Applicator = status.Applicator; matchingStatus.TurnsRemaining = status.BaseStatus.Duration; } // If the status isn't stackable, refresh the duration and reset the damage else { matchingStatus.Applicator = status.Applicator; matchingStatus.TurnsRemaining = status.BaseStatus.Duration; matchingStatus.TotalDamage = status.TotalDamage; matchingStatus.HealAmount = status.HealAmount; matchingStatus.HealPercentage = status.HealPercentage; } } // Create and apply a new status effect on a character else { ApplyStatusEffects(status.BaseStatus, target); _appliedStatuses[target].Add(CreateAppliedStatus(status)); if (status.BaseStatus.IsDebuff) { target.Debuffs.Add(status.BaseStatus); } else { target.Buffs.Add(status.BaseStatus); } } } StatusEffectApplied?.Invoke(this, new StatusEffectAppliedEventArgs() { AffectedCharacterIds = new List <int>(livingTargets.Select(chr => chr.Id)), LogMessage = CombatMessenger.GetAffectedByStatusMessage(status.BaseStatus.Name, livingTargets.Select(target => target.Name).ToList()) }); }
/// <summary> /// Applies a status effect on a character. /// </summary> /// <param name="applicator">The character that is applying the status effect.</param> /// <param name="status">The status effect being applied.</param> /// <param name="character">The character the status effect is being applied on.</param> public void ApplyStatus(Character applicator, StatusEffect status, Character character, bool invokeAppliedStatusEvent = true) { if (!_appliedStatuses.ContainsKey(character)) { _appliedStatuses[character] = new List <AppliedStatus>(); } // If the the same type of status is already on a character if (_appliedStatuses[character].Any(applied => applied.BaseStatus == status)) { var matchingStatus = _appliedStatuses[character].First(applied => applied.BaseStatus == status); // If the status is stackable, refresh the duration and apply another layer of effects if (status.Stackable && matchingStatus.StackCount < status.StackSize) { matchingStatus.TurnsRemaining = status.Duration; matchingStatus.TotalDamage += DamageCalculator.GetDamage(applicator, status); matchingStatus.HealAmount += DamageCalculator.GetHealing(applicator, status); matchingStatus.HealPercentage += DamageCalculator.GetHealingPercentage(applicator, status); matchingStatus.CritChance = status.CritChance + character.CritChance; matchingStatus.CritMultiplier = status.CritMultiplier + character.CritMultiplier; ApplyStatusEffects(status, character); matchingStatus.StackCount++; } // If the status is stackable but has reached its stack limit, refresh the duration only else if (status.Stackable) { matchingStatus.TurnsRemaining = status.Duration; } // If the status isn't stackable, refresh the duration and reset the damage else { matchingStatus.TurnsRemaining = status.Duration; matchingStatus.TotalDamage = DamageCalculator.GetDamage(applicator, status); matchingStatus.HealAmount = DamageCalculator.GetHealing(applicator, status); matchingStatus.HealPercentage = DamageCalculator.GetHealingPercentage(applicator, status); matchingStatus.CritChance = status.CritChance + character.CritChance; matchingStatus.CritMultiplier = status.CritMultiplier + character.CritMultiplier; } } // Create and apply a new status effect on a character else { ApplyStatusEffects(status, character); _appliedStatuses[character].Add(CreateAppliedStatus(applicator, status)); if (status.IsDebuff) { character.Debuffs.Add(status); } else { character.Buffs.Add(status); } } if (invokeAppliedStatusEvent) { StatusEffectApplied?.Invoke(this, new StatusEffectAppliedEventArgs() { AffectedCharacterIds = new List <int>() { character.Id }, LogMessage = CombatMessenger.GetAffectedByStatusMessage(status.Name, character.Name) }); } }