예제 #1
0
        public MainForm()
        {
            InitializeComponent();

            database = ObjectDatabase.Database;
            var pw = database.GetUnitByName("Photon Walker");

            var force = new Force
            {
                Name = "Robots Test",
                Formation = database.GetFormationByName("Rage Vindicator")
            };

            force.AddUnit(database.GetUnitByName("Field Marshall Riggs"));
            for (var i = 0; i < force.Formation.AssaultSlots - 1; i++)
                force.AddUnit(pw);
            force.AddUnit(database.GetUnitByName("Mammoth Tank"));
            force.AddUnit(database.GetUnitByName("Beowulf Cluster"));
            force.AddUnit(database.GetUnitByName("Omega, Machine of War"));

            force.AddReinforcement(pw, 2);

            var enemy = new Force
            {
                Name = "Dummy",
                IsEpicBoss = true
            };

            ForceReportTextBox.Text = force.ForceReport(enemy);
            ForceReportTextBox.SelectionStart = ForceReportTextBox.Text.Length;
        }
예제 #2
0
        public CombatResult CalculateAverageDamage(Force myForce, Force enemyForce, List<Effect> boosts, bool vsEpic = true)
        {
            EnsureEffectProcs();

            var result = new CombatResult();
            foreach (var effect in Effects)
            {
                result.Add(effect.CalculateAverageDamage(myForce, enemyForce, boosts, vsEpic));
            }

            // Apply Rally Effects - Rally will only work once for each ability and will affect abilities which deal no damage
            if (boosts != null)
            {
                foreach (var rallyEffect in boosts.Where(x => x.Type == EffectType.Rally))
                {
                    var abilBonus = rallyEffect.ParentAbilityProcChance*rallyEffect.EffectValue*this.ProcChance;
                    if (HasEffect(EffectType.FlurryDamage))
                    {
                        var baseBonus = abilBonus;
                        abilBonus = 0;
                        foreach (var effect in GetEffects(EffectType.FlurryDamage))
                        {
                            abilBonus += baseBonus*effect.EffectValue;
                        }
                    }
                    result.Damage += abilBonus;
                }
            }

            return result;
        }
예제 #3
0
        public CombatResult CalculateAverageDamage(Force myForce, Force enemyForce, bool vsEpic = true)
        {
            var result = new CombatResult();

            foreach (var ability in Abilities)
            {
                // Formations can never recieve Boosts
                result.Add(ability.CalculateAverageDamage(myForce, enemyForce, null, vsEpic));
            }

            return result;
        }
예제 #4
0
        public CombatResult CalculateAverageDamage(Force myForce, Force enemyForce, List<Effect> boosts, bool vsEpic = true)
        {
            var result = new CombatResult();

            var useableBoosts = new List<Effect>();
            if(boosts != null)
            {
                useableBoosts.AddRange(boosts.Where(effect => effect.IsBoostEffect() && this.IsClassification(effect.TargetType)).ToList());
            }
            foreach (var ability in Abilities)
            {
                result.Add(ability.CalculateAverageDamage(myForce, enemyForce, useableBoosts, vsEpic));
            }

            return result;
        }
예제 #5
0
        public double CalculateBoostToForce(Force myForce, Force enemyForce, bool vsEpic = true)
        {
            var bonus = 0.0;

            var boostEffects = new List<Effect>();
            foreach (var ability in Abilities)
            {
                boostEffects.AddRange(ability.GetEffects(EffectType.Rally));
                boostEffects.AddRange(ability.GetEffects(EffectType.Boost));
            }

            foreach (var effect in boostEffects)
            {
                foreach (var unit in myForce.GetUnits()) // TODO: Get this to count Reinforced units
                {
                    bonus += unit.CalculateBoostBonus(myForce, enemyForce, effect, vsEpic);
                }
            }

            return Math.Round(bonus, 2, MidpointRounding.AwayFromZero);
        }
예제 #6
0
        public CombatResult CalculateTotalDamageContribution(Guid claimerID, Force myForce, Force enemyForce, List<Effect> boosts, bool vsEpic = true)
        {
            var result = new CombatResult();

            result.Add(this.CalculateAverageDamage(myForce, enemyForce, boosts, vsEpic));
            result.Add(this.CalculateReinforcedDamage(claimerID, myForce, enemyForce, boosts, vsEpic));

            return result;
        }
예제 #7
0
        public CombatResult CalculateReinforcedDamage(Guid claimerID, Force myForce, Force enemyForce, List<Effect> boosts, bool vsEpic = true)
        {
            EnsureEffectProcs();

            var result = new CombatResult();

            if (HasEffect(EffectType.Reinforce) == false)
            {
                return result;
            }

            foreach (var effect in GetEffects(EffectType.Reinforce))
            {
                result.Add(effect.CalculateReinforcedDamage(claimerID, myForce, enemyForce, boosts, vsEpic));
            }

            return result;
        }
예제 #8
0
        public string ForceReport(Force enemy)
        {
            ResetCombat();
            var boosts = GetBoostAbilities();
            var repeatedUnits = new List<Guid>();

            var commandersString = new StringBuilder();
            foreach (var unit in Commanders)
            {
                commandersString.Append(unit.DamageReport(this, enemy, boosts, enemy.IsEpicBoss, "  "));
            }

            var assaultString = new StringBuilder();
            foreach (var unit in AssaultUnits)
            {
                if (repeatedUnits.Contains(unit.ID))
                {
                    continue;
                }

                var count = AssaultUnits.Count(x => x.ID == unit.ID);
                if (unit.Abilities.Any(x => x.HasEffect(EffectType.Reinforce)) == false && count > 1)
                {
                    repeatedUnits.Add(unit.ID);
                    assaultString.AppendFormat("  {0}x {1}", count, unit.DamageReport(this, enemy, boosts, enemy.IsEpicBoss, "  ", hideNamePrefix:true));
                }
                else
                {
                    assaultString.Append(unit.DamageReport(this, enemy, boosts, enemy.IsEpicBoss, "  "));
                }
            }

            var structureString = new StringBuilder();
            foreach (var unit in Structures)
            {
                if (repeatedUnits.Contains(unit.ID))
                {
                    continue;
                }

                var count = AssaultUnits.Count(x => x.ID == unit.ID);
                if (unit.Abilities.Any(x => x.HasEffect(EffectType.Reinforce)) == false && count > 1)
                {
                    repeatedUnits.Add(unit.ID);
                    structureString.AppendFormat("  {0}x {1}", count, unit.DamageReport(this, enemy, boosts, enemy.IsEpicBoss, "  ", hideNamePrefix: true));
                }
                else
                {
                    structureString.Append(unit.DamageReport(this, enemy, boosts, enemy.IsEpicBoss, "  "));
                }
            }

            var vindiFormString = new StringBuilder();
            foreach (var unit in Vindicators)
            {
                vindiFormString.Append(unit.DamageReport(this, enemy, boosts, enemy.IsEpicBoss, "  "));
            }
            vindiFormString.Append("\r\n");
            vindiFormString.Append(Formation.DamageReport(this, enemy, boosts, enemy.IsEpicBoss, "  "));

            ResetCombat();
            var total = CalculateAverageForceDamage(enemy);

            var report = string.Format(ReportTemplate, Name, Formation, commandersString, assaultString, structureString, vindiFormString,
                total.Damage, total.Healing, total.AntiHeal, total.Damage * 5);

            return report;
        }
예제 #9
0
        public CombatResult CalculateAverageForceDamage(Force enemy)
        {
            var total = new CombatResult();
            foreach (var unit in GetUnits())
            {
                total.Add(unit.CalculateTotalDamageContribution(this, enemy, this.GetBoostAbilities(), enemy.IsEpicBoss));
            }

            return total;
        }
예제 #10
0
        public CombatResult CalculateReinforcedDamage(Guid claimerID, Force myForce, Force enemyForce, List<Effect> boosts, bool vsEpic)
        {
            var result = new CombatResult();

            foreach (var unit in myForce.ClaimReinforcements(claimerID, TargetType, EffectValue))
            {
                // Add each reinforced units total average damage potential (including reinforcements it might bring in too)
                var baseDamage = unit.CalculateTotalDamageContribution(myForce, enemyForce, boosts, vsEpic);
                result.Add(baseDamage.AdjustToProcChance(ParentAbilityProcChance));
            }

            return result;
        }
예제 #11
0
        // boosts is populated with only effects that can boost the source abilities unit
        public CombatResult CalculateAverageDamage(Force myForce, Force enemyForce, List<Effect> boosts, bool vsEpic = true)
        {
            var result = new CombatResult();

            if (VsEpicOnly && (vsEpic == false))
            {
                return result;
            }

            var min = Min + (vsEpic ? MinBonusVsEpic : 0);
            var max = Max + (vsEpic ? MaxBonusVsEpic : 0);
            var avg = ((min + max)/2.0);
            if (IsDamageEffect())
            {
                if (Type == EffectType.FlurryDamage)
                {
                    avg *= EffectValue;
                }
                if (Type == EffectType.ConditionalDamage && enemyForce != null)
                {
                    avg *= enemyForce.AvgNumOfUnitTypeAfterReinforcements(TargetType);
                }

                result.Damage += (avg*ParentAbilityProcChance);

                // Apply Percentile Boosts
                if (boosts != null)
                {
                    foreach (var boostEffect in boosts.Where(x => x.Type == EffectType.Boost))
                    {
                        var boostBonus = 1 + (boostEffect.ParentAbilityProcChance*(boostEffect.EffectValue*0.01));
                        result.Damage *= boostBonus;
                    }
                }
            }
            if (IsHealingEffect())
            {
                if (Type == EffectType.ConditionalHeal && myForce != null)
                {
                    avg *= myForce.AvgNumOfUnitTypeAfterReinforcements(TargetType);
                }

                result.Healing += (avg*ParentAbilityProcChance);
            }
            if (Type == EffectType.AntiHeal)
            {
                result.AntiHeal += (avg*ParentAbilityProcChance);
            }

            return result;
        }
예제 #12
0
 public string DamageReport(Force force, Force enemy, List<Effect> boosts, bool isEpicBoss, string prefix = "")
 {
     var sb = new StringBuilder();
     sb.AppendFormat(prefix + "{0} [{1}]\r\n", Name, CalculateTotalDamageContribution(force, enemy, boosts, isEpicBoss).ToSimpleString());
     foreach (var ability in Abilities)
     {
         sb.AppendFormat(prefix + " * {0} [{1}]\r\n", ability.Name, ability.CalculateTotalDamageContribution(this.ID, force, enemy, null, isEpicBoss).ToSimpleString());
         foreach (var reinforcement in force.GetReinforcedUnits(ID))
         {
             sb.AppendFormat(prefix + "   * Reinforced - {0}", reinforcement.DamageReport(force, enemy, boosts, isEpicBoss, prefix + "\t  "));
         }
         if(ability.HasEffect(EffectType.Boost))
         {
             sb.AppendFormat(prefix + "   * Boosts units in this force for a total bonus of {0}\r\n", CalculateBoostToForce(force, enemy, isEpicBoss));
         }
         if(ability.HasEffect(EffectType.Rally))
         {
             sb.AppendFormat(prefix + "   * Rallies units in this force for a total bonus of {0}\r\n", CalculateBoostToForce(force, enemy, isEpicBoss));
         }
     }
     return sb.ToString();
 }
예제 #13
0
        private void RunTests()
        {
            var database = ObjectDatabase.Database;
            var riggs = database.GetUnitByName("Field Marshall Riggs");
            var pw = database.GetUnitByName("Photon Walker");
            var mt = database.GetUnitByName("Mammoth Tank");
            var beowulf = database.GetUnitByName("Beowulf Cluster");
            var omega = database.GetUnitByName("Omega, Machine of War");
            var rageVindi = database.GetFormationByName("Rage Vindicator");

            var force = new Force
            {
                Name = "Robots Test",
                Formation = rageVindi
            };

            var riggsDmg = riggs.CalculateAverageDamage(force, null, null, true);
            var pwNDmg = pw.CalculateAverageDamage(force, null, null, false);
            var pwEDmg = pw.CalculateAverageDamage(force, null, null, true);
            var mtDmg = mt.CalculateAverageDamage(force, null, null, true);
            var omegaDmg = omega.CalculateAverageDamage(force, null, null, true);

            var omegaBoost = pw.CalculateBoostBonus(force, null, omega.Abilities[0].Effects[0], true);
            var mtBoost = mt.CalculateBoostBonus(force, null, rageVindi.Abilities[0].Effects[0], true);

            force.AddUnit(riggs);
            force.AddUnit(riggs);
            for (int i = 0; i < force.Formation.AssaultSlots - 1; i++)
                force.AddUnit(pw);
            force.AddUnit(mt);
            force.AddUnit(beowulf);
            force.AddUnit(omega);

            force.AddReinforcement(pw, 2);

            var boosts = force.GetBoostAbilities();
            var poweredPW = pw.CalculateAverageDamage(force, null, boosts, true); // This is counting the vs epic & vs non-epic twice for rallys

            // These don't count reinforcements from Riggs
            var beoBonus = beowulf.CalculateBoostToForce(force, null, true);
            var rvBonus = rageVindi.CalculateBoostToForce(force, null, true);
            var omegaBonus = omega.CalculateBoostToForce(force, null, true);

            var riggsReinf = riggs.CalculateReinforcedDamage(force, null, boosts, true);

            force.ResetCombat();
            var riggsTotal = riggs.CalculateTotalDamageContribution(force, null, boosts, true);
            var pwTotal = pw.CalculateTotalDamageContribution(force, null, boosts, true);
            var mtTotal = mt.CalculateTotalDamageContribution(force, null, boosts, true);
            var beowulfTotal = beowulf.CalculateTotalDamageContribution(force, null, boosts, true);
            var omegaTotal = omega.CalculateTotalDamageContribution(force, null, boosts, true);

            force.ResetCombat();
            var enemy = new Force
            {
                Name = "Dummy",
                IsEpicBoss = true
            };
            var forceDmg = force.CalculateAverageForceDamage(enemy);
        }
예제 #14
0
        public double CalculateBoostBonus(Force myForce, Force enemyForce, Effect boostEffect, bool vsEpic = true)
        {
            // Find all effects that can boost this unit
            if (IsClassification(boostEffect.TargetType) == false)
            {
                return 0.0;
            }

            var bonus = 0.0;
            foreach (var unitAbility in Abilities)
            {
                bonus += unitAbility.CalculateBoostBonus(myForce, enemyForce, boostEffect, vsEpic);
            }

            return Math.Round(bonus, 2, MidpointRounding.AwayFromZero);
        }
예제 #15
0
        public CombatResult CalculateReinforcedDamage(Force myForce, Force enemyForce, List<Effect> boosts, bool vsEpic = true)
        {
            var result = new CombatResult();

            foreach (var ability in Abilities.Where(x => x.HasEffect(EffectType.Reinforce)))
            {
                result.Add(ability.CalculateReinforcedDamage(this.ID, myForce, enemyForce, boosts, vsEpic));
            }

            return result;
        }
예제 #16
0
        // This method assumes that the effect must be able to apply to this ability
        public double CalculateBoostBonus(Force myForce, Force enemyForce, Effect boostEffect, bool vsEpic = true)
        {
            var bonus = 0.0;
            if (boostEffect.Type == EffectType.Boost)
            {
                var boostBonus = (boostEffect.ParentAbilityProcChance * (boostEffect.EffectValue * 0.01));
                bonus += (CalculateAverageDamage(myForce, enemyForce, null, vsEpic).Damage * boostBonus);
            }
            else if (boostEffect.Type == EffectType.Rally)
            {
                var abilBonus = boostEffect.ParentAbilityProcChance * boostEffect.EffectValue * ProcChance;
                var flurryEffects = Effects.Where(x => x.Type == EffectType.FlurryDamage).ToList();
                if (flurryEffects.Count > 0)
                {
                    var baseBonus = abilBonus;
                    abilBonus = 0;
                    foreach (var flurryEffect in flurryEffects)
                    {
                        abilBonus += baseBonus * flurryEffect.EffectValue;
                    }
                }
                bonus += abilBonus;
            }

            return Math.Round(bonus, 2, MidpointRounding.AwayFromZero);
        }
예제 #17
0
        public string DamageReport(Force force, Force enemy, List<Effect> boosts, bool isEpicBoss, string prefix = "", bool hideNamePrefix = false, double reinforcementRate = 0.0)
        {
            var sb = new StringBuilder();
            if (reinforcementRate > 0.0) // TODO: Better fix for this
            {
                var contrib = CalculateTotalDamageContribution(force, enemy, boosts, isEpicBoss);
                sb.AppendFormat((hideNamePrefix ? "" : prefix) + "{0} [{1}] at {2}% = [{3}]\r\n", Name, contrib.ToSimpleString(), reinforcementRate * 100, contrib.AdjustToProcChance(reinforcementRate).ToSimpleString());
            }
            else
            {
                sb.AppendFormat((hideNamePrefix ? "" : prefix) + "{0} [{1}]\r\n", Name, CalculateTotalDamageContribution(force, enemy, boosts, isEpicBoss).ToSimpleString());
            }

            var useableBoosts = new List<Effect>();
            if (boosts != null)
            {
                useableBoosts.AddRange(boosts.Where(effect => effect.IsBoostEffect() && this.IsClassification(effect.TargetType)).ToList());
            }
            foreach (var ability in Abilities)
            {
                var dmg = ability.CalculateTotalDamageContribution(this.ID, force, enemy, useableBoosts, isEpicBoss);
                sb.AppendFormat(prefix + " * {0} [{1}]\r\n", ability.Name, dmg.ToSimpleString());
                if(dmg.DoneAnything() && useableBoosts.Count > 0)
                {
                    sb.AppendFormat(prefix + "   * Base [{0}]\r\n", ability.CalculateTotalDamageContribution(this.ID, force, enemy, null, isEpicBoss).ToSimpleString());
                }
                foreach (var effect in useableBoosts)
                {
                    if(IsClassification(effect.TargetType))
                    {
                        sb.AppendFormat(prefix + "   + {0} {1} {2}\r\n", ability.CalculateBoostBonus(force, enemy, effect, isEpicBoss), effect.ParentsName,  effect.Type == EffectType.Boost ? "Boost" : "Rally");
                    }
                }
                var repeatedReinforcements = new List<Guid>();
                foreach (var reinforcement in force.GetReinforcedUnits(ID))
                {
                    if (repeatedReinforcements.Contains(reinforcement.ID))
                    {
                        continue;
                    }

                    var count = force.GetReinforcedUnits(ID).Count(x => x.ID == reinforcement.ID);
                    if (reinforcement.Abilities.Any(x => x.HasEffect(EffectType.Reinforce)) == false && count > 1)
                    {
                        repeatedReinforcements.Add(reinforcement.ID);
                        sb.AppendFormat(prefix + "   * {0}x Reinforced - {1}", count, reinforcement.DamageReport(force, enemy, boosts, isEpicBoss, prefix + "\t  ", hideNamePrefix: true, reinforcementRate: 0.5)); // TODO: Better fix for this
                    }
                    else
                    {
                        sb.AppendFormat(prefix + "   * Reinforced - {0}", reinforcement.DamageReport(force, enemy, boosts, isEpicBoss, prefix + "\t  ", hideNamePrefix: true));
                    }
                }
                if (ability.HasEffect(EffectType.Boost))
                {
                    sb.AppendFormat(prefix + "   * Boosts units in this force for a total bonus of {0}\r\n", CalculateBoostToForce(force, enemy, isEpicBoss));
                }
                if (ability.HasEffect(EffectType.Rally))
                {
                    sb.AppendFormat(prefix + "   * Rallies units in this force for a total bonus of {0}\r\n", CalculateBoostToForce(force, enemy, isEpicBoss));
                }
            }
            return sb.ToString();
        }