ActionDistribution[] computeRaidHealing(bool burst, out int[] candidates) { ActionDistribution[] dists = new ActionDistribution[calc.Division.Count]; for (int div = 0; div < calc.Division.Count; ++div) { TreeStats stats = calc.Stats[div]; ComputedSpell[] spells = calc.Spells[div]; TreeComputedData data = DivisionData[div]; bool refreshLBWithDHs = Talents.EmpoweredTouch == 2 && opts.RefreshLifebloomWithDirectHeals; ContinuousAction[] actions = calc.Actions[div]; ActionDistribution dist = new ActionDistribution(actions, (int)TreePassive.Count); if (!burst) dist.MaxMPS = calc.ManaRegen; addPassiveHealing(dist, stats); addSelfHealing(dist, actions, spells, 1); addLifebloomRefresh(dist, actions, spells[(int)TreeSpell.Lifebloom], data, refreshLBWithDHs, opts.RejuvenationTankDuringRaid); double minDHRate = 0; if (refreshLBWithDHs) minDHRate = Math.Max(minDHRate, 1.0f / data.LifebloomRefreshInterval); // note that 1/15 + 1/25 > 1/10, so in practice swiftmends and cchts alone should be enough to keep up Harmony, unless the Swiftmend cast delay has been set high (> 4 seconds) if (opts.Restoration) minDHRate = Math.Max(minDHRate, 1.0f / 10.0f - 1.0 / (15 + opts.SwiftmendCastDelay)); addSpecialDirectHeals(dist, spells, stats, refreshLBWithDHs, !burst, minDHRate, burst); // TODO: add option to choose when to use tranquility (maybe even model it as a division?) dist.AddActionOnCooldown((int)TreeAction.RaidTranquility); if (Restoration) dist.AddActionOnCooldown((int)TreeAction.RaidSwiftmend); if (opts.RejuvenationTankDuringRaid) dist.AddActionOnCooldown((int)TreeAction.TankRejuvenation); if (Talents.WildGrowth > 0) dist.AddActionOnCooldown((int)TreeAction.RaidWildGrowth); dists[div] = dist; } List<int> candidatesList = new List<int>(); if(Talents.NaturesSwiftness > 0) candidatesList.Add((int)TreeAction.RaidSwiftHT); candidatesList.Add((int)TreeAction.RaidRejuvenation); candidatesList.Add((int)TreeAction.RaidHealingTouch); candidatesList.Add((int)TreeAction.RaidNourish); candidatesList.Add((int)TreeAction.RaidRegrowth); if(character.DruidTalents.NaturesBounty > 0) candidatesList.Add(opts.RejuvenationTankDuringRaid ? (int)TreeAction.RaidRj2NourishNB : (int)TreeAction.RaidRj3NourishNB); candidatesList.Add((int)TreeAction.RaidTolLb); candidatesList.Add((int)TreeAction.RaidTolLbCcHt); candidates = candidatesList.ToArray(); return dists; }
void addLifebloomRefresh(ActionDistribution dist, ContinuousAction[] actions, ComputedSpell spell, TreeComputedData data, bool automatic, bool rejuvenationUp) { if (!automatic) dist.AddActionOnCooldown((int)TreeAction.ReLifebloom); dist.AddPassive((int)TreePassive.RollingLifebloom, (rejuvenationUp ? spell.TankAction.Periodic : spell.RaidAction.Periodic) * 3 * opts.TankLifebloomEH / spell.Duration, -data.LifebloomMPSGain); dist.AddPassiveTPS((int)TreePassive.RollingLifebloom, spell.TPS); }
void addPassiveHealing(ActionDistribution dist, TreeStats stats) { dist.AddPassive((int)TreePassive.HealingTrinkets, stats.Healed * stats.DirectHealMultiplier * getCritMultiplier(stats, 0, 0)); if (InsectSwarm) dist.AddActionOnCooldown((int)TreeAction.InsectSwarm); }
ActionDistribution[] computeTankHealing(bool burst, out int[] candidates) { ActionDistribution[] dists = new ActionDistribution[calc.Division.Count]; for (int div = 0; div < calc.Division.Count; ++div) { TreeStats stats = calc.Stats[div]; ComputedSpell[] spells = calc.Spells[div]; TreeComputedData data = DivisionData[div]; ContinuousAction[] actions = calc.Actions[div]; ActionDistribution dist = new ActionDistribution(actions, (int)TreePassive.Count); if (!burst) dist.MaxMPS = calc.ManaRegen; addPassiveHealing(dist, stats); addSelfHealing(dist, actions, spells, opts.TankRaidHealingWeight); addLifebloomRefresh(dist, actions, spells[(int)TreeSpell.Lifebloom], data, Talents.EmpoweredTouch != 0, true); // assume we will automatically heal the tank enough to refresh lifebloom if we have Empowered Touch addSpecialDirectHeals(dist, spells, stats, true, !burst, 0, false); if (Restoration && opts.TankSwiftmend) dist.AddActionOnCooldown((int)TreeAction.TankSwiftmend); if (!burst && opts.TankWildGrowth && Talents.WildGrowth > 0) dist.AddActionOnCooldown((int)TreeAction.TankWildGrowth); dists[div] = dist; } List<int> candidatesList = new List<int>(); if (Talents.NaturesSwiftness > 0) candidatesList.Add((int)TreeAction.TankSwiftHT); candidatesList.Add((int)TreeAction.TankRejuvenation); candidatesList.Add((int)TreeAction.TankHealingTouch); candidatesList.Add((int)TreeAction.TankNourish); candidatesList.Add((int)TreeAction.TankRegrowth); if(character.DruidTalents.NaturesBounty > 0) candidatesList.Add((int)TreeAction.TankRj2NourishNB); candidatesList.Add((int)TreeAction.TankTolLbCcHt); candidates = candidatesList.ToArray(); return dists; }