public override void ApplyOnAttack(AttackData attackData, CombatDamageModifier damageModifier) { if (!attackData.Attacker.IsRanged || (SkillLevel == SecondarySkillLevel.None)) { return; } double bonus; if (SkillLevel == SecondarySkillLevel.Basic) { bonus = 0.1; } else if (SkillLevel == SecondarySkillLevel.Advanced) { bonus = 0.25; } else { bonus = 0.5; } if (IsSpecialized) { bonus *= (1.0 + 0.05 * HeroStats.Level); } damageModifier.DamageBonuses.Add(bonus); }
public override void ApplyOnDefense(AttackData attackData, CombatDamageModifier damageModifier) { if (SkillLevel == SecondarySkillLevel.None) { return; } double reduction; if (SkillLevel == SecondarySkillLevel.Basic) { reduction = 0.05; } else if (SkillLevel == SecondarySkillLevel.Advanced) { reduction = 0.1; } else { reduction = 0.15; } if (IsSpecialized) { reduction *= (1.0 + 0.05 * HeroStats.Level); } damageModifier.DamageReductions.Add(reduction); }
public void ApplyOnDefense(AttackData attackData, CombatDamageModifier damageModifier) { foreach (SecondarySkill skill in SecondarySkills) { skill.ApplyOnDefense(attackData, damageModifier); } }
public override void ApplyOnAttack(AttackData attackData, CombatDamageModifier damageModifier) { if (CasterStats.IsSpecialized) { double bonus = 0.03 * (CasterStats.SpecializationLevel / attackData.Attacker.Level); damageModifier.DamageBonuses.Add(bonus); } }
public void ApplyOnAttack(AttackData attackData, CombatDamageModifier damageModifier) { int attackerId = attackData.Attacker.Id; int defenderId = attackData.Defender.Id; int minUnitId = Math.Min(attackerId, defenderId); int maxUnitId = Math.Max(attackerId, defenderId); // Opposite elementals bool isOppositeElementalPair = false; isOppositeElementalPair |= (minUnitId == 114 || minUnitId == 115) && (maxUnitId == 120 || maxUnitId == 121); // air / earth isOppositeElementalPair |= (minUnitId == 116 || minUnitId == 117) && (maxUnitId == 118 || maxUnitId == 119); // water / fire if (isOppositeElementalPair) { damageModifier.DamageBonuses.Add(1.0); } // Hate pairs bool isHatePair = false; isHatePair |= (minUnitId == 12 || minUnitId == 13) && (maxUnitId == 82 || maxUnitId == 83); // angels / devils isHatePair |= (minUnitId == 36 || minUnitId == 37) && (maxUnitId == 80 || maxUnitId == 81); // genies / efreets isHatePair |= (minUnitId == 41) && (maxUnitId == 69); // titans / black dragons if (isHatePair) { damageModifier.DamageBonuses.Add(0.5); } // Attacker is Psychic Elemental, defender is immune to Mind spells if ((attackerId == 122) && ( attackData.Defender.IsUndead || (defenderId == 32 || defenderId == 33 || defenderId == 134 || defenderId == 135) || // Golems (defenderId == 40 || defenderId == 41) || // Giant / Titan (defenderId == 69) || // Black Dragon (defenderId >= 114 && defenderId <= 123) // Elementals )) { damageModifier.DamageReductions.Add(0.5); } // Magic Elemental vs Magic Elemental or Black Dragon if ((attackerId == 123) && (defenderId == 123 || defenderId == 69)) { damageModifier.DamageReductions.Add(0.5); } }
public override void ApplyOnDefense(AttackData attackData, CombatDamageModifier damageModifier) { if (!attackData.Attacker.IsRanged) { return; } if (CasterStats.SkillLevel <= SecondarySkillLevel.Basic) { damageModifier.DamageReductions.Add(0.25); } else { damageModifier.DamageReductions.Add(0.5); } }
private int PerformCalculation(int baseDamage, CombatDamageModifier damageModifier) { double result = baseDamage; double totalBonus = 1; foreach (double damageBonus in damageModifier.DamageBonuses) { totalBonus += damageBonus; } result *= totalBonus; result = Math.Floor(result); foreach (double damageReduction in damageModifier.DamageReductions) { result *= (1 - damageReduction); result = Math.Floor(result); } int intResult = (int)result; return((intResult > 0) ? intResult : 1); }
public void CalculateDamage(CombatDamageCalculatorInputData data, out int minDamage, out int maxDamage, out string notes) { if (data.AttackerCount == 0) { minDamage = 0; maxDamage = 0; notes = null; return; } CombatDamageModifier damageModifier = new CombatDamageModifier(); AttackData attackData = new AttackData { Attacker = data.Attacker, Defender = data.Defender }; List<ICombatUnitStatsModifier> attackerStatsModifiers = new List<ICombatUnitStatsModifier>(); List<ICombatUnitStatsModifier> defenderStatsModifiers = new List<ICombatUnitStatsModifier>(); List<ICombatDamageModifierProvider> attackerDamageModifierProviders = new List<ICombatDamageModifierProvider>(); List<ICombatDamageModifierProvider> defenderDamageModifierProviders = new List<ICombatDamageModifierProvider>(); if (data.Terrain != null) { attackerStatsModifiers.Add(data.Terrain); defenderStatsModifiers.Add(data.Terrain); } if (data.AttackerHeroStats != null) { attackerStatsModifiers.Add(data.AttackerHeroStats); attackerDamageModifierProviders.Add(data.AttackerHeroStats); } if (data.DefenderHeroStats != null) { defenderStatsModifiers.Add(data.DefenderHeroStats); defenderDamageModifierProviders.Add(data.DefenderHeroStats); } if (data.AttackerSpells != null) { attackerStatsModifiers.AddRange(data.AttackerSpells); attackerDamageModifierProviders.AddRange(data.AttackerSpells); } if (data.DefenderSpells != null) { defenderStatsModifiers.AddRange(data.DefenderSpells); defenderDamageModifierProviders.AddRange(data.DefenderSpells); } attackerStatsModifiers.Add(UnitUniqueTraitManager.Instance); defenderStatsModifiers.Add(UnitUniqueTraitManager.Instance); attackerDamageModifierProviders.Add(UnitUniqueTraitManager.Instance); defenderDamageModifierProviders.Add(UnitUniqueTraitManager.Instance); ///////////////////////// UnitStats modifiedAttackerStats = data.Attacker.InitialStats.Copy(); UnitStats modifiedDefenderStats = data.Defender.InitialStats.Copy(); foreach (ICombatUnitStatsModifier modifier in attackerStatsModifiers) { modifier.ApplyPermanently(data.Attacker, modifiedAttackerStats); modifier.ApplyOnAttack(attackData, modifiedAttackerStats); } foreach (ICombatUnitStatsModifier modifier in defenderStatsModifiers) { modifier.ApplyPermanently(data.Defender, modifiedDefenderStats); modifier.ApplyOnDefense(attackData, modifiedDefenderStats); } int totalAttack = modifiedAttackerStats.Attack; int totalDefense = modifiedDefenderStats.Defense; if (totalAttack > totalDefense) { double primarySkillBonus = Math.Min((totalAttack - totalDefense) * 0.05, 3.0); damageModifier.DamageBonuses.Add(primarySkillBonus); } else if (totalAttack < totalDefense) { double primarySkillReduction = Math.Min((totalDefense - totalAttack) * 0.025, 0.7); damageModifier.DamageReductions.Add(primarySkillReduction); } ///////////////////////// foreach (ICombatDamageModifierProvider provider in attackerDamageModifierProviders) { provider.ApplyOnAttack(attackData, damageModifier); } foreach (ICombatDamageModifierProvider provider in defenderDamageModifierProviders) { provider.ApplyOnDefense(attackData, damageModifier); } int minBaseDamage = data.AttackerCount * modifiedAttackerStats.MinDamage; int maxBaseDamage = data.AttackerCount * modifiedAttackerStats.MaxDamage; minDamage = PerformCalculation(minBaseDamage, damageModifier); maxDamage = PerformCalculation(maxBaseDamage, damageModifier); notes = GenerateNotes(data); }
private int PerformCalculation(int baseDamage, CombatDamageModifier damageModifier) { double result = baseDamage; double totalBonus = 1; foreach (double damageBonus in damageModifier.DamageBonuses) { totalBonus += damageBonus; } result *= totalBonus; result = Math.Floor(result); foreach (double damageReduction in damageModifier.DamageReductions) { result *= (1 - damageReduction); result = Math.Floor(result); } int intResult = (int)result; return (intResult > 0) ? intResult : 1; }
public void CalculateDamage(CombatDamageCalculatorInputData data, out int minDamage, out int maxDamage, out string notes) { if (data.AttackerCount == 0) { minDamage = 0; maxDamage = 0; notes = null; return; } CombatDamageModifier damageModifier = new CombatDamageModifier(); AttackData attackData = new AttackData { Attacker = data.Attacker, Defender = data.Defender }; List <ICombatUnitStatsModifier> attackerStatsModifiers = new List <ICombatUnitStatsModifier>(); List <ICombatUnitStatsModifier> defenderStatsModifiers = new List <ICombatUnitStatsModifier>(); List <ICombatDamageModifierProvider> attackerDamageModifierProviders = new List <ICombatDamageModifierProvider>(); List <ICombatDamageModifierProvider> defenderDamageModifierProviders = new List <ICombatDamageModifierProvider>(); if (data.Terrain != null) { attackerStatsModifiers.Add(data.Terrain); defenderStatsModifiers.Add(data.Terrain); } if (data.AttackerHeroStats != null) { attackerStatsModifiers.Add(data.AttackerHeroStats); attackerDamageModifierProviders.Add(data.AttackerHeroStats); } if (data.DefenderHeroStats != null) { defenderStatsModifiers.Add(data.DefenderHeroStats); defenderDamageModifierProviders.Add(data.DefenderHeroStats); } if (data.AttackerSpells != null) { attackerStatsModifiers.AddRange(data.AttackerSpells); attackerDamageModifierProviders.AddRange(data.AttackerSpells); } if (data.DefenderSpells != null) { defenderStatsModifiers.AddRange(data.DefenderSpells); defenderDamageModifierProviders.AddRange(data.DefenderSpells); } attackerStatsModifiers.Add(UnitUniqueTraitManager.Instance); defenderStatsModifiers.Add(UnitUniqueTraitManager.Instance); attackerDamageModifierProviders.Add(UnitUniqueTraitManager.Instance); defenderDamageModifierProviders.Add(UnitUniqueTraitManager.Instance); ///////////////////////// UnitStats modifiedAttackerStats = data.Attacker.InitialStats.Copy(); UnitStats modifiedDefenderStats = data.Defender.InitialStats.Copy(); foreach (ICombatUnitStatsModifier modifier in attackerStatsModifiers) { modifier.ApplyPermanently(data.Attacker, modifiedAttackerStats); modifier.ApplyOnAttack(attackData, modifiedAttackerStats); } foreach (ICombatUnitStatsModifier modifier in defenderStatsModifiers) { modifier.ApplyPermanently(data.Defender, modifiedDefenderStats); modifier.ApplyOnDefense(attackData, modifiedDefenderStats); } int totalAttack = modifiedAttackerStats.Attack; int totalDefense = modifiedDefenderStats.Defense; if (totalAttack > totalDefense) { double primarySkillBonus = Math.Min((totalAttack - totalDefense) * 0.05, 3.0); damageModifier.DamageBonuses.Add(primarySkillBonus); } else if (totalAttack < totalDefense) { double primarySkillReduction = Math.Min((totalDefense - totalAttack) * 0.025, 0.7); damageModifier.DamageReductions.Add(primarySkillReduction); } ///////////////////////// foreach (ICombatDamageModifierProvider provider in attackerDamageModifierProviders) { provider.ApplyOnAttack(attackData, damageModifier); } foreach (ICombatDamageModifierProvider provider in defenderDamageModifierProviders) { provider.ApplyOnDefense(attackData, damageModifier); } int minBaseDamage = data.AttackerCount * modifiedAttackerStats.MinDamage; int maxBaseDamage = data.AttackerCount * modifiedAttackerStats.MaxDamage; minDamage = PerformCalculation(minBaseDamage, damageModifier); maxDamage = PerformCalculation(maxBaseDamage, damageModifier); notes = GenerateNotes(data); }
public virtual void ApplyOnDefense(AttackData attackData, CombatDamageModifier damageModifier) { }