/// <summary> /// Given an instance of a DelayedStatus, creates and returns an instance of an AppliedStatus. /// </summary> /// <param name="status">The DelayedStatus the AppliedStatus should use as a base.</param> /// <returns>A wrapper around a status effect, containing modified values and a turn counter.</returns> private AppliedStatus CreateAppliedStatus(DelayedStatus status) { return(new AppliedStatus() { Applicator = status.Applicator, BaseStatus = status.BaseStatus, TotalDamage = status.TotalDamage, HealAmount = status.HealAmount, HealPercentage = status.HealPercentage, TurnsRemaining = status.BaseStatus.Duration, CritChance = status.CritChance, CritMultiplier = status.CritMultiplier, StackCount = 1 }); }
/// <summary> /// Creates a delayed status instance, which will apply a status effect after a set amount of turns has passed. /// </summary> /// <param name="applicator">The character from which the spell originated.</param> /// <param name="statusBase">The status effect to use as the base for the delayed status.</param> /// <param name="target">A list of characters to apply to status effects to.</param> /// <param name="spellDelay">How many rounds until the buffs activate.</param> public void CreateDelayedStatus(Character applicator, StatusEffect statusBase, IReadOnlyList <int> targets, int spellDelay) { var delayedStatus = new DelayedStatus() { Applicator = applicator, BaseStatus = statusBase, TotalDamage = DamageCalculator.GetDamage(applicator, statusBase), HealAmount = DamageCalculator.GetHealing(applicator, statusBase), HealPercentage = DamageCalculator.GetHealingPercentage(applicator, statusBase), SpellDelay = spellDelay, CritChance = applicator.CritChance + statusBase.CritChance, CritMultiplier = applicator.CritMultiplier + statusBase.CritMultiplier, Targets = targets }; if (!_delayedStatuses.ContainsKey(applicator)) { _delayedStatuses[applicator] = new List <DelayedStatus>(); } _delayedStatuses[applicator].Add(delayedStatus); }
/// <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()) }); }