public void AvoidableByTest() { Attack target = new Attack(); // Default is it avoidable by all. bool expected = true; bool actual; foreach (AVOIDANCE_TYPES at in Enum.GetValues(typeof(AVOIDANCE_TYPES))) { foreach (AVOIDANCE_TYPES at2 in Enum.GetValues(typeof(AVOIDANCE_TYPES))) { if ((at | at2) == AVOIDANCE_TYPES.None) expected = false; else expected = true; actual = target.AvoidableBy(at | at2); Assert.AreEqual(expected, actual, Enum.GetName(typeof(AVOIDANCE_TYPES), at | at2)); } } target.SetUnavoidable(); foreach (AVOIDANCE_TYPES at in Enum.GetValues(typeof(AVOIDANCE_TYPES))) { foreach (AVOIDANCE_TYPES at2 in Enum.GetValues(typeof(AVOIDANCE_TYPES))) { if ((at | at2) == AVOIDANCE_TYPES.None) expected = true; else expected = false; actual = target.AvoidableBy(at | at2); Assert.AreEqual(expected, actual, Enum.GetName(typeof(AVOIDANCE_TYPES), at | at2)); } } // Set up individual flag values. target.Missable = true; foreach (AVOIDANCE_TYPES at in Enum.GetValues(typeof(AVOIDANCE_TYPES))) { foreach (AVOIDANCE_TYPES at2 in Enum.GetValues(typeof(AVOIDANCE_TYPES))) { if ((at | at2) == AVOIDANCE_TYPES.Miss) expected = true; else expected = false; actual = target.AvoidableBy(at | at2); Assert.AreEqual(expected, actual, Enum.GetName(typeof(AVOIDANCE_TYPES), at | at2)); } } target.SetUnavoidable(); target.Dodgable = true; foreach (AVOIDANCE_TYPES at in Enum.GetValues(typeof(AVOIDANCE_TYPES))) { foreach (AVOIDANCE_TYPES at2 in Enum.GetValues(typeof(AVOIDANCE_TYPES))) { if ((at | at2) == AVOIDANCE_TYPES.Dodge) expected = true; else expected = false; actual = target.AvoidableBy(at | at2); Assert.AreEqual(expected, actual, Enum.GetName(typeof(AVOIDANCE_TYPES), at | at2)); } } target.SetUnavoidable(); target.Parryable = true; foreach (AVOIDANCE_TYPES at in Enum.GetValues(typeof(AVOIDANCE_TYPES))) { foreach (AVOIDANCE_TYPES at2 in Enum.GetValues(typeof(AVOIDANCE_TYPES))) { if ((at | at2) == AVOIDANCE_TYPES.Parry) expected = true; else expected = false; actual = target.AvoidableBy(at | at2); Assert.AreEqual(expected, actual, Enum.GetName(typeof(AVOIDANCE_TYPES), at | at2)); } } target.SetUnavoidable(); target.Blockable = true; foreach (AVOIDANCE_TYPES at in Enum.GetValues(typeof(AVOIDANCE_TYPES))) { foreach (AVOIDANCE_TYPES at2 in Enum.GetValues(typeof(AVOIDANCE_TYPES))) { if ((at | at2) == AVOIDANCE_TYPES.Block) expected = true; else expected = false; actual = target.AvoidableBy(at | at2); Assert.AreEqual(expected, actual, Enum.GetName(typeof(AVOIDANCE_TYPES), at | at2)); } } target.SetUnavoidable(); }
public void MissableTest() { Attack target = new Attack(); bool expected = true; bool actual; actual = target.Missable; Assert.AreEqual(expected, actual, "Miss default"); expected = false; target.Missable = expected; actual = target.Missable; Assert.AreEqual(expected, actual, "Misss false"); }
public void ParryableTest() { Attack target = new Attack(); bool expected = true; bool actual; actual = target.Parryable; Assert.AreEqual(expected, actual, "Parry default"); expected = false; target.Parryable = expected; actual = target.Parryable; Assert.AreEqual(expected, actual, "Parry false"); }
public void BlockableTest() { Attack target = new Attack(); bool expected = true; bool actual; actual = target.Blockable; Assert.AreEqual(expected, actual, "Block default"); expected = false; target.Blockable = expected; actual = target.Blockable; Assert.AreEqual(expected, actual, "Block false"); }
public void AvoidableTest() { Attack target = new Attack(); bool actual; actual = target.Avoidable; Assert.IsTrue(actual); target.SetUnavoidable(); actual = target.Avoidable; Assert.IsFalse(actual); }
private void CalculateHardAttack(List<Attack> attacks, int maxPlayers, string name, bool defaultmelee, out Attack toAdd) { bool isDot = attacks[0].IsDoT; float perhit = 0, pertick = 0, duration = 0, tickinterval = 12*60, numtrg = 0, atkspd = 12*60; Dictionary<ATTACK_TYPES, int> ATCounts = new Dictionary<ATTACK_TYPES, int>() { { ATTACK_TYPES.AT_MELEE, 0 }, { ATTACK_TYPES.AT_RANGED, 0 }, { ATTACK_TYPES.AT_AOE, 0 }, { ATTACK_TYPES.AT_DOT, 0 }, }; Dictionary<ItemDamageType, int> DTCounts = new Dictionary<ItemDamageType, int>() { { ItemDamageType.Physical, 0 }, { ItemDamageType.Arcane, 0 }, { ItemDamageType.Fire, 0 }, { ItemDamageType.Frost, 0 }, { ItemDamageType.Holy, 0 }, { ItemDamageType.Nature, 0 }, { ItemDamageType.Shadow, 0 }, }; Dictionary<PLAYER_ROLES, int> ARCounts = new Dictionary<PLAYER_ROLES, int>() { { PLAYER_ROLES.MainTank, 0 }, { PLAYER_ROLES.OffTank, 0 }, { PLAYER_ROLES.TertiaryTank, 0 }, { PLAYER_ROLES.MeleeDPS, 0 }, { PLAYER_ROLES.RangedDPS, 0 }, { PLAYER_ROLES.RaidHealer, 0 }, { PLAYER_ROLES.MainTankHealer, 0 }, { PLAYER_ROLES.OffAndTertTankHealer, 0 }, }; foreach (Attack a in attacks) { perhit = Math.Max(perhit, a.DamagePerHit); if (isDot) { pertick = Math.Max(pertick, a.DamagePerTick); duration = Math.Max(duration, a.Duration); tickinterval = Math.Min(tickinterval, a.TickInterval); } numtrg = Math.Max(numtrg, a.MaxNumTargets); atkspd = Math.Min(atkspd, a.AttackSpeed); ATCounts[a.AttackType]++; DTCounts[a.DamageType]++; for (int i = 0; i < (int)PLAYER_ROLES.RaidHealer; i++) { if (a.AffectsRole[(PLAYER_ROLES)i]) { ARCounts[(PLAYER_ROLES)i]++; } } } ATTACK_TYPES at = ATTACK_TYPES.AT_MELEE; foreach(ATTACK_TYPES t in ATCounts.Keys){ if (ATCounts[t] > ATCounts[at]) { at = t; } if (ATCounts[at] == ATCounts[ATTACK_TYPES.AT_MELEE]) { at = ATTACK_TYPES.AT_MELEE; } } ItemDamageType dt = ItemDamageType.Physical; foreach (ItemDamageType t in DTCounts.Keys) { if (DTCounts[t] > DTCounts[dt]) { dt = t; } if (DTCounts[dt] == DTCounts[ItemDamageType.Physical]) { dt = ItemDamageType.Physical; } } toAdd = new Attack { Name = name, IsDoT = isDot, AttackType = at, DamageType = dt, DamagePerHit = perhit, DamagePerTick = isDot ? pertick : 0, Duration = isDot ? duration : 0, TickInterval = isDot ? tickinterval : 0, MaxNumTargets = numtrg, AttackSpeed = atkspd, IsTheDefaultMelee = defaultmelee, }; foreach (PLAYER_ROLES pr in ARCounts.Keys) { toAdd.AffectsRole[pr] = ARCounts[pr] > 0; } }
private void CalculateAvgAttack(List<Attack> attacks, float fightDur, int maxPlayers, string name, bool defaultmelee, out Attack toAdd) { bool isDot = attacks[0].IsDoT; float perhit = 0, pertick = 0, duration = 0, tickinterval = 0, numtrg = 0, atkspd = 0f, phaseUptime = 0; Dictionary<ATTACK_TYPES, int> ATCounts = new Dictionary<ATTACK_TYPES, int>() { { ATTACK_TYPES.AT_MELEE, 0 }, { ATTACK_TYPES.AT_RANGED, 0 }, { ATTACK_TYPES.AT_AOE, 0 }, { ATTACK_TYPES.AT_DOT, 0 }, }; Dictionary<ItemDamageType, int> DTCounts = new Dictionary<ItemDamageType, int>() { { ItemDamageType.Physical, 0 }, { ItemDamageType.Arcane, 0 }, { ItemDamageType.Fire, 0 }, { ItemDamageType.Frost, 0 }, { ItemDamageType.Holy, 0 }, { ItemDamageType.Nature, 0 }, { ItemDamageType.Shadow, 0 }, }; Dictionary<PLAYER_ROLES, int> ARCounts = new Dictionary<PLAYER_ROLES, int>() { { PLAYER_ROLES.MainTank, 0 }, { PLAYER_ROLES.OffTank, 0 }, { PLAYER_ROLES.TertiaryTank, 0 }, { PLAYER_ROLES.MeleeDPS, 0 }, { PLAYER_ROLES.RangedDPS, 0 }, { PLAYER_ROLES.RaidHealer, 0 }, { PLAYER_ROLES.MainTankHealer, 0 }, { PLAYER_ROLES.OffAndTertTankHealer, 0 }, }; foreach (Attack a in attacks) { perhit += a.DamagePerHit; if (isDot) { pertick += a.DamagePerTick; duration += a.Duration; tickinterval += a.TickInterval; } numtrg += a.MaxNumTargets; atkspd += a.AttackSpeed; phaseUptime += a.FightUptimePercent; ATCounts[a.AttackType]++; DTCounts[a.DamageType]++; for (int i = 0; i < (int)PLAYER_ROLES.RaidHealer; i++) { if (a.AffectsRole[(PLAYER_ROLES)i]) { ARCounts[(PLAYER_ROLES)i]++; } } } perhit /= (float)attacks.Count; if (isDot) { pertick /= (float)attacks.Count; duration /= (float)attacks.Count; tickinterval /= (float)attacks.Count; } numtrg /= (float)attacks.Count; atkspd /= (float)attacks.Count; phaseUptime /= (float)attacks.Count; ATTACK_TYPES at = ATTACK_TYPES.AT_MELEE; foreach(ATTACK_TYPES t in ATCounts.Keys){ if (ATCounts[t] > ATCounts[at]) { at = t; } if (ATCounts[at] == ATCounts[ATTACK_TYPES.AT_MELEE]) { at = ATTACK_TYPES.AT_MELEE; } } ItemDamageType dt = ItemDamageType.Physical; foreach (ItemDamageType t in DTCounts.Keys) { if (DTCounts[t] > DTCounts[dt]) { dt = t; } if (DTCounts[dt] == DTCounts[ItemDamageType.Physical]) { dt = ItemDamageType.Physical; } } toAdd = new Attack { Name = name, IsDoT = isDot, AttackType = at, DamageType = dt, DamagePerHit = perhit, DamagePerTick = isDot ? pertick : 0, Duration = isDot ? duration : 0, TickInterval = isDot ? tickinterval : 0, MaxNumTargets = numtrg, AttackSpeed = atkspd, IsTheDefaultMelee = defaultmelee, FightDuration = fightDur, }; toAdd.PhaseTimes[1] = new float[] { 0f, fightDur * phaseUptime }; foreach (PLAYER_ROLES pr in ARCounts.Keys) { toAdd.AffectsRole[pr] = ((float)ARCounts[pr] / (float)attacks.Count) > 0.25f; // at least 25% of the affected roles matched } }
private void CalculateEZAttack(List<Attack> attacks, int maxPlayers, string name, bool defaultmelee, out Attack toAdd) { bool isDot = attacks[0].IsDoT; float perhit = BossHandler.StandardMeleePerHit[(int)BossHandler.TierLevels.T11_25H] * 2, // start at normal attack, some bosses could be less and it will pick that up pertick = BossHandler.StandardMeleePerHit[(int)BossHandler.TierLevels.T11_25H] * 2, duration = 20*60, //phasestarttime = 0, //phaseendtime = 20*60, tickinterval = 0, numtrg = maxPlayers, atkspd = 0f; Dictionary<ATTACK_TYPES, int> ATCounts = new Dictionary<ATTACK_TYPES, int>() { { ATTACK_TYPES.AT_MELEE, 0 }, { ATTACK_TYPES.AT_RANGED, 0 }, { ATTACK_TYPES.AT_AOE, 0 }, { ATTACK_TYPES.AT_DOT, 0 }, }; Dictionary<ItemDamageType, int> DTCounts = new Dictionary<ItemDamageType, int>() { { ItemDamageType.Physical, 0 }, { ItemDamageType.Arcane, 0 }, { ItemDamageType.Fire, 0 }, { ItemDamageType.Frost, 0 }, { ItemDamageType.Holy, 0 }, { ItemDamageType.Nature, 0 }, { ItemDamageType.Shadow, 0 }, }; Dictionary<PLAYER_ROLES, int> ARCounts = new Dictionary<PLAYER_ROLES, int>() { { PLAYER_ROLES.MainTank, 0 }, { PLAYER_ROLES.OffTank, 0 }, { PLAYER_ROLES.TertiaryTank, 0 }, { PLAYER_ROLES.MeleeDPS, 0 }, { PLAYER_ROLES.RangedDPS, 0 }, { PLAYER_ROLES.RaidHealer, 0 }, { PLAYER_ROLES.MainTankHealer, 0 }, { PLAYER_ROLES.OffAndTertTankHealer, 0 }, }; foreach (Attack a in attacks) { perhit = Math.Min(perhit, a.DamagePerHit); if (isDot) { pertick = Math.Min(pertick, a.DamagePerTick); duration = Math.Min(duration, a.Duration); tickinterval = Math.Max(tickinterval, a.TickInterval); } //phasestarttime = Math.Max(phasestarttime, a.PhaseStartTime); // this isn't actually gonna work //phaseendtime = Math.Min(phaseendtime, a.PhaseEndTime); numtrg = Math.Min(numtrg, a.MaxNumTargets); atkspd = Math.Max(atkspd, a.AttackSpeed); ATCounts[a.AttackType]++; DTCounts[a.DamageType]++; for (int i = 0; i < (int)PLAYER_ROLES.RaidHealer; i++) { if (a.AffectsRole[(PLAYER_ROLES)i]) { ARCounts[(PLAYER_ROLES)i]++; } } } ATTACK_TYPES at = ATTACK_TYPES.AT_MELEE; foreach(ATTACK_TYPES t in ATCounts.Keys){ if (ATCounts[t] > ATCounts[at]) { at = t; } if (ATCounts[at] == ATCounts[ATTACK_TYPES.AT_MELEE]) { at = ATTACK_TYPES.AT_MELEE; } } ItemDamageType dt = ItemDamageType.Physical; foreach (ItemDamageType t in DTCounts.Keys) { if (DTCounts[t] > DTCounts[dt]) { dt = t; } if (DTCounts[dt] == DTCounts[ItemDamageType.Physical]) { dt = ItemDamageType.Physical; } } toAdd = new Attack { Name = name, IsDoT = isDot, AttackType = at, DamageType = dt, DamagePerHit = perhit, DamagePerTick = isDot ? pertick : 0, Duration = isDot ? duration : 0, TickInterval = isDot ? tickinterval : 0, MaxNumTargets = numtrg, AttackSpeed = atkspd, IsTheDefaultMelee = defaultmelee, //PhaseStartTime = phasestarttime, //PhaseEndTime = phaseendtime, }; foreach (PLAYER_ROLES pr in ARCounts.Keys) { toAdd.AffectsRole[pr] = ARCounts[pr] > 0; } }