/// <summary> /// Apply the action's spell to the given target. /// </summary> /// <returns>True if there was any effect on the target.</returns> private bool ApplySpell(Combatant spellTarget) { StatisticsValue effectStatistics = CalculateSpellDamage(combatant, spell); if (spell.IsOffensive) { // calculate the defense Int32Range defenseRange = spellTarget.Character.MagicDefenseRange + spellTarget.Statistics.MagicalDefense; Int32 defense = defenseRange.GenerateValue(Session.Random); // subtract the defense effectStatistics -= new StatisticsValue(defense, defense, defense, defense, defense, defense); // make sure that this only contains damage effectStatistics.ApplyMinimum(new StatisticsValue()); // damage the target spellTarget.Damage(effectStatistics, spell.TargetDuration); } else { // make sure that this only contains healing effectStatistics.ApplyMinimum(new StatisticsValue()); // heal the target spellTarget.Heal(effectStatistics, spell.TargetDuration); } return(!effectStatistics.IsZero); }
/// <summary> /// Starts a new combat stage. Called right after the stage changes. /// </summary> /// <remarks>The stage never changes into NotStarted.</remarks> protected override void StartStage() { switch (stage) { case CombatActionStage.Preparing: // called from Start() { // play the animation combatant.CombatSprite.PlayAnimation("Idle"); } break; case CombatActionStage.Advancing: { // play the animation combatant.CombatSprite.PlayAnimation("Walk"); // calculate the advancing destination if (Target.Position.X > Combatant.Position.X) { advanceDirection = Target.Position - Combatant.OriginalPosition - advanceOffset; } else { advanceDirection = Target.Position - Combatant.OriginalPosition + advanceOffset; } totalAdvanceDistance = advanceDirection.Length(); advanceDirection.Normalize(); advanceDistanceCovered = 0f; } break; case CombatActionStage.Executing: { // play the animation combatant.CombatSprite.PlayAnimation("Attack"); // play the audio Weapon weapon = combatant.Character.GetEquippedWeapon(); if (weapon != null) { AudioManager.PlayCue(weapon.SwingCueName); } else { AudioManager.PlayCue("StaffSwing"); } } break; case CombatActionStage.Returning: { // play the animation combatant.CombatSprite.PlayAnimation("Walk"); // calculate the damage Int32Range damageRange = combatant.Character.TargetDamageRange + combatant.Statistics.PhysicalOffense; Int32Range defenseRange = Target.Character.HealthDefenseRange + Target.Statistics.PhysicalDefense; int damage = Math.Max(0, damageRange.GenerateValue(Session.Random) - defenseRange.GenerateValue(Session.Random)); // apply the damage if (damage > 0) { // play the audio Weapon weapon = combatant.Character.GetEquippedWeapon(); if (weapon != null) { AudioManager.PlayCue(weapon.HitCueName); } else { AudioManager.PlayCue("StaffHit"); } // damage the target Target.DamageHealth(damage, 0); if ((weapon != null) && (weapon.Overlay != null)) { weapon.Overlay.PlayAnimation(0); weapon.Overlay.ResetAnimation(); } } } break; case CombatActionStage.Finishing: { // play the animation combatant.CombatSprite.PlayAnimation("Idle"); } break; case CombatActionStage.Complete: { // play the animation combatant.CombatSprite.PlayAnimation("Idle"); } break; } }