diff --git a/assets/database/db.bin b/assets/database/db.bin index bcbea6a4ce..f52cc3c317 100644 Binary files a/assets/database/db.bin and b/assets/database/db.bin differ diff --git a/assets/database/db.json b/assets/database/db.json index 0112d6e3ed..65bfb6c9fa 100644 --- a/assets/database/db.json +++ b/assets/database/db.json @@ -18071,7 +18071,6 @@ {"id":770,"name":"Faerie Fire","icon":"spell_nature_faeriefire","hasBuff":true}, {"id":779,"name":"Swipe","icon":"inv_misc_monsterclaw_03"}, {"id":879,"name":"Exorcism","icon":"spell_holy_excorcism_02"}, -{"id":1130,"name":"Hunter's Mark","icon":"ability_hunter_snipershot","hasBuff":true}, {"id":1459,"name":"Arcane Brilliance","icon":"spell_holy_magicalsentry","hasBuff":true}, {"id":1463,"name":"Incanter's Ward","icon":"spell_shadow_detectlesserinvisibility","hasBuff":true}, {"id":1490,"name":"Curse of the Elements","icon":"warlock_curse_shadow","hasBuff":true}, diff --git a/assets/database/leftover_db.bin b/assets/database/leftover_db.bin index c03ba7a198..1514f0951e 100644 Binary files a/assets/database/leftover_db.bin and b/assets/database/leftover_db.bin differ diff --git a/proto/common.proto b/proto/common.proto index 356ea176b4..9cd9a7b632 100644 --- a/proto/common.proto +++ b/proto/common.proto @@ -431,88 +431,66 @@ enum TristateEffect { } // Buffs that affect the entire raid. -// TODO: Reindex -// next index: 48 +// Reindexed to Mists of Pandaria raid buffs. +// Next index: 36 message RaidBuffs { - // +5% Base Stats and Spell Resistances - bool mark_of_the_wild = 1; - bool blessing_of_kings = 2; - bool drums_of_the_burning_wild = 3; - bool legacy_of_the_emperor = 47; - - // +Spell Resistances - bool elemental_resistance_totem = 4; - bool resistance_aura = 5; - bool shadow_protection = 6; - bool aspect_of_the_wild = 7; - - // +Stamina - bool power_word_fortitude = 8; - bool commanding_shout = 9; - bool blood_pact = 10; - - // +Stength and Agility - bool battle_shout = 11; - bool horn_of_winter = 12; - bool strength_of_earth_totem = 13; - // +10% Attack Power - bool trueshot_aura = 14; - bool unleashed_rage = 15; - bool abominations_might = 16; - bool blessing_of_might = 17; - - // +10% Melee Speed - bool windfury_totem = 18; - bool icy_talons = 19; - bool hunting_party = 20; - - // +Mana - bool arcane_brilliance = 21; // Also +Mp5 - bool fel_intelligence = 22; // Also +6% SP - - // +Mana Regen - bool mana_spring_totem = 23; - - // +Spell Power - bool demonic_pact = 24; - bool totemic_wrath = 25; - bool flametongue_totem = 26; // 6% SP - - // +5% Spell haste - bool moonkin_form = 27; - bool shadow_form = 28; - bool wrath_of_air_totem = 29; - - // +3% All Damage - bool arcane_tactics = 30; - bool ferocious_inspiration = 31; - bool communion = 32; - - // +5% All Crit - bool leader_of_the_pack = 33; - bool elemental_oath = 34; - bool honor_among_thieves = 35; - bool rampage = 36; - bool terrifying_roar = 37; - bool furious_howl = 45; - bool legacy_of_the_white_tiger = 46; + bool horn_of_winter = 1; // Death Knights + bool trueshot_aura = 2; // Hunters + bool battle_shout = 3; // Warriors + + // +10% Melee and Ranged Attack Speed + bool unholy_aura = 5; // Frost/Unholy DKs + bool cackling_howl = 6; // Hyena Pets + bool serpents_swiftness = 7; // Serpent Pets + bool swiftblades_cunning = 8; // Rogues + bool unleashed_rage = 9; // Enhancement Shamans + + // +10% Spell Power + bool still_water = 10; // Exotic Water Strider Pets + bool arcane_brilliance = 11; // Mages + bool burning_wrath = 12; // Shamans + bool dark_intent = 13; // Warlocks + + // +5% Spell Haste + bool moonkin_aura = 14; // Balance Druids + bool mind_quickening = 15; // Sporebat Pets + bool shadow_form = 16; // Shadow Priests + bool elemental_oath = 17; // Elemental Shamans + + // +5% Critical Strike Chance + bool leader_of_the_pack = 18; // Feral/Guardian Druids + bool terrifying_roar = 19; // Devilsaur Pets + bool furious_howl = 20; // Wolf Pets + bool legacy_of_the_white_tiger= 21; // Windwalker Monks + + // +3000 Mastery Rating + bool roar_of_courage = 22; // Cat Pets + bool spirit_beast_blessing = 23; // Spirit Beast Pets + bool blessing_of_might = 24; // Paladins + bool grace_of_air = 25; // Shamans + + // +5% Strength, Agility, Intellect + bool mark_of_the_wild = 26; // Druids + bool embrace_of_the_shale_spider = 27; // Shale Spider Pets + bool legacy_of_the_emperor = 28; // Monks + bool blessing_of_kings = 29; // Paladins + + // +10% Stamina + bool qiraji_fortitude = 30; // Silithid Pets + bool power_word_fortitude = 31; // Priests + bool commanding_shout = 4; // Warriors // Major Haste - bool bloodlust = 38; - bool heroism = 39; - bool time_warp = 40; - - // Major Mana Replenishment - int32 mana_tide_totem_count = 41; - - // +Armor - bool devotion_aura = 42; - bool stoneskin_totem = 43; + bool bloodlust = 32; + bool heroism = 33; + bool time_warp = 34; - // Miscellaneous - bool retribution_aura = 44; -} + // Raid Cooldowns + int32 mana_tide_totem_count = 35; + int32 stormlash_totem_count = 36; + int32 skull_banner_count = 37; + } // Buffs that affect a single party. message PartyBuffs { @@ -528,15 +506,7 @@ message IndividualBuffs { int32 innervate_count = 10; int32 hymn_of_hope_count = 7; - // Minor Mana Replenishment - bool vampiric_touch = 14; - bool enduring_winter = 18; - bool soul_leach = 16; - bool revitalize = 17; - bool communion = 100; - // Other Buffs - int32 power_infusion_count = 11; int32 unholy_frenzy_count = 12; TristateEffect tricks_of_the_trade = 101; // "Regular" = Glyphed, "Improved" = un-Glyphed int32 divine_guardian_count = 23; @@ -545,57 +515,42 @@ message IndividualBuffs { int32 guardian_spirit_count = 26; int32 rallying_cry_count = 102; int32 shattering_throw_count = 103; - bool focus_magic = 22; - bool dark_intent = 27; } message Debuffs { - // 8% spell damage - bool curse_of_elements = 1; - bool ebon_plaguebringer = 2; - bool earth_and_moon = 3; - bool master_poisoner = 4; - bool fire_breath = 5; - bool lightning_breath = 6; - - // 5% spell crit - bool critical_mass = 7; - bool shadow_and_flame = 8; - - // 30% bleed damage - bool blood_frenzy = 9; - bool hemorrhage = 10; - bool mangle = 11; - bool stampede = 12; - - // Major armor - bool expose_armor = 13; - bool sunder_armor = 14; - bool faerie_fire = 15; - bool corrosive_spit = 16; - - // 4% physical dmg - bool savage_combat = 17; - bool brittle_bones = 18; - bool acid_spit = 19; - - // -dmg % - bool curse_of_weakness = 20; - bool demoralizing_roar = 21; - bool demoralizing_shout = 22; - bool vindication = 23; - bool scarlet_fever = 24; - bool demoralizing_screech = 25; - bool keg_smask = 32; - - // -attack speed - bool thunder_clap = 26; - bool frost_fever = 27; - bool infected_wounds = 28; - bool judgements_of_the_just = 29; - bool dust_cloud = 30; - bool earth_shock = 31; -} + + // –10% Physical damage dealt for 30s + // Physical‐damage‐dealt sources: + // Scarlet Fever, Thrash, Demoralizing Roar, Demoralizing Screech, Keg Smash, + // Hammer of the Righteous, Earth Shock, Curse of Enfeeblement, Thunder Clap + bool weakened_blows = 1; + + // +4% Physical damage taken for 30s + // Gore, Stampede, Acid Spit, Ravage, Judgments of the Bold, Colossus Smash + bool physical_vulnerability = 2; + + // –4% Armor for 30s, stacks 3 times + // Faerie Fire, Tear Armor, Dust Cloud, Expose Armor, Sunder Armor + bool weakened_armor = 3; + + //Healing reduction + //Widow Venom, Monstrous Bite, Rising Sun Kick, Wound Poison, Mortal Strike, Wild Strike + bool mortal_wounds = 4; + + // Spell‐damage‐taken sources: + bool fire_breath = 5; + bool lightning_breath = 6; + bool master_poisoner = 7; + bool curse_of_elements = 8; + + // Casting‐speed‐reduction sources: + bool necrotic_strike = 9; + bool lava_breath = 10; + bool spore_cloud = 11; + bool slow = 12; + bool mind_numbing_poison = 13; + bool curse_of_enfeeblement = 14; + } message ConsumesSpec { int32 prepot_id = 1; @@ -869,13 +824,11 @@ message HealingModel { // How often healing is applied. double cadence_seconds = 2; // Variation in the cadence. - double cadence_variation = 5; + double cadence_variation = 4; // Fraction of each heal to model as an absorb shield. - double absorb_frac = 6; - // % Inspiration buff uptime - double inspiration_uptime = 3; + double absorb_frac = 5; // TMI burst window bin size - int32 burst_window = 4; + int32 burst_window = 3; } message CustomRotation { diff --git a/sim/core/armor_test.go b/sim/core/armor_test.go index ca7cfc91d5..aab777fde0 100644 --- a/sim/core/armor_test.go +++ b/sim/core/armor_test.go @@ -6,7 +6,7 @@ import ( "github.com/wowsims/mop/sim/core/stats" ) -func TestSunderArmorStacks(t *testing.T) { +func TestWeakenedArmorStacks(t *testing.T) { sim := Simulation{} baseArmor := 11977.0 target := Unit{ @@ -24,7 +24,7 @@ func TestSunderArmorStacks(t *testing.T) { t.Fatalf("Armor value for target should be %f but found %f", 11977.0, target.Armor()) } stacks := int32(1) - sunderAura := SunderArmorAura(&target) + sunderAura := WeakenedArmorAura(&target) sunderAura.Activate(&sim) sunderAura.SetStacks(&sim, stacks) tolerance := 0.001 @@ -38,96 +38,6 @@ func TestSunderArmorStacks(t *testing.T) { } } -func TestAcidSpitStacks(t *testing.T) { - sim := Simulation{} - baseArmor := 11977.0 - target := Unit{ - Type: EnemyUnit, - Index: 0, - Level: 88, - auraTracker: newAuraTracker(), - initialStats: stats.Stats{stats.Armor: baseArmor}, - PseudoStats: stats.NewPseudoStats(), - Metrics: NewUnitMetrics(), - } - target.stats = target.initialStats - expectedArmor := baseArmor - if target.Armor() != expectedArmor { - t.Fatalf("Armor value for target should be %f but found %f", 11977.0, target.Armor()) - } - stacks := int32(1) - corrosiveSpitAura := CorrosiveSpitAura(&target) - corrosiveSpitAura.Activate(&sim) - corrosiveSpitAura.SetStacks(&sim, stacks) - tolerance := 0.001 - for stacks <= 3 { - expectedArmor = baseArmor * (1.0 - float64(stacks)*0.04) - if !WithinToleranceFloat64(expectedArmor, target.Armor(), tolerance) { - t.Fatalf("Armor value for target should be %f but found %f", expectedArmor, target.Armor()) - } - stacks++ - corrosiveSpitAura.AddStack(&sim) - } -} - -func TestExposeArmor(t *testing.T) { - sim := Simulation{} - baseArmor := 11977.0 - target := Unit{ - Type: EnemyUnit, - Index: 0, - Level: 88, - auraTracker: newAuraTracker(), - initialStats: stats.Stats{stats.Armor: baseArmor}, - PseudoStats: stats.NewPseudoStats(), - Metrics: NewUnitMetrics(), - } - target.stats = target.initialStats - expectedArmor := baseArmor - if target.Armor() != expectedArmor { - t.Fatalf("Armor value for target should be %f but found %f", 11977.0, target.Armor()) - } - exposeAura := ExposeArmorAura(&target, false) - exposeAura.Activate(&sim) - tolerance := 0.001 - expectedArmor = baseArmor * (1.0 - 0.12) - if !WithinToleranceFloat64(expectedArmor, target.Armor(), tolerance) { - t.Fatalf("Armor value for target should be %f but found %f", expectedArmor, target.Armor()) - } -} - -func TestMajorArmorReductionAurasDoNotStack(t *testing.T) { - sim := Simulation{} - baseArmor := 11977.0 - target := Unit{ - Type: EnemyUnit, - Index: 0, - Level: 88, - auraTracker: newAuraTracker(), - initialStats: stats.Stats{stats.Armor: baseArmor}, - PseudoStats: stats.NewPseudoStats(), - Metrics: NewUnitMetrics(), - } - target.stats = target.initialStats - expectedArmor := baseArmor - if target.Armor() != expectedArmor { - t.Fatalf("Armor value for target should be %f but found %f", 11977.0, target.Armor()) - } - corrosiveSpitAura := CorrosiveSpitAura(&target) - corrosiveSpitAura.Activate(&sim) - corrosiveSpitAura.SetStacks(&sim, 3) - tolerance := 0.001 - expectedArmor = baseArmor * (1.0 - 0.12) - if !WithinToleranceFloat64(expectedArmor, target.Armor(), tolerance) { - t.Fatalf("Armor value for target should be %f but found %f", expectedArmor, target.Armor()) - } - exposeArmorAura := ExposeArmorAura(&target, false) - exposeArmorAura.Activate(&sim) - if !WithinToleranceFloat64(expectedArmor, target.Armor(), tolerance) { - t.Fatalf("Armor value for target should be %f but found %f", expectedArmor, target.Armor()) - } -} - func TestDamageReductionFromArmor(t *testing.T) { sim := Simulation{} baseArmor := 11977.0 @@ -154,28 +64,19 @@ func TestDamageReductionFromArmor(t *testing.T) { } // Major - corrosiveSpitAura := CorrosiveSpitAura(&target) - corrosiveSpitAura.Activate(&sim) - corrosiveSpitAura.SetStacks(&sim, 3) + weakenedArmorAura := WeakenedArmorAura(&target) + weakenedArmorAura.Activate(&sim) + weakenedArmorAura.SetStacks(&sim, 3) expectedDamageReduction = 0.287895 if !WithinToleranceFloat64(1-expectedDamageReduction, attackTable.GetArmorDamageModifier(spell), tolerance) { t.Fatalf("Expected major armor modifier to result in %f damage reduction got %f", expectedDamageReduction, 1-attackTable.GetArmorDamageModifier(spell)) } - corrosiveSpitAura.Deactivate(&sim) - - // Major - faerieFireAura := FaerieFireAura(&target) - faerieFireAura.Activate(&sim) - faerieFireAura.SetStacks(&sim, 3) - expectedDamageReduction = 0.287895 - if !WithinToleranceFloat64(1-expectedDamageReduction, attackTable.GetArmorDamageModifier(spell), tolerance) { - t.Fatalf("Expected major & minor armor modifier to result in %f damage reduction got %f", expectedDamageReduction, 1-attackTable.GetArmorDamageModifier(spell)) - } + weakenedArmorAura.Deactivate(&sim) // Major Multi shatteringThrowAura := ShatteringThrowAura(&target, attacker.UnitIndex) shatteringThrowAura.Activate(&sim) - expectedDamageReduction = 0.244387 + expectedDamageReduction = 0.268757 if !WithinToleranceFloat64(1-expectedDamageReduction, attackTable.GetArmorDamageModifier(spell), tolerance) { t.Fatalf("Expected major & shattering modifier to result in %f damage reduction got %f", expectedDamageReduction, 1-attackTable.GetArmorDamageModifier(spell)) } diff --git a/sim/core/buffs.go b/sim/core/buffs.go index 0c121f47e7..6f10293276 100644 --- a/sim/core/buffs.go +++ b/sim/core/buffs.go @@ -1,9 +1,6 @@ package core import ( - "cmp" - "slices" - "strconv" "time" googleProto "google.golang.org/protobuf/proto" @@ -66,7 +63,6 @@ func makeExclusiveAllStatPercentBuff(unit *Unit, label string, actionID ActionID []StatConfig{ {stats.Agility, value, true}, {stats.Strength, value, true}, - {stats.Stamina, value, true}, {stats.Intellect, value, true}, }}) } @@ -91,304 +87,139 @@ func makeExclusiveBuff(unit *Unit, config BuffConfig) *Aura { } // Applies buffs that affect individual players. -func applyBuffEffects(agent Agent, raidBuffs *proto.RaidBuffs, _ *proto.PartyBuffs, individualBuffs *proto.IndividualBuffs) { - character := agent.GetCharacter() +func applyBuffEffects(agent Agent, raidBuffs *proto.RaidBuffs, _ *proto.PartyBuffs, individual *proto.IndividualBuffs) { + char := agent.GetCharacter() + u := &char.Unit - // % Stats Buffs - // https://www.wowhead.com/mop-classic/spell=1126/mark-of-the-wild - // https://www.wowhead.com/mop-classic/spell=20217/blessing-of-kings - // https://www.wowhead.com/mop-classic/item=63140/drums-of-the-burning-wild - if raidBuffs.BlessingOfKings { - BlessingOfKingsAura(&character.Unit) + // +10% Attack Power + if raidBuffs.HornOfWinter { + HornOfWinterAura(u, true) } - - if raidBuffs.DrumsOfTheBurningWild { - DrumsOfTheBurningWildAura(&character.Unit) + if raidBuffs.TrueshotAura { + TrueShotAura(u) } - - if raidBuffs.MarkOfTheWild { - MarkOfTheWildAura(&character.Unit) + if raidBuffs.BattleShout { + BattleShoutAura(u, true) } - if raidBuffs.LegacyOfTheEmperor { - LegacyOfTheEmperorAura(&character.Unit) + // +10% Melee and Ranged Attack Speed + if raidBuffs.UnholyAura { + UnholyAura(u) } - - // Resistances - if raidBuffs.ResistanceAura { - ResistanceAura(&character.Unit) + if raidBuffs.CacklingHowl { + CacklingHowlAura(u) } - - if raidBuffs.ShadowProtection { - ShadowProtectionAura(&character.Unit) + if raidBuffs.SerpentsSwiftness { + SerpentsSwiftnessAura(u) } - - if raidBuffs.AspectOfTheWild { - AspectOfTheWildAura(&character.Unit) + if raidBuffs.SwiftbladesCunning { + SwiftbladesCunningAura(u) } - - if raidBuffs.ElementalResistanceTotem { - ElementalResistanceTotemAura(&character.Unit) + if raidBuffs.UnleashedRage { + UnleashedRageAura(u) } - // Stamina - applyStaminaBuffs(&character.Unit, raidBuffs) - - // Strength and Agility - applyStrengthAgilityBuffs(&character.Unit, raidBuffs) - - // Mana - if raidBuffs.ArcaneBrilliance { - ArcaneBrilliance(&character.Unit) + // +10% Spell Power + if raidBuffs.StillWater { + StillWaterAura(u) } - - if raidBuffs.FelIntelligence { - FelIntelligence(&character.Unit) + if raidBuffs.ArcaneBrilliance { + ArcaneBrilliance(u) } - - // Melee haste - if raidBuffs.WindfuryTotem { - WindfuryTotem(&character.Unit) + if raidBuffs.BurningWrath { + BurningWrathAura(u) } - - if raidBuffs.IcyTalons { - IcyTalons(&character.Unit) + if raidBuffs.DarkIntent { + MakePermanent(DarkIntentAura(u)) } - if raidBuffs.HuntingParty { - HuntingParty(&character.Unit) + // +5% Spell Haste + if raidBuffs.MoonkinAura { + MoonkinAura(u) } - - // +Crit% - if raidBuffs.LeaderOfThePack { - LeaderOfThePack(&character.Unit) + if raidBuffs.MindQuickening { + MindQuickeningAura(u) } - - if raidBuffs.Rampage { - Rampage(&character.Unit) + if raidBuffs.ShadowForm { + ShadowFormAura(u) } - if raidBuffs.ElementalOath { - ElementalOath(&character.Unit) + ElementalOath(u) } - if raidBuffs.HonorAmongThieves { - HonorAmongThieves(&character.Unit) + // +5% Critical Strike Chance + if raidBuffs.LeaderOfThePack { + LeaderOfThePack(u) } - if raidBuffs.TerrifyingRoar { - TerrifyingRoar(&character.Unit) + TerrifyingRoar(u) } - if raidBuffs.FuriousHowl { - FuriousHowl(&character.Unit) + FuriousHowl(u) } - if raidBuffs.LegacyOfTheWhiteTiger { - LegacyOfTheWhiteTiger(&character.Unit) + LegacyOfTheWhiteTiger(u) } - // +% Attackpower - if raidBuffs.AbominationsMight { - AbominationsMightAura(&character.Unit) + // +3000 Mastery Rating + if raidBuffs.RoarOfCourage { + RoarOfCourageAura(u) } - - if raidBuffs.UnleashedRage { - UnleashedRageAura(&character.Unit) - } - - if raidBuffs.TrueshotAura { - TrueShotAura(&character.Unit) + if raidBuffs.SpiritBeastBlessing { + SpiritBeastBlessingAura(u) } - if raidBuffs.BlessingOfMight { - BlessingOfMightAura(&character.Unit) - } - - // Spell Haste - if raidBuffs.MoonkinForm { - MoonkinAura(&character.Unit) - } - - if raidBuffs.ShadowForm { - ShadowFormAura(&character.Unit) - } - - if raidBuffs.WrathOfAirTotem { - WrathOfAirAura(&character.Unit) - } - - // Spell Power - if raidBuffs.FlametongueTotem { - FlametongueTotem(&character.Unit) + BlessingOfMightAura(u) } - - // Arcane Brilliance already @Mana Buffs - if raidBuffs.DemonicPact { - DemonicPact(&character.Unit) - } - - if raidBuffs.TotemicWrath { - TotemicWrath(&character.Unit) - } - - // +DMG% - if raidBuffs.ArcaneTactics { - ArcaneTactics(&character.Unit) - } - - if raidBuffs.FerociousInspiration { - FerociousInspiration(&character.Unit) + if raidBuffs.GraceOfAir { + GraceOfAirAura(u) } - if raidBuffs.Communion { - Communion(&character.Unit) - } - - // MP5 - if raidBuffs.ManaSpringTotem { - ManaSpringTotem(&character.Unit) + // +5% Strength, Agility, Intellect + if raidBuffs.MarkOfTheWild { + MarkOfTheWildAura(u) } - - // Armor - if raidBuffs.DevotionAura { - DevotionAura(&character.Unit) + if raidBuffs.EmbraceOfTheShaleSpider { + EmbraceOfTheShaleSpiderAura(u) } - - if raidBuffs.StoneskinTotem { - StoneskinTotem(&character.Unit) - } - - // Blessing Of Might @AttackPower& - // Fel Inteligenc @Mana+ - - var replenishmentActionID ActionID - if individualBuffs.VampiricTouch { - replenishmentActionID.SpellID = 34914 - } else if individualBuffs.SoulLeach { - replenishmentActionID.SpellID = 30295 - } else if individualBuffs.Revitalize { - replenishmentActionID.SpellID = 48544 - } else if individualBuffs.EnduringWinter { - replenishmentActionID.SpellID = 44561 - } else if individualBuffs.Communion { - replenishmentActionID.SpellID = 31876 + if raidBuffs.LegacyOfTheEmperor { + LegacyOfTheEmperorAura(u) } - - if !(replenishmentActionID.IsEmptyAction()) { - MakePermanent(replenishmentAura(&character.Unit, replenishmentActionID)) + if raidBuffs.BlessingOfKings { + BlessingOfKingsAura(u) } - // character.AddStats(stats.Stats{ - // stats.Armor: GetTristateValueFloat(raidBuffs.DevotionAura, 1205, 1807.5), - // }) - // } - - if raidBuffs.RetributionAura { - RetributionAura(&character.Unit) - } + // Stamina & Strength/Agility secondary grouping + applyStaminaBuffs(u, raidBuffs) - if len(character.Env.Raid.AllPlayerUnits)-character.Env.Raid.NumTargetDummies == 1 { + registerManaTideTotemCD(agent, raidBuffs.ManaTideTotemCount) + // Individual cooldowns and major buffs + if len(char.Env.Raid.AllPlayerUnits)-char.Env.Raid.NumTargetDummies == 1 { + // Major Haste if raidBuffs.Bloodlust { registerBloodlustCD(agent, 2825) - } else if raidBuffs.Heroism { + } + if raidBuffs.Heroism { registerBloodlustCD(agent, 32182) - } else if raidBuffs.TimeWarp { - registerBloodlustCD(agent, 80353) } - - registerUnholyFrenzyCD(agent, individualBuffs.UnholyFrenzyCount) - registerTricksOfTheTradeCD(agent, individualBuffs.TricksOfTheTrade) - registerPowerInfusionCD(agent, individualBuffs.PowerInfusionCount) - registerManaTideTotemCD(agent, raidBuffs.ManaTideTotemCount) - registerInnervateCD(agent, individualBuffs.InnervateCount) - registerDivineGuardianCD(agent, individualBuffs.DivineGuardianCount) - registerHandOfSacrificeCD(agent, individualBuffs.HandOfSacrificeCount) - registerPainSuppressionCD(agent, individualBuffs.PainSuppressionCount) - registerGuardianSpiritCD(agent, individualBuffs.GuardianSpiritCount) - registerRallyingCryCD(agent, individualBuffs.RallyingCryCount) - registerShatteringThrowCD(agent, individualBuffs.ShatteringThrowCount) - - if individualBuffs.FocusMagic { - FocusMagicAura(nil, &character.Unit) + if raidBuffs.TimeWarp { + registerBloodlustCD(agent, 80353) } - if individualBuffs.DarkIntent && character.Unit.Type == PlayerUnit { - MakePermanent(DarkIntentAura(&character.Unit, character.Class == proto.Class_ClassWarlock)) - } + // Other individual CDs + registerUnholyFrenzyCD(agent, individual.UnholyFrenzyCount) + registerTricksOfTheTradeCD(agent, individual.TricksOfTheTrade) + registerHandOfSacrificeCD(agent, individual.HandOfSacrificeCount) + registerPainSuppressionCD(agent, individual.PainSuppressionCount) + registerGuardianSpiritCD(agent, individual.GuardianSpiritCount) + registerRallyingCryCD(agent, individual.RallyingCryCount) + registerShatteringThrowCD(agent, individual.ShatteringThrowCount) } } -func DarkIntentAura(unit *Unit, isWarlock bool) *Aura { - var dotDmgEffect *ExclusiveEffect - procAura := unit.RegisterAura(Aura{ - Label: "Dark Intent Proc", - ActionID: ActionID{SpellID: 85759}, - Duration: 7 * time.Second, - MaxStacks: 3, - OnStacksChange: func(aura *Aura, sim *Simulation, oldStacks, newStacks int32) { - dotDmgEffect.SetPriority(sim, TernaryFloat64(isWarlock, 0.03, 0.01)*float64(newStacks)) - }, - }) - dotDmgEffect = procAura.NewExclusiveEffect("DarkIntent", false, ExclusiveEffect{ - Priority: 0, - OnGain: func(ee *ExclusiveEffect, s *Simulation) { - ee.Aura.Unit.PseudoStats.DotDamageMultiplierAdditive += ee.Priority - }, - OnExpire: func(ee *ExclusiveEffect, s *Simulation) { - ee.Aura.Unit.PseudoStats.DotDamageMultiplierAdditive -= ee.Priority - }, - }) - - // proc this based on the uptime configuration - // We assume lock precasts dot so first tick might happen after 2 seconds already - ApplyFixedUptimeAura(procAura, unit.DarkIntentUptimePercent, time.Second*2, time.Second*2) - - // var periodicHandler OnPeriodicDamage - // if selfBuff { - // periodicHandler = func(_ *Aura, sim *Simulation, spell *Spell, result *SpellResult) { - // if result.Outcome.Matches(OutcomeCrit) && spell.SchoolIndex > stats.SchoolIndexPhysical { - // procAura.Activate(sim) - // procAura.AddStack(sim) - // } - // } - // } - - return unit.RegisterAura(Aura{ - Label: "Dark Intent", - ActionID: ActionID{SpellID: 85767}, - OnGain: func(aura *Aura, sim *Simulation) { - aura.Unit.MultiplyCastSpeed(1.03) - aura.Unit.MultiplyAttackSpeed(sim, 1.03) - }, - OnExpire: func(aura *Aura, sim *Simulation) { - aura.Unit.MultiplyCastSpeed(1 / 1.03) - aura.Unit.MultiplyAttackSpeed(sim, 1/1.03) - }, - // OnPeriodicDamageDealt: periodicHandler, - BuildPhase: CharacterBuildPhaseBuffs, - }) -} - -func StoneskinTotem(unit *Unit) *Aura { - return makeExclusiveBuff(unit, BuffConfig{ - "Stoneskin Totem", - ActionID{SpellID: 8071}, - []StatConfig{ - {stats.Armor, 4075, false}, - }, - }) -} - -func DevotionAura(unit *Unit) *Aura { - return makeExclusiveBuff(unit, BuffConfig{ - "Devotion Aura", - ActionID{SpellID: 465}, - []StatConfig{ - {stats.Armor, 4075, false}, - }, - }) -} +/////////////////////////////////////////////////////////////////////////// +// Strength, Agility, Intellect 5% +/////////////////////////////////////////////////////////////////////////// func BlessingOfKingsAura(unit *Unit) *Aura { return makeExclusiveAllStatPercentBuff(unit, "Blessing of Kings", ActionID{SpellID: 20217}, 1.05) @@ -396,23 +227,6 @@ func BlessingOfKingsAura(unit *Unit) *Aura { func MarkOfTheWildAura(unit *Unit) *Aura { aura := makeExclusiveAllStatPercentBuff(unit, "Mark of the Wild", ActionID{SpellID: 1126}, 1.05) - registerExlusiveEffects(aura, []StatConfig{ - {stats.FireResistance, 97, false}, - {stats.FrostResistance, 97, false}, - {stats.ShadowResistance, 97, false}, - {stats.NatureResistance, 97, false}, - }) - return aura -} - -func DrumsOfTheBurningWildAura(unit *Unit) *Aura { - aura := makeExclusiveAllStatPercentBuff(unit, "Drums of the burning Wild", ActionID{ItemID: 63140}, 1.04) - registerExlusiveEffects(aura, []StatConfig{ - {stats.FireResistance, 78, false}, - {stats.FrostResistance, 78, false}, - {stats.ShadowResistance, 78, false}, - {stats.NatureResistance, 78, false}, - }) return aura } @@ -420,60 +234,8 @@ func LegacyOfTheEmperorAura(unit *Unit) *Aura { return makeExclusiveAllStatPercentBuff(unit, "Legacy of the Emperor", ActionID{SpellID: 115921}, 1.05) } -/////////////////////////////////////////////////////////////////////////// -// Resistances -/////////////////////////////////////////////////////////////////////////// - -// https://www.wowhead.com/mop-classic/item=63140/drums-of-the-burning-wild -// https://www.wowhead.com/mop-classic/spell=1126/mark-of-the-wild -// https://www.wowhead.com/mop-classic/spell=20217/blessing-of-kings -// https://www.wowhead.com/mop-classic/spell=8184/elemental-resistance-totem -// https://www.wowhead.com/mop-classic/spell=19891/resistance-aura -// https://www.wowhead.com/mop-classic/spell=20043/aspect-of-the-wild -// https://www.wowhead.com/mop-classic/spell=27683/shadow-protection - -func ElementalResistanceTotemAura(unit *Unit) *Aura { - return makeExclusiveBuff(unit, BuffConfig{ - "Elemental Resistance Totem", - ActionID{SpellID: 8184}, - []StatConfig{ - {stats.FireResistance, 195, false}, - {stats.FrostResistance, 195, false}, - {stats.NatureResistance, 195, false}, - }, - }) -} - -func ResistanceAura(unit *Unit) *Aura { - return makeExclusiveBuff(unit, BuffConfig{ - "Resistance Aura", - ActionID{SpellID: 19891}, - []StatConfig{ - {stats.FireResistance, 195, false}, - {stats.FrostResistance, 195, false}, - {stats.ShadowResistance, 195, false}, - }, - }) -} - -func ShadowProtectionAura(unit *Unit) *Aura { - return makeExclusiveBuff(unit, BuffConfig{ - "Shadow Protection", - ActionID{SpellID: 27683}, - []StatConfig{ - {stats.ShadowResistance, 195, false}, - }, - }) -} - -func AspectOfTheWildAura(unit *Unit) *Aura { - return makeExclusiveBuff(unit, BuffConfig{ - "Aspect of the Wild", - ActionID{SpellID: 20043}, - []StatConfig{ - {stats.NatureResistance, 195, false}, - }, - }) +func EmbraceOfTheShaleSpiderAura(u *Unit) *Aura { + return makeExclusiveAllStatPercentBuff(u, "Embrace of the Shale Spider", ActionID{SpellID: 90363}, 1.05) } /////////////////////////////////////////////////////////////////////////// @@ -486,87 +248,78 @@ func PowerWordFortitudeAura(unit *Unit) *Aura { "Power Word: Fortitude", ActionID{SpellID: 21562}, []StatConfig{ - {stats.Stamina, 585.0, false}, + {stats.Stamina, 1.1, true}, }, }) } -// https://www.wowhead.com/mop-classic/spell=6307/blood-pact -func BloodPactAura(unit *Unit) *Aura { - return makeExclusiveBuff(unit, BuffConfig{ - "Blood Pact", - ActionID{SpellID: 6307}, - []StatConfig{ - {stats.Stamina, 585.0, false}, - }, - }) +func QirajiFortitudeAura(u *Unit) *Aura { + return makeExclusiveBuff(u, BuffConfig{"Qiraji Fortitude", ActionID{SpellID: 90364}, []StatConfig{{stats.Stamina, 1.1, true}}}) } - -// https://www.wowhead.com/mop-classic/spell=469/commanding-shout -func CommandingShoutAura(unit *Unit, asExternal bool, withGlyph bool) *Aura { +func CommandingShoutAura(unit *Unit, asExternal bool) *Aura { baseAura := makeExclusiveBuff(unit, BuffConfig{ "Commanding Shout", ActionID{SpellID: 469}, []StatConfig{ - {stats.Stamina, 585.0, false}, - }, - }) - + {stats.Stamina, 1.1, true}, + }}) if asExternal { return baseAura } baseAura.OnReset = nil - baseAura.Duration = TernaryDuration(withGlyph, time.Minute*4, time.Minute*2) + baseAura.Duration = time.Minute * 5 return baseAura } - -func applyStaminaBuffs(unit *Unit, raidBuffs *proto.RaidBuffs) { +func applyStaminaBuffs(u *Unit, raidBuffs *proto.RaidBuffs) { + // +10% Stamina buffs if raidBuffs.PowerWordFortitude { - PowerWordFortitudeAura(unit) + PowerWordFortitudeAura(u) + } + if raidBuffs.QirajiFortitude { + QirajiFortitudeAura(u) } - if raidBuffs.CommandingShout { - CommandingShoutAura(unit, true, false) + CommandingShoutAura(u, true) } +} - if raidBuffs.BloodPact { - BloodPactAura(unit) - } +//////// 3000 Mastery Rating + +func RoarOfCourageAura(u *Unit) *Aura { + return makeExclusiveBuff(u, BuffConfig{"Roar of Courage", ActionID{SpellID: 93435}, []StatConfig{{stats.MasteryRating, 3000, false}}}) +} +func SpiritBeastBlessingAura(u *Unit) *Aura { + return makeExclusiveBuff(u, BuffConfig{"Spirit Beast Blessing", ActionID{SpellID: 128997}, []StatConfig{{stats.MasteryRating, 3000, false}}}) +} +func BlessingOfMightAura(u *Unit) *Aura { + return makeExclusiveBuff(u, BuffConfig{"Blessing of Might", ActionID{SpellID: 19740}, []StatConfig{{stats.MasteryRating, 3000, false}}}) +} +func GraceOfAirAura(u *Unit) *Aura { + return makeExclusiveBuff(u, BuffConfig{"Grace of Air", ActionID{SpellID: 116956}, []StatConfig{{stats.MasteryRating, 3000, false}}}) } /////////////////////////////////////////////////////////////////////////// -// Strength and Agility +// Attack Power /////////////////////////////////////////////////////////////////////////// -// https://www.wowhead.com/mop-classic/spell=8075/strength-of-earth-totem -func StrengthOfEarthTotemAura(unit *Unit) *Aura { - return makeExclusiveBuff(unit, BuffConfig{ - "Strength of Earth Totem", - ActionID{SpellID: 8075}, - []StatConfig{ - {stats.Agility, 549.0, false}, - {stats.Strength, 549.0, false}, - }}) -} -func RoarOfCourageAura(unit *Unit) *Aura { +func TrueShotAura(unit *Unit) *Aura { return makeExclusiveBuff(unit, BuffConfig{ - "Roar of Courage", - ActionID{SpellID: 93435}, + "Trueshot Aura", + ActionID{SpellID: 19506}, []StatConfig{ - {stats.Agility, 549.0, false}, - {stats.Strength, 549.0, false}, + {stats.AttackPower, 1.1, true}, + {stats.RangedAttackPower, 1.1, true}, }}) } -// https://www.wowhead.com/mop-classic/spell=57330/horn-of-winter -func HornOfWinterAura(unit *Unit, asExternal bool, withGlyph bool) *Aura { +func HornOfWinterAura(unit *Unit, asExternal bool) *Aura { baseAura := makeExclusiveBuff(unit, BuffConfig{ "Horn of Winter", ActionID{SpellID: 57330}, []StatConfig{ - {stats.Agility, 549.0, false}, - {stats.Strength, 549.0, false}, + {stats.AttackPower, 1.1, true}, + {stats.RangedAttackPower, 1.1, true}, }}) if asExternal { @@ -574,18 +327,17 @@ func HornOfWinterAura(unit *Unit, asExternal bool, withGlyph bool) *Aura { } baseAura.OnReset = nil - baseAura.Duration = TernaryDuration(withGlyph, time.Minute*3, time.Minute*2) + baseAura.Duration = time.Minute * 5 return baseAura } -// https://www.wowhead.com/mop-classic/spell=6673/battle-shout -func BattleShoutAura(unit *Unit, asExternal bool, withGlyph bool) *Aura { +func BattleShoutAura(unit *Unit, asExternal bool) *Aura { baseAura := makeExclusiveBuff(unit, BuffConfig{ "Battle Shout", ActionID{SpellID: 6673}, []StatConfig{ - {stats.Agility, 549.0, false}, - {stats.Strength, 549.0, false}, + {stats.AttackPower, 1.1, true}, + {stats.RangedAttackPower, 1.1, true}, }}) if asExternal { @@ -593,113 +345,10 @@ func BattleShoutAura(unit *Unit, asExternal bool, withGlyph bool) *Aura { } baseAura.OnReset = nil - baseAura.Duration = TernaryDuration(withGlyph, time.Minute*4, time.Minute*2) + baseAura.Duration = time.Minute * 5 return baseAura } -func applyStrengthAgilityBuffs(unit *Unit, raidBuffs *proto.RaidBuffs) { - if raidBuffs.StrengthOfEarthTotem { - MakePermanent(StrengthOfEarthTotemAura(unit)) - } - - if raidBuffs.HornOfWinter { - MakePermanent(HornOfWinterAura(unit, true, false)) - } - - if raidBuffs.BattleShout { - MakePermanent(BattleShoutAura(unit, true, false)) - } -} - -/////////////////////////////////////////////////////////////////////////// -// Attack Power -/////////////////////////////////////////////////////////////////////////// - -// https://www.wowhead.com/mop-classic/spell=30808/unleashed-rage -// https://www.wowhead.com/mop-classic/spell=19506/trueshot-aura -// https://www.wowhead.com/mop-classic/spell=53138/abominations-might -// https://www.wowhead.com/mop-classic/spell=19740/blessing-of-might - -func UnleashedRageAura(unit *Unit) *Aura { - return makeExclusiveBuff(unit, BuffConfig{ - "Unleashed Rage", - ActionID{SpellID: 30808}, - []StatConfig{ - {stats.AttackPower, 1.2, true}, - {stats.RangedAttackPower, 1.1, true}, - }}) -} - -func TrueShotAura(unit *Unit) *Aura { - return makeExclusiveBuff(unit, BuffConfig{ - "True Shot Aura", - ActionID{SpellID: 19506}, - []StatConfig{ - {stats.AttackPower, 1.2, true}, - {stats.RangedAttackPower, 1.1, true}, - }}) -} - -func AbominationsMightAura(unit *Unit) *Aura { - return makeExclusiveBuff(unit, BuffConfig{ - "Abominations Might", - ActionID{SpellID: 53138}, - []StatConfig{ - {stats.AttackPower, 1.2, true}, - {stats.RangedAttackPower, 1.1, true}, - }}) -} - -func BlessingOfMightAura(unit *Unit) *Aura { - return makeExclusiveBuff(unit, BuffConfig{ - "Blessing of Might", - ActionID{SpellID: 19740}, - []StatConfig{ - {stats.AttackPower, 1.2, true}, - {stats.RangedAttackPower, 1.1, true}, - {stats.MP5, 326, false}, - }}) -} - -/////////////////////////////////////////////////////////////////////////// -// Mp5 -/////////////////////////////////////////////////////////////////////////// - -func FelIntelligence(unit *Unit) *Aura { - if !unit.HasManaBar() { - return nil - } - return makeExclusiveBuff(unit, BuffConfig{ - "Fel Intelligence", - ActionID{SpellID: 54424}, - []StatConfig{ - {stats.Mana, 2126, false}, - {stats.MP5, 326, false}, - }}) -} - -func ArcaneBrilliance(unit *Unit) *Aura { - if !unit.HasManaBar() { - return nil - } - return makeExclusiveBuff(unit, BuffConfig{ - "Arcane Brilliance", - ActionID{SpellID: 1459}, - []StatConfig{ - {stats.Mana, 2126, false}, - {stats.SpellPower, 1.06, true}, - }}) -} - -func ManaSpringTotem(unit *Unit) *Aura { - return makeExclusiveBuff(unit, BuffConfig{ - "Mana Spring Totem", - ActionID{SpellID: 5675}, - []StatConfig{ - {stats.MP5, 326, false}, - }}) -} - // ///////////////////////////////////////////////////////////////////////// // // Melee Haste @@ -715,35 +364,30 @@ func registerExclusiveMeleeHaste(aura *Aura, value float64) { }, }) } - -func WindfuryTotem(unit *Unit) *Aura { - baseAura := makeExclusiveBuff(unit, BuffConfig{ - "Windfury Totem", - ActionID{SpellID: 8512}, - []StatConfig{}}) - - registerExclusiveMeleeHaste(baseAura, 1.1) - return baseAura +func UnholyAura(u *Unit) *Aura { + aura := makeExclusiveBuff(u, BuffConfig{"Unholy Aura", ActionID{SpellID: 55610}, nil}) + registerExclusiveMeleeHaste(aura, 0.10) + return aura } - -func IcyTalons(unit *Unit) *Aura { - baseAura := makeExclusiveBuff(unit, BuffConfig{ - "Icy Talons", - ActionID{SpellID: 55610}, - []StatConfig{}}) - - registerExclusiveMeleeHaste(baseAura, 1.1) - return baseAura +func CacklingHowlAura(u *Unit) *Aura { + aura := makeExclusiveBuff(u, BuffConfig{"Cackling Howl", ActionID{SpellID: 128432}, nil}) + registerExclusiveMeleeHaste(aura, 0.10) + return aura } - -func HuntingParty(unit *Unit) *Aura { - baseAura := makeExclusiveBuff(unit, BuffConfig{ - "Hunting Party", - ActionID{SpellID: 53290}, - []StatConfig{}}) - - registerExclusiveMeleeHaste(baseAura, 1.1) - return baseAura +func SerpentsSwiftnessAura(u *Unit) *Aura { + aura := makeExclusiveBuff(u, BuffConfig{"Serpent's Swiftness", ActionID{SpellID: 128433}, nil}) + registerExclusiveMeleeHaste(aura, 0.10) + return aura +} +func SwiftbladesCunningAura(u *Unit) *Aura { + aura := makeExclusiveBuff(u, BuffConfig{"Swiftblade's Cunning", ActionID{SpellID: 113742}, nil}) + registerExclusiveMeleeHaste(aura, 0.10) + return aura +} +func UnleashedRageAura(u *Unit) *Aura { + aura := makeExclusiveBuff(u, BuffConfig{"Unleashed Rage", ActionID{SpellID: 30809}, nil}) + registerExclusiveMeleeHaste(aura, 0.10) + return aura } // ///////////////////////////////////////////////////////////////////////// @@ -764,42 +408,6 @@ func LeaderOfThePack(unit *Unit) *Aura { return baseAura } -func ElementalOath(unit *Unit) *Aura { - baseAura := makeExclusiveBuff(unit, BuffConfig{ - "Elemental Oath", - ActionID{SpellID: 51470}, - []StatConfig{ - {stats.PhysicalCritPercent, 5, false}, - {stats.SpellCritPercent, 5, false}, - }}) - - return baseAura -} - -func HonorAmongThieves(unit *Unit) *Aura { - baseAura := makeExclusiveBuff(unit, BuffConfig{ - "Honor Among Thieves", - ActionID{SpellID: 51701}, - []StatConfig{ - {stats.PhysicalCritPercent, 5, false}, - {stats.SpellCritPercent, 5, false}, - }}) - - return baseAura -} - -func Rampage(unit *Unit) *Aura { - baseAura := makeExclusiveBuff(unit, BuffConfig{ - "Rampage", - ActionID{SpellID: 29801}, - []StatConfig{ - {stats.PhysicalCritPercent, 5, false}, - {stats.SpellCritPercent, 5, false}, - }}) - - return baseAura -} - func TerrifyingRoar(unit *Unit) *Aura { baseAura := makeExclusiveBuff(unit, BuffConfig{ "Terrifying Roar", @@ -858,29 +466,27 @@ func registerExclusiveSpellHaste(aura *Aura, spellHastePercent float64) { func MoonkinAura(unit *Unit) *Aura { aura := makeExclusiveBuff(unit, BuffConfig{ "Moonkin Aura", - ActionID{SpellID: 24858}, + ActionID{SpellID: 24907}, []StatConfig{}}) registerExclusiveSpellHaste(aura, 0.05) return aura } -func WrathOfAirAura(unit *Unit) *Aura { - aura := makeExclusiveBuff(unit, BuffConfig{ - "Wrath of Air", - ActionID{SpellID: 3738}, - []StatConfig{}}) - +func MindQuickeningAura(u *Unit) *Aura { + aura := makeExclusiveBuff(u, BuffConfig{"Mind Quickening", ActionID{SpellID: 49868}, nil}) registerExclusiveSpellHaste(aura, 0.05) return aura } -func ShadowFormAura(unit *Unit) *Aura { - aura := makeExclusiveBuff(unit, BuffConfig{ - "Shadow Form", - ActionID{SpellID: 15473}, - []StatConfig{}}) +func ShadowFormAura(u *Unit) *Aura { + aura := makeExclusiveBuff(u, BuffConfig{"Shadow Form", ActionID{SpellID: 15473}, nil}) + registerExclusiveSpellHaste(aura, 0.05) + return aura +} +func ElementalOath(u *Unit) *Aura { + aura := makeExclusiveBuff(u, BuffConfig{"Elemental Oath", ActionID{SpellID: 51470}, nil}) registerExclusiveSpellHaste(aura, 0.05) return aura } @@ -890,66 +496,27 @@ func ShadowFormAura(unit *Unit) *Aura { // Spell Power // // ///////////////////////////////////////////////////////////////////////// -func FlametongueTotem(unit *Unit) *Aura { - return makeExclusiveBuff(unit, BuffConfig{ - "Flametongue Totem", - ActionID{SpellID: 8227}, - []StatConfig{ - {stats.SpellPower, 1.06, true}, - }}) -} -func DemonicPact(unit *Unit) *Aura { - return makeExclusiveBuff(unit, BuffConfig{ - "Demonic Pact", - ActionID{SpellID: 53646}, +func StillWaterAura(u *Unit) *Aura { + return makeExclusiveBuff(u, BuffConfig{"Still Water", ActionID{SpellID: 126309}, []StatConfig{ - {stats.SpellPower, 1.1, true}, - }}) + {stats.SpellPower, 0.10, true}, + {stats.PhysicalCritPercent, 5, false}, + {stats.SpellCritPercent, 5, false}}}) } - -func TotemicWrath(unit *Unit) *Aura { - return makeExclusiveBuff(unit, BuffConfig{ - "Totemic Wrath", - ActionID{SpellID: 77746}, +func ArcaneBrilliance(u *Unit) *Aura { + // Mages: +10% Spell Power + return makeExclusiveBuff(u, BuffConfig{"Arcane Brilliance", ActionID{SpellID: 1459}, []StatConfig{ - {stats.SpellPower, 1.1, true}, - }}) -} - -// ///////////////////////////////////////////////////////////////////////// -// -// Damage Done% -// -// ///////////////////////////////////////////////////////////////////////// -func registerExclusiveDamageDone(aura *Aura, damageDoneMod float64) { - aura.NewExclusiveEffect("DamageDone%Buff", false, ExclusiveEffect{ - Priority: damageDoneMod, - OnGain: func(ee *ExclusiveEffect, sim *Simulation) { - ee.Aura.Unit.PseudoStats.DamageDealtMultiplier *= (1 + ee.Priority) - }, - OnExpire: func(ee *ExclusiveEffect, sim *Simulation) { - ee.Aura.Unit.PseudoStats.DamageDealtMultiplier /= (1 + ee.Priority) - }, - }) -} - -func ArcaneTactics(unit *Unit) *Aura { - aura := makeExclusiveBuff(unit, BuffConfig{"Arcane Tactics", ActionID{SpellID: 82930}, []StatConfig{}}) - registerExclusiveDamageDone(aura, 0.03) - return aura + {stats.SpellPower, 0.10, true}, + {stats.PhysicalCritPercent, 5, false}, + {stats.SpellCritPercent, 5, false}}}) } - -func FerociousInspiration(unit *Unit) *Aura { - aura := makeExclusiveBuff(unit, BuffConfig{"Ferocious Inspiration", ActionID{SpellID: 34460}, []StatConfig{}}) - registerExclusiveDamageDone(aura, 0.03) - return aura +func BurningWrathAura(u *Unit) *Aura { + return makeExclusiveBuff(u, BuffConfig{"Burning Wrath", ActionID{SpellID: 77747}, []StatConfig{{stats.SpellPower, 0.10, true}}}) } - -func Communion(unit *Unit) *Aura { - aura := makeExclusiveBuff(unit, BuffConfig{"Communion", ActionID{SpellID: 31876}, []StatConfig{}}) - registerExclusiveDamageDone(aura, 0.03) - return aura +func DarkIntentAura(u *Unit) *Aura { + return makeExclusiveBuff(u, BuffConfig{"Dark Intent", ActionID{SpellID: 109773}, []StatConfig{{stats.SpellPower, 0.10, true}, {stats.Stamina, 0.10, true}}}) } ///////////// @@ -962,81 +529,15 @@ func applyPetBuffEffects(petAgent PetAgent, raidBuffs *proto.RaidBuffs, partyBuf if petAgent.GetPet().IsGuardian() { return } - raidBuffs = googleProto.Clone(raidBuffs).(*proto.RaidBuffs) partyBuffs = googleProto.Clone(partyBuffs).(*proto.PartyBuffs) individualBuffs = googleProto.Clone(individualBuffs).(*proto.IndividualBuffs) - // Remove buffs that do not apply to pets - // Or those that will be applied from the player (BL) - raidBuffs.Bloodlust = false - raidBuffs.Heroism = false - raidBuffs.TimeWarp = false - // Stam - raidBuffs.PowerWordFortitude = false - raidBuffs.CommandingShout = false - raidBuffs.BloodPact = false // does apply to the imp itself, but not to any other pet - // Str/Agi - raidBuffs.StrengthOfEarthTotem = false - raidBuffs.HornOfWinter = false - raidBuffs.BattleShout = false - // Crit% - raidBuffs.LeaderOfThePack = false - raidBuffs.HonorAmongThieves = false - raidBuffs.ElementalOath = false - raidBuffs.Rampage = false - raidBuffs.TerrifyingRoar = false - raidBuffs.FuriousHowl = false - raidBuffs.LegacyOfTheWhiteTiger = false - // AP% - raidBuffs.TrueshotAura = false - raidBuffs.UnleashedRage = false - raidBuffs.AbominationsMight = false - raidBuffs.BlessingOfMight = false - // SP% - raidBuffs.ArcaneBrilliance = false - raidBuffs.DemonicPact = false - raidBuffs.TotemicWrath = false - raidBuffs.FlametongueTotem = false - // +5% Spell haste - raidBuffs.MoonkinForm = false - raidBuffs.ShadowForm = false - raidBuffs.WrathOfAirTotem = false - // Mana - raidBuffs.FelIntelligence = false // does apply to the fel hunter itself, but not to any other pet - // +Armor - raidBuffs.DevotionAura = false - raidBuffs.StoneskinTotem = false - // 10% Haste - // raidBuffs.HuntingParty = false - // raidBuffs.IcyTalons = false - // raidBuffs.WindfuryTotem = false - // +3% All Damage - raidBuffs.ArcaneTactics = false - raidBuffs.FerociousInspiration = false - raidBuffs.Communion = false - // +Spell Resistances - raidBuffs.ElementalResistanceTotem = false - raidBuffs.ResistanceAura = false - raidBuffs.ShadowProtection = false - raidBuffs.AspectOfTheWild = false - // +5% Base Stats and Spell Resistances - raidBuffs.MarkOfTheWild = false - raidBuffs.BlessingOfKings = false - raidBuffs.DrumsOfTheBurningWild = false - raidBuffs.LegacyOfTheEmperor = false - - individualBuffs.HymnOfHopeCount = 0 - individualBuffs.InnervateCount = 0 - individualBuffs.PowerInfusionCount = 0 - individualBuffs.DivineGuardianCount = 0 - individualBuffs.GuardianSpiritCount = 0 - individualBuffs.HandOfSacrificeCount = 0 - individualBuffs.PainSuppressionCount = 0 - individualBuffs.PowerInfusionCount = 0 - individualBuffs.TricksOfTheTrade = proto.TristateEffect_TristateEffectMissing - individualBuffs.UnholyFrenzyCount = 0 - individualBuffs.RallyingCryCount = 0 + //Todo: Only cancel the buffs that are supposed to be cancelled + // Check beta when pets are better implemented? + raidBuffs = &proto.RaidBuffs{} + partyBuffs = &proto.PartyBuffs{} + individualBuffs = &proto.IndividualBuffs{} if !petAgent.GetPet().enabledOnStart { // What do we do with permanent pets that are not enabled at start? @@ -1045,67 +546,6 @@ func applyPetBuffEffects(petAgent PetAgent, raidBuffs *proto.RaidBuffs, partyBuf applyBuffEffects(petAgent, raidBuffs, partyBuffs, individualBuffs) } -func InspirationAura(unit *Unit, points int32) *Aura { - multiplier := 1 - []float64{0, .03, .07, .10}[points] - - return unit.GetOrRegisterAura(Aura{ - Label: "Inspiration", - ActionID: ActionID{SpellID: 15357}, - Duration: time.Second * 15, - OnGain: func(aura *Aura, sim *Simulation) { - aura.Unit.PseudoStats.SchoolDamageTakenMultiplier[stats.SchoolIndexPhysical] *= multiplier - }, - OnExpire: func(aura *Aura, sim *Simulation) { - aura.Unit.PseudoStats.SchoolDamageTakenMultiplier[stats.SchoolIndexPhysical] /= multiplier - }, - }) -} - -func ApplyInspiration(unit *Unit, uptime float64) { - if uptime <= 0 { - return - } - uptime = min(1, uptime) - - inspirationAura := InspirationAura(unit, 3) - - ApplyFixedUptimeAura(inspirationAura, uptime, time.Millisecond*2500, 1) -} - -func RetributionAura(unit *Unit) *Aura { - actionID := ActionID{SpellID: 7294} - - baseDamage := 116.0 - - procSpell := unit.RegisterSpell(SpellConfig{ - ActionID: actionID, - SpellSchool: SpellSchoolHoly, - ProcMask: ProcMaskEmpty, - Flags: SpellFlagBinary, - - DamageMultiplier: 1, - ThreatMultiplier: 1, - - ApplyEffects: func(sim *Simulation, target *Unit, spell *Spell) { - spell.CalcAndDealDamage(sim, target, baseDamage, spell.OutcomeMagicHit) - }, - }) - - return unit.RegisterAura(Aura{ - Label: "Retribution Aura", - ActionID: actionID, - Duration: NeverExpires, - OnReset: func(aura *Aura, sim *Simulation) { - aura.Activate(sim) - }, - OnSpellHitTaken: func(aura *Aura, sim *Simulation, spell *Spell, result *SpellResult) { - if result.Landed() && spell.SpellSchool.Matches(SpellSchoolPhysical) { - procSpell.Cast(sim, spell.Unit) - } - }, - }) -} - // Used for approximating cooldowns applied by other players to you, such as // bloodlust, innervate, power infusion, etc. This is specifically for buffs // which can be consecutively applied multiple times to a single player. @@ -1220,8 +660,7 @@ func registerBloodlustCD(agent Agent, spellID int32) { Priority: CooldownPriorityBloodlust, Type: CooldownTypeDPS, ShouldActivate: func(sim *Simulation, character *Character) bool { - // Haste portion doesn't stack with Power Infusion, so prefer to wait. - return !character.HasActiveAuraWithTag(PowerInfusionAuraTag) && !character.HasActiveAura(SatedAuraLabel) + return !character.HasActiveAura(SatedAuraLabel) }, }) } @@ -1266,63 +705,6 @@ func BloodlustAura(character *Character, actionTag int32) *Aura { return aura } -var PowerInfusionActionID = ActionID{SpellID: 10060} -var PowerInfusionAuraTag = "PowerInfusion" - -const PowerInfusionDuration = time.Second * 15 -const PowerInfusionCD = time.Minute * 2 - -func registerPowerInfusionCD(agent Agent, numPowerInfusions int32) { - if numPowerInfusions == 0 { - return - } - - piAura := PowerInfusionAura(&agent.GetCharacter().Unit, -1) - - registerExternalConsecutiveCDApproximation( - agent, - externalConsecutiveCDApproximation{ - ActionID: PowerInfusionActionID.WithTag(-1), - AuraTag: PowerInfusionAuraTag, - CooldownPriority: CooldownPriorityDefault, - AuraDuration: PowerInfusionDuration, - AuraCD: PowerInfusionCD, - Type: CooldownTypeDPS, - - ShouldActivate: func(sim *Simulation, character *Character) bool { - // Haste portion doesn't stack with Bloodlust, so prefer to wait. - return !character.HasActiveAuraWithTag(BloodlustAuraTag) - }, - AddAura: func(sim *Simulation, character *Character) { piAura.Activate(sim) }, - }, - numPowerInfusions) -} - -func PowerInfusionAura(character *Unit, actionTag int32) *Aura { - actionID := ActionID{SpellID: 10060, Tag: actionTag} - aura := character.GetOrRegisterAura(Aura{ - Label: "PowerInfusion-" + actionID.String(), - Tag: PowerInfusionAuraTag, - ActionID: actionID, - Duration: PowerInfusionDuration, - }) - aura.NewExclusiveEffect("ManaCost", true, ExclusiveEffect{ - Priority: -20, - OnGain: func(ee *ExclusiveEffect, sim *Simulation) { - if ee.Aura.Unit.HasManaBar() { - ee.Aura.Unit.PseudoStats.SpellCostPercentModifier -= 20 - } - }, - OnExpire: func(ee *ExclusiveEffect, sim *Simulation) { - if ee.Aura.Unit.HasManaBar() { - ee.Aura.Unit.PseudoStats.SpellCostPercentModifier += 20 - } - }, - }) - multiplyCastSpeedEffect(aura, 1.2) - return aura -} - func multiplyCastSpeedEffect(aura *Aura, multiplier float64) *ExclusiveEffect { return aura.NewExclusiveEffect("MultiplyCastSpeed", false, ExclusiveEffect{ Priority: multiplier, @@ -1446,53 +828,6 @@ func RegisterPercentDamageModifierEffect(aura *Aura, percentDamageModifier float }) } -var DivineGuardianAuraTag = "DivineGuardian" - -const DivineGuardianDuration = time.Second * 6 -const DivineGuardianCD = time.Minute * 2 - -func registerDivineGuardianCD(agent Agent, numDivineGuardians int32) { - if numDivineGuardians == 0 { - return - } - - dgAura := DivineGuardianAura(agent.GetCharacter(), -1) - - registerExternalConsecutiveCDApproximation( - agent, - externalConsecutiveCDApproximation{ - ActionID: ActionID{SpellID: 70940, Tag: -1}, - AuraTag: DivineGuardianAuraTag, - CooldownPriority: CooldownPriorityLow, - AuraDuration: DivineGuardianDuration, - AuraCD: DivineGuardianCD, - Type: CooldownTypeSurvival, - - ShouldActivate: func(sim *Simulation, character *Character) bool { - return true - }, - AddAura: func(sim *Simulation, character *Character) { dgAura.Activate(sim) }, - }, - numDivineGuardians) -} - -func DivineGuardianAura(character *Character, actionTag int32) *Aura { - actionID := ActionID{SpellID: 53530, Tag: actionTag} - - return character.GetOrRegisterAura(Aura{ - Label: "DivineGuardian-" + actionID.String(), - Tag: DivineGuardianAuraTag, - ActionID: actionID, - Duration: DivineGuardianDuration, - OnGain: func(aura *Aura, sim *Simulation) { - character.PseudoStats.DamageTakenMultiplier *= 0.8 - }, - OnExpire: func(aura *Aura, sim *Simulation) { - character.PseudoStats.DamageTakenMultiplier /= 0.8 - }, - }) -} - var HandOfSacrificeAuraTag = "HandOfSacrifice" const HandOfSacrificeDuration = time.Millisecond * 10500 // subtract Divine Shield GCD @@ -1734,75 +1069,6 @@ func registerShatteringThrowCD(agent Agent, numShatteringThrows int32) { numShatteringThrows) } -var InnervateAuraTag = "Innervate" - -const InnervateDuration = time.Second * 10 -const InnervateCD = time.Minute * 3 - -func InnervateManaThreshold(character *Character) float64 { - if character.Class == proto.Class_ClassMage { - // Mages burn mana really fast so they need a higher threshold. - return character.MaxMana() * 0.7 - } else { - return character.MaxMana() * 0.45 - } -} - -func registerInnervateCD(agent Agent, numInnervates int32) { - if numInnervates == 0 { - return - } - - innervateThreshold := 0.0 - var innervateAura *Aura - - character := agent.GetCharacter() - character.Env.RegisterPostFinalizeEffect(func() { - innervateThreshold = InnervateManaThreshold(character) - innervateAura = InnervateAura(character, -1, 0.05) - }) - - registerExternalConsecutiveCDApproximation( - agent, - externalConsecutiveCDApproximation{ - ActionID: ActionID{SpellID: 29166, Tag: -1}, - AuraTag: InnervateAuraTag, - CooldownPriority: CooldownPriorityDefault, - AuraDuration: InnervateDuration, - AuraCD: InnervateCD, - Type: CooldownTypeMana, - ShouldActivate: func(sim *Simulation, character *Character) bool { - // Only cast innervate when very low on mana, to make sure all other mana CDs are prioritized. - return character.CurrentMana() <= innervateThreshold - }, - AddAura: func(sim *Simulation, character *Character) { - innervateAura.Activate(sim) - }, - }, - numInnervates) -} - -func InnervateAura(character *Character, actionTag int32, reg float64) *Aura { - actionID := ActionID{SpellID: 29166, Tag: actionTag} - manaMetrics := character.NewManaMetrics(actionID) - return character.GetOrRegisterAura(Aura{ - Label: "Innervate-" + actionID.String(), - Tag: InnervateAuraTag, - ActionID: actionID, - Duration: InnervateDuration, - OnGain: func(aura *Aura, sim *Simulation) { - manaPerTick := aura.Unit.MaxMana() * reg / 10.0 - StartPeriodicAction(sim, PeriodicActionOptions{ - Period: InnervateDuration / 10, - NumTicks: 10, - OnAction: func(sim *Simulation) { - character.AddMana(sim, manaPerTick, manaMetrics) - }, - }) - }, - }) -} - var ManaTideTotemActionID = ActionID{SpellID: 16190} var ManaTideTotemAuraTag = "ManaTideTotem" @@ -1845,7 +1111,6 @@ func registerManaTideTotemCD(agent Agent, numManaTideTotems int32) { numManaTideTotems) } -// TODO: Should this be a raid aura on every character available? func ManaTideTotemAura(character *Character, actionTag int32) *Aura { actionID := ManaTideTotemActionID.WithTag(actionTag) dep := character.NewDynamicMultiplyStat(stats.Spirit, 2) @@ -1862,168 +1127,3 @@ func ManaTideTotemAura(character *Character, actionTag int32) *Aura { }, }) } - -const ReplenishmentAuraDuration = time.Second * 15 - -// Creates the actual replenishment aura for a unit. -func replenishmentAura(unit *Unit, _ ActionID) *Aura { - if unit.ReplenishmentAura != nil { - return unit.ReplenishmentAura - } - - replenishmentDep := unit.NewDynamicStatDependency(stats.Mana, stats.MP5, 0.005) - - unit.ReplenishmentAura = unit.RegisterAura(Aura{ - Label: "Replenishment", - ActionID: ActionID{SpellID: 57669}, - Duration: ReplenishmentAuraDuration, - OnGain: func(aura *Aura, sim *Simulation) { - aura.Unit.EnableDynamicStatDep(sim, replenishmentDep) - }, - OnExpire: func(aura *Aura, sim *Simulation) { - aura.Unit.DisableDynamicStatDep(sim, replenishmentDep) - }, - }) - - return unit.ReplenishmentAura -} - -type ReplenishmentSource int - -// Returns a new aura whose activation will give the Replenishment buff to 10 party/raid members. -func (raid *Raid) NewReplenishmentSource(actionID ActionID) ReplenishmentSource { - newReplSource := ReplenishmentSource(len(raid.curReplenishmentUnits)) - raid.curReplenishmentUnits = append(raid.curReplenishmentUnits, []*Unit{}) - - if raid.replenishmentUnits != nil { - return newReplSource - } - - // Get the list of all eligible units (party/raid members + their pets, but no guardians). - var manaUsers []*Unit - for _, party := range raid.Parties { - for _, player := range party.Players { - character := player.GetCharacter() - if character.HasManaBar() { - manaUsers = append(manaUsers, &character.Unit) - } - } - for _, petAgent := range party.Pets { - pet := petAgent.GetPet() - if pet.HasManaBar() && !pet.IsGuardian() { - manaUsers = append(manaUsers, &pet.Unit) - } - } - } - raid.replenishmentUnits = manaUsers - - // Initialize replenishment aura for all applicable units. - for _, unit := range raid.replenishmentUnits { - replenishmentAura(unit, actionID) - } - - return newReplSource -} - -func (raid *Raid) resetReplenishment(_ *Simulation) { - raid.leftoverReplenishmentUnits = raid.replenishmentUnits - for i := 0; i < len(raid.curReplenishmentUnits); i++ { - raid.curReplenishmentUnits[i] = nil - } -} - -func (raid *Raid) ProcReplenishment(sim *Simulation, src ReplenishmentSource) { - if sim.GetRemainingDuration() <= 0 { - return - } - // If the raid is fully covered by one or more replenishment sources, we can - // skip the mana sorting. - if len(raid.curReplenishmentUnits)*10 >= len(raid.replenishmentUnits) { - if len(raid.curReplenishmentUnits[src]) == 0 { - if len(raid.leftoverReplenishmentUnits) > 10 { - raid.curReplenishmentUnits[src] = raid.leftoverReplenishmentUnits[:10] - raid.leftoverReplenishmentUnits = raid.leftoverReplenishmentUnits[10:] - } else { - raid.curReplenishmentUnits[src] = raid.leftoverReplenishmentUnits - raid.leftoverReplenishmentUnits = nil - } - } - for _, unit := range raid.curReplenishmentUnits[src] { - unit.ReplenishmentAura.Activate(sim) - } - return - } - - eligible := append(raid.curReplenishmentUnits[src], raid.leftoverReplenishmentUnits...) - slices.SortFunc(eligible, func(v1, v2 *Unit) int { - return cmp.Compare(v1.CurrentManaPercent(), v2.CurrentManaPercent()) - }) - raid.curReplenishmentUnits[src] = eligible[:10] - raid.leftoverReplenishmentUnits = eligible[10:] - for _, unit := range raid.curReplenishmentUnits[src] { - unit.ReplenishmentAura.Activate(sim) - } - for _, unit := range raid.leftoverReplenishmentUnits { - unit.ReplenishmentAura.Deactivate(sim) - } -} - -func FocusMagicAura(caster *Unit, target *Unit) (*Aura, *Aura) { - actionID := ActionID{SpellID: 54648} - - var casterAura *Aura - var onHitCallback OnSpellHit - casterIndex := -1 - if caster != nil { - casterIndex = int(caster.Index) - casterAura = caster.GetOrRegisterAura(Aura{ - Label: "Focus Magic", - ActionID: actionID, - Duration: time.Second * 10, - OnGain: func(aura *Aura, sim *Simulation) { - aura.Unit.AddStatsDynamic(sim, stats.Stats{ - stats.SpellCritPercent: 3, - }) - }, - OnExpire: func(aura *Aura, sim *Simulation) { - aura.Unit.AddStatsDynamic(sim, stats.Stats{ - stats.SpellCritPercent: -3, - }) - }, - }) - - onHitCallback = func(_ *Aura, sim *Simulation, _ *Spell, result *SpellResult) { - if result.DidCrit() { - casterAura.Activate(sim) - } - } - } - - var aura *Aura - if target != nil { - aura = target.GetOrRegisterAura(Aura{ - Label: "Focus Magic" + strconv.Itoa(casterIndex), - ActionID: actionID.WithTag(int32(casterIndex)), - Duration: NeverExpires, - BuildPhase: CharacterBuildPhaseBuffs, - OnReset: func(aura *Aura, sim *Simulation) { - aura.Activate(sim) - }, - OnSpellHitDealt: onHitCallback, - }) - aura.NewExclusiveEffect("FocusMagic", true, ExclusiveEffect{ - OnGain: func(ee *ExclusiveEffect, sim *Simulation) { - ee.Aura.Unit.AddStatsDynamic(sim, stats.Stats{ - stats.SpellCritPercent: 3, - }) - }, - OnExpire: func(ee *ExclusiveEffect, sim *Simulation) { - ee.Aura.Unit.AddStatsDynamic(sim, stats.Stats{ - stats.SpellCritPercent: -3, - }) - }, - }) - } - - return casterAura, aura -} diff --git a/sim/core/character.go b/sim/core/character.go index 9010943aa3..83f99899d7 100644 --- a/sim/core/character.go +++ b/sim/core/character.go @@ -106,7 +106,6 @@ func NewCharacter(party *Party, partyIndex int, player *proto.Player) Character ReactionTime: time.Duration(max(player.ReactionTimeMs, 10)) * time.Millisecond, ChannelClipDelay: max(0, time.Duration(player.ChannelClipDelayMs)*time.Millisecond), - DarkIntentUptimePercent: max(0, min(1.0, player.DarkIntentUptime/100.0)), StartDistanceFromTarget: player.DistanceFromTarget, }, diff --git a/sim/core/debuffs.go b/sim/core/debuffs.go index 5b47cf2c5b..5d8b36ba21 100644 --- a/sim/core/debuffs.go +++ b/sim/core/debuffs.go @@ -1,402 +1,191 @@ package core import ( - "strconv" "time" "github.com/wowsims/mop/sim/core/proto" "github.com/wowsims/mop/sim/core/stats" ) +// applyRaidDebuffEffects applies all raid-level debuffs based on the provided Debuffs proto. func applyDebuffEffects(target *Unit, targetIdx int, debuffs *proto.Debuffs, raid *proto.Raid) { - // +8% Spell DMG - if debuffs.CurseOfElements && targetIdx == 0 { - MakePermanent(CurseOfElementsAura(target)) + // –10% Physical damage dealt for 30s + if debuffs.WeakenedBlows { + MakePermanent(WeakenedBlowsAura(target)) } - if debuffs.EbonPlaguebringer { - MakePermanent(EbonPlaguebringerAura(nil, target, 2, 3)) + // +4% Physical damage taken for 30s + if debuffs.PhysicalVulnerability { + MakePermanent(PhysVulnerabilityAura(target)) } - if debuffs.EarthAndMoon && targetIdx == 0 { - MakePermanent(EarthAndMoonAura(target)) - } + // –4% Armor for 30s, stacks 3 times + if debuffs.WeakenedArmor { + aura := MakePermanent(WeakenedArmorAura(target)) - if debuffs.MasterPoisoner && targetIdx == 0 { - MakePermanent(MasterPoisonerDebuff(target)) + aura.ApplyOnGain(func(aura *Aura, sim *Simulation) { + aura.SetStacks(sim, 3) + }) } - if debuffs.FireBreath && targetIdx == 0 { + // Spell‐damage‐taken sources + if debuffs.FireBreath { MakePermanent(FireBreathDebuff(target)) } - - if debuffs.LightningBreath && targetIdx == 0 { - MakePermanent(LightningBreath(target)) - } - - // +4% Phsyical Damage - if debuffs.BloodFrenzy && targetIdx < 4 { - MakePermanent(BloodFrenzyAura(target, 2)) - MakePermanent(TraumaAura(target, 2)) - } - - if debuffs.SavageCombat { - MakePermanent(SavageCombatAura(target, 2)) - } - - if debuffs.FrostFever || debuffs.BrittleBones { - MakePermanent(FrostFeverAura(target, TernaryInt32(debuffs.BrittleBones, 2, 0))) - } - - if debuffs.AcidSpit && targetIdx == 0 { - MakePermanent(AcidSpitAura(target)) - } - - // Bleed Damage - // Blood Frenzy @4% Physical Damage - if debuffs.Mangle && targetIdx == 0 { - MakePermanent(MangleAura(target)) - } - - if debuffs.Hemorrhage && targetIdx == 0 { - MakePermanent(HemorrhageAura(target)) - } - - if debuffs.Stampede && targetIdx == 0 { - MakePermanent(StampedeAura(target)) - } - - // Spell Crit - if debuffs.CriticalMass && targetIdx == 0 { - MakePermanent(CriticalMassAura(target)) - } - - if debuffs.ShadowAndFlame && targetIdx == 0 { - MakePermanent(CriticalMassAura(target)) - } - - if debuffs.ExposeArmor && targetIdx == 0 { - aura := ExposeArmorAura(target, false) - ScheduledMajorArmorAura(aura, PeriodicActionOptions{ - Period: time.Second * 3, - NumTicks: 1, - OnAction: func(sim *Simulation) { - aura.Activate(sim) - }, - }, raid) - } - - if debuffs.SunderArmor && targetIdx == 0 { - aura := SunderArmorAura(target) - ScheduledMajorArmorAura(aura, PeriodicActionOptions{ - Period: time.Millisecond * 1500, - NumTicks: 3, - TickImmediately: true, - Priority: ActionPriorityDOT, // High prio so it comes before actual warrior sunders. - OnAction: func(sim *Simulation) { - aura.Activate(sim) - if aura.IsActive() { - aura.AddStack(sim) - } - }, - }, raid) - } - - if debuffs.CorrosiveSpit && targetIdx == 0 { - aura := CorrosiveSpitAura(target) - ScheduledMajorArmorAura(aura, PeriodicActionOptions{ - Period: time.Second * 10, - NumTicks: 3, - TickImmediately: true, - Priority: ActionPriorityDOT, - OnAction: func(sim *Simulation) { - aura.Activate(sim) - if aura.IsActive() { - aura.AddStack(sim) - } - }, - }, raid) - } - - if debuffs.FaerieFire && targetIdx == 0 { - aura := FaerieFireAura(target) - ScheduledMajorArmorAura(aura, PeriodicActionOptions{ - Period: time.Millisecond * 1500, - NumTicks: 1, - Priority: ActionPriorityDOT, - OnAction: func(sim *Simulation) { - aura.Activate(sim) - if aura.IsActive() { - aura.SetStacks(sim, 3) - } - }, - }, raid) + if debuffs.LightningBreath { + MakePermanent(LightningBreathDebuff(target)) } - - // -10% Physical Damage - if debuffs.CurseOfWeakness { - MakePermanent(CurseOfWeaknessAura(target)) + if debuffs.MasterPoisoner { + MakePermanent(MasterPoisonerDebuff(target)) } - - if debuffs.DemoralizingRoar { - MakePermanent(DemoralizingRoarAura(target)) + if debuffs.CurseOfElements { + MakePermanent(CurseOfElementsAura(target)) } - if debuffs.DemoralizingShout { - MakePermanent(DemoralizingShoutAura(target, false)) + // Casting‐speed‐reduction sources + if debuffs.NecroticStrike { + MakePermanent(NecroticStrikeAura(target)) } - - if debuffs.DemoralizingScreech { - MakePermanent(DemoralizingScreechAura(target)) + if debuffs.LavaBreath { + MakePermanent(LavaBreathAura(target)) } - - if debuffs.Vindication { - MakePermanent(VindicationAura(target)) + if debuffs.SporeCloud { + MakePermanent(SporeCloud(target)) } - - if debuffs.ScarletFever { - MakePermanent(ScarletFeverAura(target, 2, 0)) + if debuffs.Slow { + MakePermanent(SlowAura(target)) } - - // Atk spd reduction - if debuffs.ThunderClap { - MakePermanent(ThunderClapAura(target)) + if debuffs.MindNumbingPoison { + MakePermanent(MindNumbingPoisonAura(target)) } - - if debuffs.InfectedWounds && targetIdx == 0 { - MakePermanent(InfectedWoundsAura(target, 2)) - } - - if debuffs.JudgementsOfTheJust && targetIdx == 0 { - MakePermanent(JudgementsOfTheJustAura(target, 2)) - } - - if debuffs.DustCloud && targetIdx == 0 { - MakePermanent(DustCloud(target)) + if debuffs.CurseOfEnfeeblement { + MakePermanent(CurseOfEnfeeblement(target)) } } -func ScheduledMajorArmorAura(aura *Aura, options PeriodicActionOptions, raid *proto.Raid) { - aura.OnReset = func(aura *Aura, sim *Simulation) { - aura.Duration = NeverExpires - StartPeriodicAction(sim, options) - } +// –10% Physical damage dealt +func WeakenedBlowsAura(target *Unit) *Aura { + aura := target.GetOrRegisterAura(Aura{ + Label: "Weakened Blows", + ActionID: ActionID{SpellID: 115798}, + Duration: time.Second * 30, + }) + PhysDamageReductionEffect(aura, 0.1) + return aura } -func CurseOfElementsAura(target *Unit) *Aura { - aura := Aura{ - Label: "Curse of Elements", - ActionID: ActionID{SpellID: 1490}, - Duration: time.Minute * 5, - OnGain: func(aura *Aura, sim *Simulation) { - aura.Unit.AddStatsDynamic(sim, stats.Stats{stats.ArcaneResistance: -215, stats.FireResistance: -215, stats.FrostResistance: -215, stats.ShadowResistance: -215, stats.NatureResistance: -215}) - }, - OnExpire: func(aura *Aura, sim *Simulation) { - aura.Unit.AddStatsDynamic(sim, stats.Stats{stats.ArcaneResistance: 215, stats.FireResistance: 215, stats.FrostResistance: 215, stats.ShadowResistance: 215, stats.NatureResistance: 215}) - }, - } - return spellDamageEffectAura(aura, target, 1.08) +// +4% Physical damage taken +func PhysVulnerabilityAura(target *Unit) *Aura { + aura := target.GetOrRegisterAura(Aura{ + Label: "Physical Vulnerability", + ActionID: ActionID{SpellID: 81326}, + Duration: time.Second * 30, + }) + PhysDamageTakenEffect(aura, 1.04) + return aura } -func EarthAndMoonAura(target *Unit) *Aura { - aura := Aura{ - Label: "Earth And Moon", - ActionID: ActionID{SpellID: 60433}, - Duration: time.Second * 12, - } - return spellDamageEffectAura(aura, target, 1.08) +// –4% Armor stacks 3 +func WeakenedArmorAura(target *Unit) *Aura { + var effect *ExclusiveEffect + aura := target.GetOrRegisterAura(Aura{ + Label: "Weakened Armor", + ActionID: ActionID{SpellID: 113746}, + Duration: time.Second * 30, + MaxStacks: 3, + OnStacksChange: func(_ *Aura, sim *Simulation, oldStacks int32, newStacks int32) { + effect.SetPriority(sim, 0.04*float64(newStacks)) + }, + }) + effect = registerMajorArpEffect(aura, 0) + return aura } -func MasterPoisonerDebuff(target *Unit) *Aura { - aura := Aura{ - Label: "Master Poisoner", - ActionID: ActionID{SpellID: 58410}, - Duration: time.Second * 15, - } - return spellDamageEffectAura(aura, target, 1.08) +func MortalWoundsAura(target *Unit) *Aura { + return majorHealingReductionAura(target, "Mortal Wounds", 115804, 0.25) } +// Spell‐damage‐taken sources func FireBreathDebuff(target *Unit) *Aura { - aura := Aura{ - Label: "Fire Breath", - ActionID: ActionID{SpellID: 34889}, - Duration: time.Second * 45, - } - return spellDamageEffectAura(aura, target, 1.08) + return spellDamageEffectAura(Aura{Label: "Fire Breath", ActionID: ActionID{SpellID: 34889}, Duration: time.Second * 45}, target, 1.05) } - -func LightningBreath(target *Unit) *Aura { - aura := Aura{ - Label: "Lightning Breath", - ActionID: ActionID{SpellID: 24844}, - Duration: time.Second * 45, - } - return spellDamageEffectAura(aura, target, 1.08) +func LightningBreathDebuff(target *Unit) *Aura { + return spellDamageEffectAura(Aura{Label: "Lightning Breath", ActionID: ActionID{SpellID: 24844}, Duration: time.Second * 45}, target, 1.05) } - -func EbonPlaguebringerAura(caster *Character, target *Unit, epidemicPoints int32, ebonPlaguebringerPoints int32) *Aura { - // On application, Ebon Plaguebringer trigger extra 'ghost' procs. - var ghostSpell *Spell - label := "External" - if caster != nil { - label = caster.Label - ghostSpell = caster.RegisterSpell(SpellConfig{ - ActionID: ActionID{SpellID: 52789}, - SpellSchool: SpellSchoolShadow, - ProcMask: ProcMaskSpellDamage, - Flags: SpellFlagNoLogs | SpellFlagNoMetrics | SpellFlagNoOnCastComplete | SpellFlagIgnoreModifiers, - - DamageMultiplier: 1, - ThreatMultiplier: 0, - - ApplyEffects: func(sim *Simulation, target *Unit, spell *Spell) { - // Just deal 0 damage as the "Harmful Spell" is implemented on spell damage - spell.CalcAndDealOutcome(sim, target, spell.OutcomeAlwaysHit) - }, - }) - } - - aura := Aura{ - Label: "EbonPlaguebringer" + label, // Support multiple DKs having their EP up - ActionID: ActionID{SpellID: 65142}, - Duration: time.Second * (21 + []time.Duration{0, 4, 8, 12}[epidemicPoints]), - OnGain: func(aura *Aura, sim *Simulation) { - if ghostSpell != nil { - ghostSpell.Cast(sim, aura.Unit) - } - }, - } - - return spellDamageEffectAura(aura, target, 1.08) +func MasterPoisonerDebuff(target *Unit) *Aura { + return spellDamageEffectAura(Aura{Label: "Master Poisoner", ActionID: ActionID{SpellID: 58410}, Duration: time.Second * 15}, target, 1.05) +} +func CurseOfElementsAura(target *Unit) *Aura { + return spellDamageEffectAura(Aura{Label: "Curse of Elements", ActionID: ActionID{SpellID: 1490}, Duration: time.Minute * 5}, target, 1.05) } -const SpellDamageEffectAuraTag = "SpellDamageAuraTag" - -func spellDamageEffectAura(auraConfig Aura, target *Unit, multiplier float64) *Aura { - auraConfig.Tag = SpellDamageEffectAuraTag - aura := target.GetOrRegisterAura(auraConfig) - aura.NewExclusiveEffect("SpellDamageTaken%", false, ExclusiveEffect{ +func majorHealingReductionAura(target *Unit, label string, spellID int32, multiplier float64) *Aura { + aura := target.GetOrRegisterAura(Aura{Label: label, ActionID: ActionID{SpellID: spellID}, Duration: time.Second * 30}) + aura.NewExclusiveEffect("HealingReduction", false, ExclusiveEffect{ Priority: multiplier, OnGain: func(ee *ExclusiveEffect, sim *Simulation) { - ee.Aura.Unit.PseudoStats.SchoolDamageTakenMultiplier[stats.SchoolIndexArcane] *= multiplier - ee.Aura.Unit.PseudoStats.SchoolDamageTakenMultiplier[stats.SchoolIndexFire] *= multiplier - ee.Aura.Unit.PseudoStats.SchoolDamageTakenMultiplier[stats.SchoolIndexFrost] *= multiplier - ee.Aura.Unit.PseudoStats.SchoolDamageTakenMultiplier[stats.SchoolIndexShadow] *= multiplier - ee.Aura.Unit.PseudoStats.SchoolDamageTakenMultiplier[stats.SchoolIndexNature] *= multiplier - ee.Aura.Unit.PseudoStats.SchoolDamageTakenMultiplier[stats.SchoolIndexHoly] *= multiplier + ee.Aura.Unit.PseudoStats.HealingTakenMultiplier *= multiplier }, OnExpire: func(ee *ExclusiveEffect, sim *Simulation) { - ee.Aura.Unit.PseudoStats.SchoolDamageTakenMultiplier[stats.SchoolIndexArcane] /= multiplier - ee.Aura.Unit.PseudoStats.SchoolDamageTakenMultiplier[stats.SchoolIndexFire] /= multiplier - ee.Aura.Unit.PseudoStats.SchoolDamageTakenMultiplier[stats.SchoolIndexFrost] /= multiplier - ee.Aura.Unit.PseudoStats.SchoolDamageTakenMultiplier[stats.SchoolIndexShadow] /= multiplier - ee.Aura.Unit.PseudoStats.SchoolDamageTakenMultiplier[stats.SchoolIndexNature] /= multiplier - ee.Aura.Unit.PseudoStats.SchoolDamageTakenMultiplier[stats.SchoolIndexHoly] /= multiplier + ee.Aura.Unit.PseudoStats.HealingTakenMultiplier /= multiplier }, }) return aura } -func BloodFrenzyAura(target *Unit, points int32) *Aura { - return bloodFrenzySavageCombatAura(target, "Blood Frenzy", ActionID{SpellID: 29859}, points) +// Casting‐speed‐reduction sources +func NecroticStrikeAura(target *Unit) *Aura { + return castSpeedReductionAura(target, "Necrotic Strike", 73975, 1.5) } -func SavageCombatAura(target *Unit, points int32) *Aura { - return bloodFrenzySavageCombatAura(target, "Savage Combat", ActionID{SpellID: 58413}, points) +func LavaBreathAura(target *Unit) *Aura { + return castSpeedReductionAura(target, "Lava Breath", 58604, 1.5) } -func AcidSpitAura(target *Unit) *Aura { - return bloodFrenzySavageCombatAura(target, "Acid Spit", ActionID{SpellID: 55749}, 2) +func SporeCloud(target *Unit) *Aura { return castSpeedReductionAura(target, "Spore Cloud", 50274, 1.5) } +func MindNumbingPoisonAura(target *Unit) *Aura { + return castSpeedReductionAura(target, "Mind-numbing Poison", 5761, 1.5) } - -func bloodFrenzySavageCombatAura(target *Unit, label string, id ActionID, points int32) *Aura { - aura := target.GetOrRegisterAura(Aura{ - Label: label + "-" + strconv.Itoa(int(points)), - ActionID: id, - // No fixed duration, lasts as long as the bleed that activates it. - Duration: NeverExpires, - }) - - multiplier := 1 + 0.02*float64(points) - PhysDamageTakenEffect(aura, multiplier) - return aura -} - -func MangleAura(target *Unit) *Aura { - return bleedDamageAura(target, Aura{ - Label: "Mangle", - ActionID: ActionID{SpellID: 33876}, - Duration: time.Minute, - }, 1.3) -} - -func HemorrhageAura(target *Unit) *Aura { - return bleedDamageAura(target, Aura{ - Label: "Hemorrhage", - ActionID: ActionID{SpellID: 16511}, - Duration: time.Minute, - }, 1.3) -} - -func StampedeAura(target *Unit) *Aura { - return bleedDamageAura(target, Aura{ - Label: "Stampede", - ActionID: ActionID{SpellID: 57386}, - Duration: time.Second * 30, - }, 1.3) +func CurseOfEnfeeblement(target *Unit) *Aura { + return castSpeedReductionAura(target, "Curse of Enfeeblement", 109466, 1.5) } - -func TraumaAura(target *Unit, points int32) *Aura { - return bleedDamageAura(target, Aura{ - Label: "Trauma", - ActionID: ActionID{SpellID: TernaryInt32(points == 1, 46856, 46857)}, - Duration: 1 * time.Minute, - }, TernaryFloat64(points == 1, 1.15, 1.3)) +func SlowAura(target *Unit) *Aura { + return castSpeedReductionAura(target, "Slow", 31589, 1.5) } - -// Bleed Damage Multiplier category -const BleedEffectCategory = "BleedDamage" - -func bleedDamageEffect(aura *Aura, multiplier float64) *Aura { - aura.NewExclusiveEffect(BleedEffectCategory, true, ExclusiveEffect{ +func castSpeedReductionAura(target *Unit, label string, spellID int32, multiplier float64) *Aura { + aura := target.GetOrRegisterAura(Aura{Label: label, ActionID: ActionID{SpellID: spellID}, Duration: time.Second * 30}) + aura.NewExclusiveEffect("CastSpdReduction", false, ExclusiveEffect{ Priority: multiplier, OnGain: func(ee *ExclusiveEffect, sim *Simulation) { - ee.Aura.Unit.PseudoStats.PeriodicPhysicalDamageTakenMultiplier *= multiplier + ee.Aura.Unit.MultiplyCastSpeed(1 / multiplier) }, OnExpire: func(ee *ExclusiveEffect, sim *Simulation) { - ee.Aura.Unit.PseudoStats.PeriodicPhysicalDamageTakenMultiplier /= multiplier + ee.Aura.Unit.MultiplyCastSpeed(multiplier) }, }) - return aura } -func bleedDamageAura(target *Unit, config Aura, multiplier float64) *Aura { - aura := target.GetOrRegisterAura(config) - return bleedDamageEffect(aura, multiplier) -} - -const SpellCritEffectCategory = "spellcritdebuff" - -func CriticalMassAura(target *Unit) *Aura { - return majorSpellCritDebuffAura(target, "Critical Mass", ActionID{SpellID: 22959}, 5) -} - -func ShadowAndFlameAura(target *Unit) *Aura { - return majorSpellCritDebuffAura(target, "Shadow and Flame", ActionID{SpellID: 17800}, 5) -} -func majorSpellCritDebuffAura(target *Unit, label string, actionID ActionID, percent float64) *Aura { - aura := target.GetOrRegisterAura(Aura{ - Label: label, - ActionID: actionID, - Duration: time.Second * 30, - }) +const SpellDamageEffectAuraTag = "SpellDamageAuraTag" - aura.NewExclusiveEffect(SpellCritEffectCategory, true, ExclusiveEffect{ - Priority: percent, +func spellDamageEffectAura(auraConfig Aura, target *Unit, multiplier float64) *Aura { + auraConfig.Tag = SpellDamageEffectAuraTag + aura := target.GetOrRegisterAura(auraConfig) + aura.NewExclusiveEffect("SpellDamageTaken%", true, ExclusiveEffect{ + Priority: multiplier, OnGain: func(ee *ExclusiveEffect, sim *Simulation) { - ee.Aura.Unit.PseudoStats.BonusSpellCritPercentTaken += percent + ee.Aura.Unit.PseudoStats.SchoolDamageTakenMultiplier[stats.SchoolIndexArcane] *= multiplier + ee.Aura.Unit.PseudoStats.SchoolDamageTakenMultiplier[stats.SchoolIndexFire] *= multiplier + ee.Aura.Unit.PseudoStats.SchoolDamageTakenMultiplier[stats.SchoolIndexFrost] *= multiplier + ee.Aura.Unit.PseudoStats.SchoolDamageTakenMultiplier[stats.SchoolIndexShadow] *= multiplier + ee.Aura.Unit.PseudoStats.SchoolDamageTakenMultiplier[stats.SchoolIndexNature] *= multiplier + ee.Aura.Unit.PseudoStats.SchoolDamageTakenMultiplier[stats.SchoolIndexHoly] *= multiplier }, OnExpire: func(ee *ExclusiveEffect, sim *Simulation) { - ee.Aura.Unit.PseudoStats.BonusSpellCritPercentTaken -= percent + ee.Aura.Unit.PseudoStats.SchoolDamageTakenMultiplier[stats.SchoolIndexArcane] /= multiplier + ee.Aura.Unit.PseudoStats.SchoolDamageTakenMultiplier[stats.SchoolIndexFire] /= multiplier + ee.Aura.Unit.PseudoStats.SchoolDamageTakenMultiplier[stats.SchoolIndexFrost] /= multiplier + ee.Aura.Unit.PseudoStats.SchoolDamageTakenMultiplier[stats.SchoolIndexShadow] /= multiplier + ee.Aura.Unit.PseudoStats.SchoolDamageTakenMultiplier[stats.SchoolIndexNature] /= multiplier + ee.Aura.Unit.PseudoStats.SchoolDamageTakenMultiplier[stats.SchoolIndexHoly] /= multiplier }, }) return aura @@ -404,51 +193,6 @@ func majorSpellCritDebuffAura(target *Unit, label string, actionID ActionID, per var majorArmorReductionEffectCategory = "MajorArmorReduction" -func SunderArmorAura(target *Unit) *Aura { - var effect *ExclusiveEffect - aura := target.GetOrRegisterAura(Aura{ - Label: "Sunder Armor", - ActionID: ActionID{SpellID: 58567}, - Duration: time.Second * 30, - MaxStacks: 3, - OnStacksChange: func(_ *Aura, sim *Simulation, oldStacks int32, newStacks int32) { - effect.SetPriority(sim, 0.04*float64(newStacks)) - }, - }) - effect = registerMajorArpEffect(aura, 0) - return aura -} - -func FaerieFireAura(target *Unit) *Aura { - var effect *ExclusiveEffect - aura := target.GetOrRegisterAura(Aura{ - Label: "Faerie Fire", - ActionID: ActionID{SpellID: 770}, - Duration: time.Minute * 5, - MaxStacks: 3, - OnStacksChange: func(aura *Aura, sim *Simulation, oldStacks int32, newStacks int32) { - effect.SetPriority(sim, 0.04*float64(newStacks)) - }, - }) - effect = registerMajorArpEffect(aura, 0) - return aura -} - -func CorrosiveSpitAura(target *Unit) *Aura { - var effect *ExclusiveEffect - aura := target.GetOrRegisterAura(Aura{ - Label: "Corrosive Spit", - ActionID: ActionID{SpellID: 35387}, - Duration: time.Second * 30, - MaxStacks: 3, - OnStacksChange: func(aura *Aura, sim *Simulation, oldStacks int32, newStacks int32) { - effect.SetPriority(sim, 0.04*float64(newStacks)) - }, - }) - effect = registerMajorArpEffect(aura, 0) - return aura -} - func registerMajorArpEffect(aura *Aura, initialArp float64) *ExclusiveEffect { return aura.NewExclusiveEffect(majorArmorReductionEffectCategory, true, ExclusiveEffect{ Priority: initialArp, @@ -461,17 +205,6 @@ func registerMajorArpEffect(aura *Aura, initialArp float64) *ExclusiveEffect { }) } -func ExposeArmorAura(target *Unit, hasGlyph bool) *Aura { - aura := target.GetOrRegisterAura(Aura{ - Label: "ExposeArmor", - ActionID: ActionID{SpellID: 8647}, - Duration: time.Second * TernaryDuration(hasGlyph, 42, 30), - }) - - registerMajorArpEffect(aura, 0.12) - return aura -} - var ShatteringThrowAuraTag = "ShatteringThrow" var ShatteringThrowDuration = time.Second * 10 @@ -492,92 +225,6 @@ func ShatteringThrowAura(target *Unit, actionTag int32) *Aura { }) } -const HuntersMarkAuraTag = "HuntersMark" - -func HuntersMarkAura(target *Unit) *Aura { - bonus := 1772.0 // 443.000000 * 4 @ VoraciousGhost - Hunters Mark and Hawk uses the Unknown class in the SpellScaling - //Todo: Validate calculation - - aura := target.GetOrRegisterAura(Aura{ - Label: "HuntersMark", - Tag: HuntersMarkAuraTag, - ActionID: ActionID{SpellID: 1130}, - Duration: NeverExpires, - }) - - aura.NewExclusiveEffect("HuntersMark", true, ExclusiveEffect{ - Priority: bonus, - OnGain: func(ee *ExclusiveEffect, sim *Simulation) { - ee.Aura.Unit.PseudoStats.BonusRangedAttackPowerTaken += bonus - }, - OnExpire: func(ee *ExclusiveEffect, sim *Simulation) { - ee.Aura.Unit.PseudoStats.BonusRangedAttackPowerTaken -= bonus - }, - }) - - return aura -} - -func CurseOfWeaknessAura(target *Unit) *Aura { - aura := target.GetOrRegisterAura(Aura{ - Label: "Curse of Weakness", - ActionID: ActionID{SpellID: 702}, - Duration: time.Minute * 2, - }) - PhysDamageReductionEffect(aura, 0.1) - return aura -} - -func DemoralizingRoarAura(target *Unit) *Aura { - aura := target.GetOrRegisterAura(Aura{ - Label: "DemoralizingRoar", - ActionID: ActionID{SpellID: 99}, - Duration: time.Second * 30, - }) - PhysDamageReductionEffect(aura, 0.1) - return aura -} - -func DemoralizingShoutAura(target *Unit, glyph bool) *Aura { - aura := target.GetOrRegisterAura(Aura{ - Label: "DemoralizingShout", - ActionID: ActionID{SpellID: 1160}, - Duration: time.Second*30 + TernaryDuration(glyph, time.Second*15, 0), - }) - PhysDamageReductionEffect(aura, 0.1) - return aura -} - -func VindicationAura(target *Unit) *Aura { - aura := target.GetOrRegisterAura(Aura{ - Label: "Vindication", - ActionID: ActionID{SpellID: 26017}, - Duration: time.Second * 30, - }) - PhysDamageReductionEffect(aura, 0.1) - return aura -} - -func DemoralizingScreechAura(target *Unit) *Aura { - aura := target.GetOrRegisterAura(Aura{ - Label: "DemoralizingScreech", - ActionID: ActionID{SpellID: 24423}, - Duration: time.Second * 10, - }) - PhysDamageReductionEffect(aura, 0.1) - return aura -} - -func ScarletFeverAura(target *Unit, points int32, epidemic int32) *Aura { - aura := target.GetOrRegisterAura(Aura{ - Label: "Scarlet Fever", - ActionID: ActionID{SpellID: 81130}, - Duration: time.Second * time.Duration(21+epidemic*4), - }) - PhysDamageReductionEffect(aura, 0.05*float64(points)) - return aura -} - func PhysDamageTakenEffect(aura *Aura, multiplier float64) *ExclusiveEffect { return aura.NewExclusiveEffect("PhysicalDmg", false, ExclusiveEffect{ Priority: multiplier, @@ -602,159 +249,3 @@ func PhysDamageReductionEffect(aura *Aura, dmgReduction float64) *ExclusiveEffec }, }) } - -func apReductionEffect(aura *Aura, apReduction float64) *ExclusiveEffect { - statReduction := stats.Stats{stats.AttackPower: -apReduction} - return aura.NewExclusiveEffect("APReduction", false, ExclusiveEffect{ - Priority: apReduction, - OnGain: func(ee *ExclusiveEffect, sim *Simulation) { - ee.Aura.Unit.AddStatsDynamic(sim, statReduction) - }, - OnExpire: func(ee *ExclusiveEffect, sim *Simulation) { - ee.Aura.Unit.AddStatsDynamic(sim, statReduction.Invert()) - }, - }) -} - -func ThunderClapAura(target *Unit) *Aura { - aura := target.GetOrRegisterAura(Aura{ - Label: "ThunderClap", - ActionID: ActionID{SpellID: 6343}, - Duration: time.Second * 30, - }) - AtkSpeedReductionEffect(aura, 1.2) - return aura -} - -func InfectedWoundsAura(target *Unit, points int32) *Aura { - aura := target.GetOrRegisterAura(Aura{ - Label: "InfectedWounds-" + strconv.Itoa(int(points)), - ActionID: ActionID{SpellID: 58178 + points}, - Duration: time.Second * 12, - }) - AtkSpeedReductionEffect(aura, 1+0.1*float64(points)) - return aura -} - -// Note: Paladin code might apply this as part of their judgement auras instead -// of using another separate aura. -func JudgementsOfTheJustAura(target *Unit, points int32) *Aura { - aura := target.GetOrRegisterAura(Aura{ - Label: "JudgementsOfTheJust-" + strconv.Itoa(int(points)), - ActionID: ActionID{SpellID: 53696}, - Duration: time.Second * 30, - }) - AtkSpeedReductionEffect(aura, 1.0+0.1*float64(points)) - return aura -} - -func DustCloud(target *Unit) *Aura { - aura := target.GetOrRegisterAura(Aura{ - Label: "Dust Cloud", - ActionID: ActionID{SpellID: 50285}, - Duration: time.Second * 30, - }) - AtkSpeedReductionEffect(aura, 1.2) - return aura -} - -func FrostFeverAura(target *Unit, britleBones int32) *Aura { - aura := target.GetOrRegisterAura(Aura{ - Label: "FrostFeverDebuff", - ActionID: ActionID{SpellID: 55095}, - Duration: NeverExpires, - }) - AtkSpeedReductionEffect(aura, 1.2) - if britleBones > 0 { - PhysDamageTakenEffect(aura, 1+0.02*float64(britleBones)) - } - return aura -} - -func AtkSpeedReductionEffect(aura *Aura, speedMultiplier float64) *ExclusiveEffect { - return aura.NewExclusiveEffect("AtkSpdReduction", false, ExclusiveEffect{ - Priority: speedMultiplier, - OnGain: func(ee *ExclusiveEffect, sim *Simulation) { - ee.Aura.Unit.MultiplyAttackSpeed(sim, 1/speedMultiplier) - }, - OnExpire: func(ee *ExclusiveEffect, sim *Simulation) { - ee.Aura.Unit.MultiplyAttackSpeed(sim, speedMultiplier) - }, - }) -} - -func MarkOfBloodAura(target *Unit) *Aura { - actionId := ActionID{SpellID: 49005} - - var healthMetrics *ResourceMetrics - aura := target.GetOrRegisterAura(Aura{ - Label: "MarkOfBlood", - ActionID: actionId, - Duration: 20 * time.Second, - MaxStacks: 20, - OnGain: func(aura *Aura, sim *Simulation) { - aura.SetStacks(sim, aura.MaxStacks) - - target := aura.Unit.CurrentTarget - - if healthMetrics == nil && target != nil { - healthMetrics = target.NewHealthMetrics(actionId) - } - }, - OnSpellHitDealt: func(aura *Aura, sim *Simulation, spell *Spell, result *SpellResult) { - target := aura.Unit.CurrentTarget - - if target != nil && result.Landed() { - // Vampiric Blood bonus max health is ignored in MoB calculation (maybe other Max health effects as well?) - targetHealth := target.MaxHealth() - if target.HasActiveAura("Vampiric Blood") { - targetHealth /= 1.15 - } - // Current testing shows 5% healing instead of 4% as stated in the tooltip - target.GainHealth(sim, targetHealth*0.05*target.PseudoStats.HealingTakenMultiplier, healthMetrics) - aura.RemoveStack(sim) - - if aura.GetStacks() == 0 { - aura.Deactivate(sim) - } - } - }, - }) - return aura -} - -func InsectSwarmAura(target *Unit) *Aura { - aura := target.GetOrRegisterAura(Aura{ - Label: "InsectSwarmMiss", - ActionID: ActionID{SpellID: 27013}, - Duration: time.Second * 12, - }) - increasedMissEffect(aura, 0.03) - return aura -} - -func increasedMissEffect(aura *Aura, increasedMissChance float64) *ExclusiveEffect { - return aura.NewExclusiveEffect("IncreasedMiss", false, ExclusiveEffect{ - Priority: increasedMissChance, - OnGain: func(ee *ExclusiveEffect, sim *Simulation) { - ee.Aura.Unit.PseudoStats.IncreasedMissChance += increasedMissChance - }, - OnExpire: func(ee *ExclusiveEffect, sim *Simulation) { - ee.Aura.Unit.PseudoStats.IncreasedMissChance -= increasedMissChance - }, - }) -} - -func CrystalYieldAura(target *Unit) *Aura { - return target.GetOrRegisterAura(Aura{ - Label: "Crystal Yield", - ActionID: ActionID{SpellID: 15235}, - Duration: 2 * time.Minute, - OnGain: func(aura *Aura, sim *Simulation) { - aura.Unit.stats[stats.Armor] -= 200 - }, - OnExpire: func(aura *Aura, sim *Simulation) { - aura.Unit.stats[stats.Armor] += 200 - }, - }) -} diff --git a/sim/core/exclusive_effect_test.go b/sim/core/exclusive_effect_test.go index 26fc53a301..e7b39bae03 100644 --- a/sim/core/exclusive_effect_test.go +++ b/sim/core/exclusive_effect_test.go @@ -14,18 +14,18 @@ func TestSingleAuraExclusiveDurationNoOverwrite(t *testing.T) { Level: 83, auraTracker: newAuraTracker(), } - mangle := MangleAura(&target) - hemorrhage := MakePermanent(HemorrhageAura(&target)) + lightningBreath := MakePermanent(LightningBreathDebuff(&target)) + fireBreath := FireBreathDebuff(&target) - // Trauma in this case should *never* be overwritten - // as its duration from 'MakePermanent' should make it non overwritable by 1 min duration mangles - hemorrhage.Activate(sim) + // Lightning Breath in this case should *never* be overwritten + // as its duration from 'MakePermanent' should make it non overwritable by Fire Breath + lightningBreath.Activate(sim) sim.CurrentTime = 1 * time.Second - mangle.Activate(sim) + fireBreath.Activate(sim) - if !(hemorrhage.IsActive() && !mangle.IsActive()) { + if !(lightningBreath.IsActive() && !fireBreath.IsActive()) { t.Fatalf("lower duration exclusive aura overwrote previous!") } } @@ -39,18 +39,18 @@ func TestSingleAuraExclusiveDurationOverwrite(t *testing.T) { Level: 83, auraTracker: newAuraTracker(), } - mangle := MangleAura(&target) - hemorrhage := HemorrhageAura(&target) + fireBreath := FireBreathDebuff(&target) + lightningBreath := LightningBreathDebuff(&target) - hemorrhage.Activate(sim) + fireBreath.Activate(sim) sim.CurrentTime = 1 * time.Second - mangle.Activate(sim) + lightningBreath.Activate(sim) - // In this case mangle should overwrite trauma as mangle will give a greater duration + // In this case Lightning Breath should overwrite Fire Breath as Lightning Breath will give a greater duration - if !(mangle.IsActive() && !hemorrhage.IsActive()) { + if !(lightningBreath.IsActive() && !fireBreath.IsActive()) { t.Fatalf("longer duration exclusive aura failed to overwrite") } } diff --git a/sim/core/raid.go b/sim/core/raid.go index 81eaa46f4a..6d851c6b77 100644 --- a/sim/core/raid.go +++ b/sim/core/raid.go @@ -361,7 +361,6 @@ func (raid *Raid) GetPlayerFromUnitIndex(unitIndex int32) Agent { } func (raid *Raid) reset(sim *Simulation) { - raid.resetReplenishment(sim) for _, party := range raid.Parties { party.reset(sim) } diff --git a/sim/core/test_utils.go b/sim/core/test_utils.go index 4dc81dd419..673dacd4e9 100644 --- a/sim/core/test_utils.go +++ b/sim/core/test_utils.go @@ -46,19 +46,37 @@ var DefaultTargetProto = &proto.Target{ } var FullRaidBuffs = &proto.RaidBuffs{ - BlessingOfKings: true, - PowerWordFortitude: true, - BlessingOfMight: true, - MoonkinForm: true, - ElementalOath: true, - StrengthOfEarthTotem: true, - IcyTalons: true, - ArcaneBrilliance: true, - DemonicPact: true, - Bloodlust: true, - Communion: true, - ShadowForm: true, + // +10% Attack Power + TrueshotAura: true, // Hunters + + // +10% Melee & Ranged Attack Speed + UnholyAura: true, // Frost/Unholy DKs + + // +10% Spell Power + ArcaneBrilliance: true, // Mages + + // +5% Spell Haste + ShadowForm: true, // Shadow Priests + + // +5% Critical Strike Chance + LeaderOfThePack: true, // Feral/Guardian Druids + + // +3000 Mastery Rating + BlessingOfMight: true, // Paladins + + // +5% Strength, Agility, Intellect + BlessingOfKings: true, // Paladins + + // +10% Stamina + PowerWordFortitude: true, // Priests + + // Major Haste + Bloodlust: true, + + // Major Mana Replenishment + ManaTideTotemCount: 1, // Shamans } + var FullPartyBuffs = &proto.PartyBuffs{ //BraidedEterniumChain: true, // ManaTideTotems: 1, @@ -68,24 +86,22 @@ var FullIndividualBuffs = &proto.IndividualBuffs{ // BlessingOfSanctuary: true, // BlessingOfWisdom: true, // JudgementsOfTheWise: true, - VampiricTouch: true, } var FullDebuffs = &proto.Debuffs{ - BloodFrenzy: true, - CurseOfElements: true, - CurseOfWeakness: true, - EarthAndMoon: true, - EbonPlaguebringer: true, - ExposeArmor: true, - FaerieFire: true, - Mangle: true, - SunderArmor: true, - ThunderClap: true, - Vindication: true, - MasterPoisoner: true, - CriticalMass: true, - DemoralizingRoar: true, + WeakenedBlows: true, + PhysicalVulnerability: true, + WeakenedArmor: true, + MortalWounds: true, + FireBreath: true, + LightningBreath: true, + MasterPoisoner: true, + CurseOfElements: true, + NecroticStrike: true, + LavaBreath: true, + SporeCloud: true, + Slow: true, + MindNumbingPoison: true, } func NewDefaultTarget() *proto.Target { diff --git a/sim/core/unit.go b/sim/core/unit.go index 518a07baef..bbeddb773e 100644 --- a/sim/core/unit.go +++ b/sim/core/unit.go @@ -73,9 +73,6 @@ type Unit struct { moveSpell *Spell movementAction *MovementAction - // How much uptime of Dark Intent the unit will have - DarkIntentUptimePercent float64 - // Environment in which this Unit exists. This will be nil until after the // construction phase. Env *Environment diff --git a/sim/death_knight/blood/blood.go b/sim/death_knight/blood/blood.go index 4748c8c8ee..412a4ba8a2 100644 --- a/sim/death_knight/blood/blood.go +++ b/sim/death_knight/blood/blood.go @@ -44,13 +44,6 @@ func NewBloodDeathKnight(character *core.Character, options *proto.Player) *Bloo vengeance: &core.VengeanceTracker{}, } - healingModel := options.HealingModel - if healingModel != nil { - if healingModel.InspirationUptime > 0.0 { - core.ApplyInspiration(&bdk.Unit, healingModel.InspirationUptime) - } - } - return bdk } diff --git a/sim/druid/demoralizing_roar.go b/sim/druid/demoralizing_roar.go index 6ec89af522..4020047d08 100644 --- a/sim/druid/demoralizing_roar.go +++ b/sim/druid/demoralizing_roar.go @@ -6,7 +6,7 @@ import ( func (druid *Druid) registerDemoralizingRoarSpell() { druid.DemoralizingRoarAuras = druid.NewEnemyAuraArray(func(target *core.Unit) *core.Aura { - return core.DemoralizingRoarAura(target) + return core.WeakenedBlowsAura(target) }) druid.DemoralizingRoar = druid.RegisterSpell(Bear, core.SpellConfig{ diff --git a/sim/druid/druid.go b/sim/druid/druid.go index bc65f2e7ce..f558b16e39 100644 --- a/sim/druid/druid.go +++ b/sim/druid/druid.go @@ -268,7 +268,7 @@ func (druid *Druid) RegisterSpell(formMask DruidForm, config core.SpellConfig) * func (druid *Druid) Initialize() { druid.form = druid.StartingForm - druid.BleedCategories = druid.GetEnemyExclusiveCategories(core.BleedEffectCategory) + //druid.BleedCategories = druid.GetEnemyExclusiveCategories(core.BleedEffectCategory) druid.Env.RegisterPostFinalizeEffect(func() { druid.MHAutoSpell = druid.AutoAttacks.MHAuto() diff --git a/sim/druid/guardian/tank.go b/sim/druid/guardian/tank.go index e1d11e74cb..0da9cf442e 100644 --- a/sim/druid/guardian/tank.go +++ b/sim/druid/guardian/tank.go @@ -45,13 +45,6 @@ func NewGuardianDruid(character *core.Character, options *proto.Player) *Guardia AutoSwingMelee: true, }) - healingModel := options.HealingModel - if healingModel != nil { - if healingModel.InspirationUptime > 0.0 { - core.ApplyInspiration(&bear.Unit, healingModel.InspirationUptime) - } - } - bear.RegisterBearFormAura() return bear diff --git a/sim/hunter/hunter.go b/sim/hunter/hunter.go index 8e39c02a3d..ee4f62046d 100644 --- a/sim/hunter/hunter.go +++ b/sim/hunter/hunter.go @@ -182,13 +182,6 @@ func (hunter *Hunter) AddRaidBuffs(raidBuffs *proto.RaidBuffs) { if hunter.Options.PetType == proto.HunterOptions_CoreHound { raidBuffs.Bloodlust = true } - if hunter.Options.PetType == proto.HunterOptions_Silithid { - raidBuffs.BloodPact = true - } - - if hunter.Options.PetType == proto.HunterOptions_Cat { - raidBuffs.StrengthOfEarthTotem = true - } if hunter.Options.PetType == proto.HunterOptions_ShaleSpider { raidBuffs.BlessingOfKings = true diff --git a/sim/hunter/hunters_mark.go b/sim/hunter/hunters_mark.go index c7a986472d..8fac9ef9a8 100644 --- a/sim/hunter/hunters_mark.go +++ b/sim/hunter/hunters_mark.go @@ -1,36 +1,32 @@ package hunter -import ( - "github.com/wowsims/mop/sim/core" -) - func (hunter *Hunter) registerHuntersMarkSpell() { //core.Aura.Unit.NewEnemyAuraArray() - enemyHuntersMarks := hunter.NewEnemyAuraArray(core.HuntersMarkAura) + // enemyHuntersMarks := hunter.NewEnemyAuraArray(core.HuntersMarkAura) - hunter.RegisterSpell(core.SpellConfig{ - ActionID: core.ActionID{SpellID: 1130}, - ProcMask: core.ProcMaskEmpty, - Flags: core.SpellFlagAPL, + // hunter.RegisterSpell(core.SpellConfig{ + // ActionID: core.ActionID{SpellID: 1130}, + // ProcMask: core.ProcMaskEmpty, + // Flags: core.SpellFlagAPL, - FocusCost: core.FocusCostOptions{ - Cost: 0, - }, - Cast: core.CastConfig{ - DefaultCast: core.Cast{ - GCD: core.GCDDefault, - }, - IgnoreHaste: true, - }, + // FocusCost: core.FocusCostOptions{ + // Cost: 0, + // }, + // Cast: core.CastConfig{ + // DefaultCast: core.Cast{ + // GCD: core.GCDDefault, + // }, + // IgnoreHaste: true, + // }, - ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) { - for _, aura := range enemyHuntersMarks { - if aura.IsActive() { - aura.Deactivate(sim) - } - } - // Activating Hunters Mark for the new target - enemyHuntersMarks.Get(target).Activate(sim) - }, - }) + // ApplyEffects: func(sim *core.Simulation, target *core.Unit, spell *core.Spell) { + // for _, aura := range enemyHuntersMarks { + // if aura.IsActive() { + // aura.Deactivate(sim) + // } + // } + // // Activating Hunters Mark for the new target + // enemyHuntersMarks.Get(target).Activate(sim) + // }, + // }) } diff --git a/sim/mage/evocation.go b/sim/mage/evocation.go index bef56ba0d7..6b194c6dbb 100644 --- a/sim/mage/evocation.go +++ b/sim/mage/evocation.go @@ -52,10 +52,6 @@ func (mage *Mage) registerEvocation() { Spell: evocation, Type: core.CooldownTypeMana, ShouldActivate: func(sim *core.Simulation, character *core.Character) bool { - if character.HasActiveAuraWithTag(core.InnervateAuraTag) || character.HasActiveAuraWithTag(core.ManaTideTotemAuraTag) { - return false - } - if sim.GetRemainingDuration() < 12*time.Second { return false } diff --git a/sim/paladin/protection/protection.go b/sim/paladin/protection/protection.go index 494dadfc8c..48ffbdaa91 100644 --- a/sim/paladin/protection/protection.go +++ b/sim/paladin/protection/protection.go @@ -36,13 +36,6 @@ func NewProtectionPaladin(character *core.Character, options *proto.Player) *Pro vengeance: &core.VengeanceTracker{}, } - healingModel := options.HealingModel - if healingModel != nil { - if healingModel.InspirationUptime > 0.0 { - core.ApplyInspiration(&prot.Unit, healingModel.InspirationUptime) - } - } - return prot } diff --git a/sim/warlock/warlock.go b/sim/warlock/warlock.go index e49580e099..23bb1bb475 100644 --- a/sim/warlock/warlock.go +++ b/sim/warlock/warlock.go @@ -119,8 +119,7 @@ func (warlock *Warlock) Initialize() { } func (warlock *Warlock) AddRaidBuffs(raidBuffs *proto.RaidBuffs) { - raidBuffs.BloodPact = warlock.Options.Summon == proto.WarlockOptions_Imp - raidBuffs.FelIntelligence = warlock.Options.Summon == proto.WarlockOptions_Felhunter + } func (warlock *Warlock) Reset(sim *core.Simulation) { diff --git a/sim/warrior/protection/protection.go b/sim/warrior/protection/protection.go index f9d2dcb490..4a6dec913d 100644 --- a/sim/warrior/protection/protection.go +++ b/sim/warrior/protection/protection.go @@ -64,13 +64,6 @@ func NewProtectionWarrior(character *core.Character, options *proto.Player) *Pro AutoSwingMelee: true, }) - //healingModel := options.HealingModel - //if healingModel != nil { - // if healingModel.InspirationUptime > 0.0 { - // core.ApplyInspiration(war.GetCharacter(), healingModel.InspirationUptime) - // } - //} - return war } diff --git a/ui/core/components/character_stats.tsx b/ui/core/components/character_stats.tsx index a237214e83..8504d7ef19 100644 --- a/ui/core/components/character_stats.tsx +++ b/ui/core/components/character_stats.tsx @@ -4,7 +4,7 @@ import { ref } from 'tsx-vanilla'; import * as Mechanics from '../constants/mechanics.js'; import { Player } from '../player.js'; -import { Class, PseudoStat, Stat } from '../proto/common.js'; +import { Stat } from '../proto/common.js'; import { ActionId } from '../proto_utils/action_id'; import { getStatName, masterySpellIDs, masterySpellNames } from '../proto_utils/names.js'; import { Stats, UnitStat } from '../proto_utils/stats.js'; @@ -102,7 +102,6 @@ export class CharacterStats extends Component { const talentsStats = Stats.fromProto(playerStats.talentsStats); const buffsStats = Stats.fromProto(playerStats.buffsStats); const consumesStats = Stats.fromProto(playerStats.consumesStats); - const debuffStats = this.getDebuffStats(); const bonusStats = player.getBonusStats(); let baseDelta = baseStats.add(statMods.base || new Stats()); @@ -120,8 +119,7 @@ export class CharacterStats extends Component { .add(statMods.talents || new Stats()) .add(statMods.buffs || new Stats()) .add(statMods.consumes || new Stats()) - .add(statMods.final || new Stats()) - .add(debuffStats); + .add(statMods.final || new Stats()); if (this.overwriteDisplayStats) { const statOverwrites = this.overwriteDisplayStats(this.player); @@ -196,12 +194,6 @@ export class CharacterStats extends Component { Consumes: {this.statDisplayString(consumesDelta, unitStat)} - {debuffStats.getUnitStat(unitStat) != 0 && ( -
- Debuffs: - {this.statDisplayString(debuffStats, unitStat)} -
- )} {bonusStatValue !== 0 && (
Bonus: @@ -287,25 +279,14 @@ export class CharacterStats extends Component { derivedPercentOrPointsValue = derivedPercentOrPointsValue! + this.player.getBaseMastery(); } - const hideRootRating = (rootRatingValue === null) || ((rootRatingValue === 0) && (derivedPercentOrPointsValue !== null)); + const hideRootRating = rootRatingValue === null || (rootRatingValue === 0 && derivedPercentOrPointsValue !== null); const rootRatingString = hideRootRating ? '' : String(Math.round(rootRatingValue)); const percentOrPointsSuffix = unitStat.equalsStat(Stat.StatMasteryRating) ? ' Points' : '%'; - const percentOrPointsString = (derivedPercentOrPointsValue === null) ? '' : (`${derivedPercentOrPointsValue.toFixed(2)}` + percentOrPointsSuffix); - const wrappedPercentOrPointsString = (hideRootRating || (derivedPercentOrPointsValue === null)) ? percentOrPointsString : ` (${percentOrPointsString})`; + const percentOrPointsString = derivedPercentOrPointsValue === null ? '' : `${derivedPercentOrPointsValue.toFixed(2)}` + percentOrPointsSuffix; + const wrappedPercentOrPointsString = hideRootRating || derivedPercentOrPointsValue === null ? percentOrPointsString : ` (${percentOrPointsString})`; return rootRatingString + wrappedPercentOrPointsString; } - private getDebuffStats(): Stats { - let debuffStats = new Stats(); - - const debuffs = this.player.sim.raid.getDebuffs(); - if (debuffs.criticalMass || debuffs.shadowAndFlame) { - debuffStats = debuffStats.addPseudoStat(PseudoStat.PseudoStatSpellCritPercent, 5); - } - - return debuffStats; - } - private bonusStatsLink(unitStat: UnitStat): HTMLElement { const rootStat = unitStat.getRootStat(); const statName = getStatName(rootStat); diff --git a/ui/core/components/individual_sim_ui/consumes_picker.tsx b/ui/core/components/individual_sim_ui/consumes_picker.tsx index ec4c52c95f..99cba9834b 100644 --- a/ui/core/components/individual_sim_ui/consumes_picker.tsx +++ b/ui/core/components/individual_sim_ui/consumes_picker.tsx @@ -64,6 +64,8 @@ export class ConsumesPicker extends Component { this.updateRow(row, [potionsPicker, conjuredPicker, prePotPicker]), ); this.addOnDisposeCallback(() => events.dispose()); + + this.updateRow(row, [potionsPicker, conjuredPicker, prePotPicker]); } private buildElixirsPicker(): void { @@ -128,7 +130,7 @@ export class ConsumesPicker extends Component { const explosivesoptions = ConsumablesInputs.makeExplosivesInput(relevantStatOptions(ConsumablesInputs.EXPLOSIVE_CONFIG, this.simUI), 'Explosives'); const explosivePicker = buildIconInput(engiConsumesElem, this.simUI.player, explosivesoptions); - const events = TypedEvent.onAny([this.simUI.player.professionChangeEmitter]).on(() => this.updateRow(row, [explosivePicker, tinkerPicker])); + const events = this.simUI.player.professionChangeEmitter.on(() => this.updateRow(row, [explosivePicker, tinkerPicker])); this.addOnDisposeCallback(() => events.dispose()); // Initial update of row based on current state. diff --git a/ui/core/components/individual_sim_ui/settings_tab.ts b/ui/core/components/individual_sim_ui/settings_tab.ts index 203d9faee4..0dcf795e7b 100644 --- a/ui/core/components/individual_sim_ui/settings_tab.ts +++ b/ui/core/components/individual_sim_ui/settings_tab.ts @@ -296,7 +296,6 @@ export class SettingsTab extends SimTab { simUI.player.setInFrontOfTarget(eventID, newSettings.inFrontOfTarget); simUI.player.setDistanceFromTarget(eventID, newSettings.distanceFromTarget); simUI.player.setHealingModel(eventID, newSettings.healingModel || HealingModel.create()); - simUI.player.setDarkIntentUptime(eventID, newSettings.darkIntentUptime); }); }, changeEmitters: [ @@ -353,7 +352,6 @@ export class SettingsTab extends SimTab { inFrontOfTarget: this.simUI.player.getInFrontOfTarget(), distanceFromTarget: this.simUI.player.getDistanceFromTarget(), healingModel: this.simUI.player.getHealingModel(), - darkIntentUptime: this.simUI.player.getDarkIntentUptime(), }); } diff --git a/ui/core/components/inputs/buffs_debuffs.ts b/ui/core/components/inputs/buffs_debuffs.ts index b8856ddef4..8cc527ead7 100644 --- a/ui/core/components/inputs/buffs_debuffs.ts +++ b/ui/core/components/inputs/buffs_debuffs.ts @@ -1,19 +1,11 @@ -import { Faction, Stat, TristateEffect } from '../../proto/common'; +import { Faction, Stat } from '../../proto/common'; import { ActionId } from '../../proto_utils/action_id'; import { makeBooleanDebuffInput, - makeBooleanIndividualBuffInput, - makeBooleanPartyBuffInput, makeBooleanRaidBuffInput, makeMultistateIndividualBuffInput, - makeMultistateMultiplierIndividualBuffInput, - makeMultistatePartyBuffInput, makeMultistateRaidBuffInput, - makeQuadstateDebuffInput, - makeTristateDebuffInput, makeTristateIndividualBuffInput, - makeTristateRaidBuffInput, - withLabel, } from '../icon_inputs'; import * as InputHelpers from '../input_helpers'; import { IconPicker } from '../pickers/icon_picker'; @@ -24,244 +16,144 @@ import { IconPickerStatOption, PickerStatOptions } from './stat_options'; // RAID BUFFS /////////////////////////////////////////////////////////////////////////// -export const AllStatsBuff = InputHelpers.makeMultiIconInput( +export const StatsBuff = InputHelpers.makeMultiIconInput( [ makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(20217), fieldName: 'blessingOfKings' }), makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(1126), fieldName: 'markOfTheWild' }), - makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(116781), fieldName: 'legacyOfTheWhiteTiger' }), - makeBooleanRaidBuffInput({ actionId: ActionId.fromItemId(63140), fieldName: 'drumsOfTheBurningWild' }), + makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(90363), fieldName: 'embraceOfTheShaleSpider' }), + makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(115921), fieldName: 'legacyOfTheEmperor' }), ], 'Stats', ); -export const ArmorBuff = InputHelpers.makeMultiIconInput( - [ - makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(465), fieldName: 'devotionAura' }), - makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(8071), fieldName: 'stoneskinTotem' }), - ], - 'Armor', -); - -export const AttackPowerPercentBuff = InputHelpers.makeMultiIconInput( +export const AttackPowerBuff = InputHelpers.makeMultiIconInput( [ - makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(19740), fieldName: 'blessingOfMight' }), - makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(53138), fieldName: 'abominationsMight' }), - makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(30808), fieldName: 'unleashedRage' }), makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(19506), fieldName: 'trueshotAura' }), + makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(57330), fieldName: 'hornOfWinter' }), + makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(6673), fieldName: 'battleShout' }), ], - 'Atk Pwr %', -); - -export const Bloodlust = InputHelpers.makeMultiIconInput( - [ - makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(2825), fieldName: 'bloodlust' }), - makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(80353), fieldName: 'timeWarp' }), - ], - 'Lust', + 'Attack Power', ); -export const DamagePercentBuff = InputHelpers.makeMultiIconInput( +export const AttackSpeedBuff = InputHelpers.makeMultiIconInput( [ - makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(31876), fieldName: 'communion' }), - makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(82930), fieldName: 'arcaneTactics' }), - makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(34460), fieldName: 'ferociousInspiration' }), + makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(55610), fieldName: 'unholyAura' }), + makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(128433), fieldName: 'serpentsSwiftness' }), + makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(113742), fieldName: 'swiftbladesCunning' }), + makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(30809), fieldName: 'unleashedRage' }), + makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(128432), fieldName: 'cacklingHowl' }), ], - '+3% Dmg', + 'Attack Speed', ); -// TODO: Look at these, what we want and how to structure them for multiple available -export const DefensiveCooldownBuff = InputHelpers.makeMultiIconInput( +export const SpellPowerBuff = InputHelpers.makeMultiIconInput( [ - makeMultistateIndividualBuffInput({ actionId: ActionId.fromSpellId(6940), numStates: 11, fieldName: 'handOfSacrificeCount' }), - // makeMultistateIndividualBuffInput({ actionId: ActionId.fromSpellId(53530), numStates: 11, fieldName: 'divineGuardians' }), - makeMultistateIndividualBuffInput({ actionId: ActionId.fromSpellId(33206), numStates: 11, fieldName: 'painSuppressionCount' }), - // makeMultistateIndividualBuffInput({ actionId: ActionId.fromSpellId(47788), numStates: 11, fieldName: 'guardianSpirits' }), - makeMultistateIndividualBuffInput({ actionId: ActionId.fromSpellId(97462), numStates: 11, fieldName: 'rallyingCryCount' }), + makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(1459), fieldName: 'arcaneBrilliance' }), + makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(126309), fieldName: 'stillWater' }), + makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(77747), fieldName: 'burningWrath' }), + makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(109773), fieldName: 'darkIntent' }), ], - 'Defensive CDs', + 'Spell Power', ); export const SpellHasteBuff = InputHelpers.makeMultiIconInput( [ makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(15473), fieldName: 'shadowForm' }), - makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(24858), fieldName: 'moonkinForm' }), - makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(3738), fieldName: 'wrathOfAirTotem' }), + makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(24907), fieldName: 'moonkinAura' }), + makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(49868), fieldName: 'mindQuickening' }), + makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(51470), fieldName: 'elementalOath' }), ], 'Spell Haste', ); -export const ManaBuff = InputHelpers.makeMultiIconInput( - [ - makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(1459), fieldName: 'arcaneBrilliance' }), - makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(54424), fieldName: 'felIntelligence' }), - ], - 'Mana', -); - export const CritBuff = InputHelpers.makeMultiIconInput( [ makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(17007), fieldName: 'leaderOfThePack' }), - makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(51470), fieldName: 'elementalOath' }), - makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(51701), fieldName: 'honorAmongThieves' }), - makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(29801), fieldName: 'rampage' }), makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(24604), fieldName: 'furiousHowl' }), - makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(115921), fieldName: 'legacyOfTheEmperor' }), + makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(90309), fieldName: 'terrifyingRoar' }), + makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(116781), fieldName: 'legacyOfTheWhiteTiger' }), + makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(1459), fieldName: 'arcaneBrilliance' }), + makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(126309), fieldName: 'stillWater' }), ], 'Crit %', ); -export const MeleeHasteBuff = InputHelpers.makeMultiIconInput( - [ - makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(55610), fieldName: 'icyTalons' }), - makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(8512), fieldName: 'windfuryTotem' }), - makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(53290), fieldName: 'huntingParty' }), - ], - 'Melee Haste', -); - -export const MP5Buff = InputHelpers.makeMultiIconInput( +export const MasteryBuff = InputHelpers.makeMultiIconInput( [ makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(19740), fieldName: 'blessingOfMight' }), - makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(54424), fieldName: 'felIntelligence' }), - makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(5675), fieldName: 'manaSpringTotem' }), - ], - 'MP5', -); - -export const ReplenishmentBuff = InputHelpers.makeMultiIconInput( - [ - makeBooleanIndividualBuffInput({ actionId: ActionId.fromSpellId(34914), fieldName: 'vampiricTouch' }), - makeBooleanIndividualBuffInput({ actionId: ActionId.fromSpellId(31876), fieldName: 'communion' }), - makeBooleanIndividualBuffInput({ actionId: ActionId.fromSpellId(48544), fieldName: 'revitalize' }), - makeBooleanIndividualBuffInput({ actionId: ActionId.fromSpellId(30295), fieldName: 'soulLeach' }), - makeBooleanIndividualBuffInput({ actionId: ActionId.fromSpellId(86508), fieldName: 'enduringWinter' }), + makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(93435), fieldName: 'roarOfCourage' }), + makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(128997), fieldName: 'spiritBeastBlessing' }), + makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(116956), fieldName: 'graceOfAir' }), ], - 'Replen', + 'Mastery', ); -export const ResistanceBuff = InputHelpers.makeMultiIconInput( - [ - makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(19891), fieldName: 'resistanceAura' }), - makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(8184), fieldName: 'elementalResistanceTotem' }), - makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(20043), fieldName: 'aspectOfTheWild' }), - makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(27683), fieldName: 'shadowProtection' }), - makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(20217), fieldName: 'blessingOfKings' }), - makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(1126), fieldName: 'markOfTheWild' }), - ], - 'Resistances', -); - -export const SpellPowerBuff = InputHelpers.makeMultiIconInput( +export const StaminaBuff = InputHelpers.makeMultiIconInput( [ - makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(47236), fieldName: 'demonicPact' }), - makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(77746), fieldName: 'totemicWrath' }), - makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(1459), fieldName: 'arcaneBrilliance' }), - makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(8227), fieldName: 'flametongueTotem' }), + makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(469), fieldName: 'commandingShout' }), + makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(109773), fieldName: 'darkIntent' }), + makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(21562), fieldName: 'powerWordFortitude' }), + makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(90364), fieldName: 'qirajiFortitude' }), ], - 'Spell Power', + 'Stamina', ); -export const StaminaBuff = InputHelpers.makeMultiIconInput( +export const MajorHasteBuff = InputHelpers.makeMultiIconInput( [ - makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(21562), fieldName: 'powerWordFortitude' }), - makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(6307), fieldName: 'bloodPact' }), - makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(469), fieldName: 'commandingShout' }), + makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(2825), fieldName: 'bloodlust' }), + makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(32182), fieldName: 'heroism' }), + makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(80353), fieldName: 'timeWarp' }), ], - 'Stamina', + 'Major Haste', ); -export const StrengthAndAgilityBuff = InputHelpers.makeMultiIconInput( +// TODO: Look at these, what we want and how to structure them for multiple available +export const DefensiveCooldownBuff = InputHelpers.makeMultiIconInput( [ - makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(8075), fieldName: 'strengthOfEarthTotem' }), - makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(57330), fieldName: 'hornOfWinter' }), - makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(6673), fieldName: 'battleShout' }), + makeMultistateIndividualBuffInput({ actionId: ActionId.fromSpellId(6940), numStates: 11, fieldName: 'handOfSacrificeCount' }), + // makeMultistateIndividualBuffInput({ actionId: ActionId.fromSpellId(53530), numStates: 11, fieldName: 'divineGuardians' }), + makeMultistateIndividualBuffInput({ actionId: ActionId.fromSpellId(33206), numStates: 11, fieldName: 'painSuppressionCount' }), + // makeMultistateIndividualBuffInput({ actionId: ActionId.fromSpellId(47788), numStates: 11, fieldName: 'guardianSpirits' }), + makeMultistateIndividualBuffInput({ actionId: ActionId.fromSpellId(97462), numStates: 11, fieldName: 'rallyingCryCount' }), ], - 'Str/Agi', + 'Defensive CDs', ); // Misc Buffs -export const RetributionAura = makeBooleanRaidBuffInput({ actionId: ActionId.fromSpellId(7294), fieldName: 'retributionAura' }); export const ManaTideTotem = makeMultistateRaidBuffInput({ actionId: ActionId.fromSpellId(16190), numStates: 5, fieldName: 'manaTideTotemCount' }); -export const Innervate = makeMultistateIndividualBuffInput({ actionId: ActionId.fromSpellId(29166), numStates: 11, fieldName: 'innervateCount' }); -export const PowerInfusion = makeMultistateIndividualBuffInput({ actionId: ActionId.fromSpellId(10060), numStates: 11, fieldName: 'powerInfusionCount' }); -export const FocusMagic = makeBooleanIndividualBuffInput({ actionId: ActionId.fromSpellId(54648), fieldName: 'focusMagic' }); export const TricksOfTheTrade = makeTristateIndividualBuffInput({ actionId: ActionId.fromItemId(45767), impId: ActionId.fromSpellId(57933), fieldName: 'tricksOfTheTrade', }); export const UnholyFrenzy = makeMultistateIndividualBuffInput({ actionId: ActionId.fromSpellId(49016), numStates: 11, fieldName: 'unholyFrenzyCount' }); -export const DarkIntent = makeBooleanIndividualBuffInput({ actionId: ActionId.fromSpellId(85759), fieldName: 'darkIntent' }); export const ShatteringThrow = makeMultistateIndividualBuffInput({ actionId: ActionId.fromSpellId(64382), numStates: 11, fieldName: 'shatteringThrowCount' }); /////////////////////////////////////////////////////////////////////////// // DEBUFFS /////////////////////////////////////////////////////////////////////////// -export const MajorArmorDebuff = InputHelpers.makeMultiIconInput( - [ - makeBooleanDebuffInput({ actionId: ActionId.fromSpellId(7386), fieldName: 'sunderArmor' }), - makeBooleanDebuffInput({ actionId: ActionId.fromSpellId(8647), fieldName: 'exposeArmor' }), - makeBooleanDebuffInput({ actionId: ActionId.fromSpellId(770), fieldName: 'faerieFire' }), - makeBooleanDebuffInput({ actionId: ActionId.fromSpellId(35387), fieldName: 'corrosiveSpit' }), - ], - '-Armor %', -); - -export const DamageReduction = InputHelpers.makeMultiIconInput( - [ - makeBooleanDebuffInput({ actionId: ActionId.fromSpellId(26017), fieldName: 'vindication' }), - makeBooleanDebuffInput({ actionId: ActionId.fromSpellId(702), fieldName: 'curseOfWeakness' }), - makeBooleanDebuffInput({ actionId: ActionId.fromSpellId(99), fieldName: 'demoralizingRoar' }), - makeBooleanDebuffInput({ actionId: ActionId.fromSpellId(81130), fieldName: 'scarletFever' }), - makeBooleanDebuffInput({ actionId: ActionId.fromSpellId(1160), fieldName: 'demoralizingShout' }), - ], - '-Dmg %', -); +export const MajorArmorDebuff = makeBooleanDebuffInput({ actionId: ActionId.fromSpellId(113746), fieldName: 'weakenedArmor' }); -export const BleedDebuff = InputHelpers.makeMultiIconInput( - [ - makeBooleanDebuffInput({ actionId: ActionId.fromSpellId(29859), fieldName: 'bloodFrenzy' }), - makeBooleanDebuffInput({ actionId: ActionId.fromSpellId(33878), fieldName: 'mangle' }), - makeBooleanDebuffInput({ actionId: ActionId.fromSpellId(57386), fieldName: 'stampede' }), - makeBooleanDebuffInput({ actionId: ActionId.fromSpellId(16511), fieldName: 'hemorrhage' }), - ], - '+Bleed %', -); +export const DamageReduction = makeBooleanDebuffInput({ actionId: ActionId.fromSpellId(115798), fieldName: 'weakenedBlows' }); -export const SpellCritDebuff = InputHelpers.makeMultiIconInput( +export const CastSpeedDebuff = InputHelpers.makeMultiIconInput( [ - makeBooleanDebuffInput({ actionId: ActionId.fromSpellId(12873), fieldName: 'criticalMass' }), - makeBooleanDebuffInput({ actionId: ActionId.fromSpellId(17801), fieldName: 'shadowAndFlame' }), + makeBooleanDebuffInput({ actionId: ActionId.fromSpellId(73975), fieldName: 'necroticStrike' }), + makeBooleanDebuffInput({ actionId: ActionId.fromSpellId(58604), fieldName: 'lavaBreath' }), + makeBooleanDebuffInput({ actionId: ActionId.fromSpellId(50274), fieldName: 'sporeCloud' }), + makeBooleanDebuffInput({ actionId: ActionId.fromSpellId(5761), fieldName: 'mindNumbingPoison' }), + makeBooleanDebuffInput({ actionId: ActionId.fromSpellId(31589), fieldName: 'slow' }), + makeBooleanDebuffInput({ actionId: ActionId.fromSpellId(109466), fieldName: 'curseOfEnfeeblement' }), ], - 'Spell Crit', + 'Cast Speed', ); -export const MeleeAttackSpeedDebuff = InputHelpers.makeMultiIconInput( - [ - makeBooleanDebuffInput({ actionId: ActionId.fromSpellId(6343), fieldName: 'thunderClap' }), - makeBooleanDebuffInput({ actionId: ActionId.fromSpellId(59921), fieldName: 'frostFever' }), - makeBooleanDebuffInput({ actionId: ActionId.fromSpellId(53696), fieldName: 'judgementsOfTheJust' }), - makeBooleanDebuffInput({ actionId: ActionId.fromSpellId(48484), fieldName: 'infectedWounds' }), - makeBooleanDebuffInput({ actionId: ActionId.fromSpellId(8042), fieldName: 'earthShock' }), - ], - 'Atk Speed', -); - -export const PhysicalDamageDebuff = InputHelpers.makeMultiIconInput( - [ - makeBooleanDebuffInput({ actionId: ActionId.fromSpellId(29859), fieldName: 'bloodFrenzy' }), - makeBooleanDebuffInput({ actionId: ActionId.fromSpellId(58413), fieldName: 'savageCombat' }), - makeBooleanDebuffInput({ actionId: ActionId.fromSpellId(81328), fieldName: 'brittleBones' }), - makeBooleanDebuffInput({ actionId: ActionId.fromSpellId(55749), fieldName: 'acidSpit' }), - ], - 'Phys Vuln', -); +export const PhysicalDamageDebuff = makeBooleanDebuffInput({ actionId: ActionId.fromSpellId(81326), fieldName: 'physicalVulnerability' }); export const SpellDamageDebuff = InputHelpers.makeMultiIconInput( [ - makeBooleanDebuffInput({ actionId: ActionId.fromSpellId(51160), fieldName: 'ebonPlaguebringer' }), - makeBooleanDebuffInput({ actionId: ActionId.fromSpellId(60433), fieldName: 'earthAndMoon' }), + makeBooleanDebuffInput({ actionId: ActionId.fromSpellId(24844), fieldName: 'lightningBreath' }), makeBooleanDebuffInput({ actionId: ActionId.fromSpellId(1490), fieldName: 'curseOfElements' }), makeBooleanDebuffInput({ actionId: ActionId.fromSpellId(58410), fieldName: 'masterPoisoner' }), makeBooleanDebuffInput({ actionId: ActionId.fromSpellId(34889), fieldName: 'fireBreath' }), @@ -276,42 +168,17 @@ export const SpellDamageDebuff = InputHelpers.makeMultiIconInput( export const RAID_BUFFS_CONFIG = [ // Standard buffs { - config: AllStatsBuff, + config: StatsBuff, picker: MultiIconPicker, - stats: [], + stats: [Stat.StatStrength, Stat.StatAgility, Stat.StatIntellect], }, { - config: ArmorBuff, - picker: MultiIconPicker, - stats: [Stat.StatArmor], - }, - { - config: StaminaBuff, - picker: MultiIconPicker, - stats: [Stat.StatStamina], - }, - { - config: StrengthAndAgilityBuff, - picker: MultiIconPicker, - stats: [Stat.StatStrength, Stat.StatAgility], - }, - { - config: ManaBuff, - picker: MultiIconPicker, - stats: [Stat.StatMana], - }, - { - config: AttackPowerPercentBuff, + config: AttackPowerBuff, picker: MultiIconPicker, stats: [Stat.StatAttackPower, Stat.StatRangedAttackPower], }, { - config: CritBuff, - picker: MultiIconPicker, - stats: [Stat.StatCritRating], - }, - { - config: MeleeHasteBuff, + config: AttackSpeedBuff, picker: MultiIconPicker, stats: [Stat.StatAttackPower, Stat.StatRangedAttackPower], }, @@ -326,27 +193,22 @@ export const RAID_BUFFS_CONFIG = [ stats: [Stat.StatSpellPower], }, { - config: DamagePercentBuff, - picker: MultiIconPicker, - stats: [Stat.StatAttackPower, Stat.StatRangedAttackPower, Stat.StatSpellPower], - }, - { - config: ResistanceBuff, + config: CritBuff, picker: MultiIconPicker, - stats: [Stat.StatNatureResistance, Stat.StatShadowResistance, Stat.StatFrostResistance], + stats: [Stat.StatCritRating], }, { - config: MP5Buff, + config: MasteryBuff, picker: MultiIconPicker, - stats: [Stat.StatMP5], + stats: [Stat.StatMasteryRating], }, { - config: ReplenishmentBuff, + config: StaminaBuff, picker: MultiIconPicker, - stats: [Stat.StatMP5], + stats: [Stat.StatStamina], }, { - config: Bloodlust, + config: MajorHasteBuff, picker: MultiIconPicker, stats: [Stat.StatHasteRating], }, @@ -358,35 +220,10 @@ export const RAID_BUFFS_CONFIG = [ ] as PickerStatOptions[]; export const RAID_BUFFS_MISC_CONFIG = [ - { - config: DarkIntent, - picker: IconPicker, - stats: [Stat.StatHasteRating], - }, - { - config: FocusMagic, - picker: IconPicker, - stats: [Stat.StatIntellect], - }, - { - config: RetributionAura, - picker: IconPicker, - stats: [Stat.StatArmor], - }, { config: ManaTideTotem, picker: IconPicker, - stats: [Stat.StatMP5], - }, - { - config: Innervate, - picker: IconPicker, - stats: [Stat.StatMP5], - }, - { - config: PowerInfusion, - picker: IconPicker, - stats: [Stat.StatMP5, Stat.StatSpellPower], + stats: [Stat.StatSpirit], }, { config: TricksOfTheTrade, @@ -408,17 +245,12 @@ export const RAID_BUFFS_MISC_CONFIG = [ export const DEBUFFS_CONFIG = [ { config: MajorArmorDebuff, - picker: MultiIconPicker, + picker: IconPicker, stats: [Stat.StatAttackPower, Stat.StatRangedAttackPower], }, { config: PhysicalDamageDebuff, - picker: MultiIconPicker, - stats: [Stat.StatAttackPower, Stat.StatRangedAttackPower], - }, - { - config: BleedDebuff, - picker: MultiIconPicker, + picker: IconPicker, stats: [Stat.StatAttackPower, Stat.StatRangedAttackPower], }, { @@ -426,19 +258,14 @@ export const DEBUFFS_CONFIG = [ picker: MultiIconPicker, stats: [Stat.StatSpellPower], }, - { - config: SpellCritDebuff, - picker: MultiIconPicker, - stats: [Stat.StatIntellect], - }, { config: DamageReduction, picker: MultiIconPicker, stats: [Stat.StatArmor], }, { - config: MeleeAttackSpeedDebuff, - picker: MultiIconPicker, + config: CastSpeedDebuff, + picker: IconPicker, stats: [Stat.StatArmor], }, ] as PickerStatOptions[]; diff --git a/ui/core/components/inputs/consumables.ts b/ui/core/components/inputs/consumables.ts index 5c041a436a..1495cd8a35 100644 --- a/ui/core/components/inputs/consumables.ts +++ b/ui/core/components/inputs/consumables.ts @@ -26,27 +26,24 @@ function makeConsumeInputFactory( args: ConsumeInputFactoryArgs, ): (options: ConsumableStatOption[], tooltip?: string) => InputHelpers.TypedIconEnumPickerConfig, T> { return (options: ConsumableStatOption[], tooltip?: string) => { + const valueOptions = options.map( + option => + ({ + actionId: option.config.actionId, + value: option.config.value, + showWhen: (player: Player) => + (!option.config.showWhen || option.config.showWhen(player)) && (option.config.faction || player.getFaction()) == player.getFaction(), + }) satisfies IconEnumValueConfig, T>, + ); return { type: 'iconEnum', tooltip: tooltip, numColumns: options.length > 5 ? 2 : 1, - values: [{ value: 0 } as unknown as IconEnumValueConfig, T>].concat( - options.map(option => { - const rtn = { - actionId: option.config.actionId, - value: option.config.value, - showWhen: (player: Player) => - (!option.config.showWhen || option.config.showWhen(player)) && - (option.config.faction || player.getFaction()) == player.getFaction(), - } as IconEnumValueConfig, T>; - - return rtn; - }), - ), + values: [{ value: 0, iconUrl: '', tooltip: 'None' } as unknown as IconEnumValueConfig, T>].concat(valueOptions), equals: (a: T, b: T) => a == b, zeroValue: 0 as T, changedEvent: (player: Player) => TypedEvent.onAny([player.consumesChangeEmitter, player.gearChangeEmitter, player.professionChangeEmitter]), - showWhen: (player: Player) => !args.showWhen || args.showWhen(player), + showWhen: (player: Player) => (!args.showWhen || args.showWhen(player)) && valueOptions.some(option => option.showWhen?.(player)), getValue: (player: Player) => player.getConsumes()[args.consumesFieldName] as T, setValue: (eventID: EventID, player: Player, newValue: number) => { const newConsumes = player.getConsumes(); @@ -158,22 +155,22 @@ export function makeConsumableInput( options: ConsumableInputOptions, tooltip?: string, ): InputHelpers.TypedIconEnumPickerConfig, number> { + const valueOptions = items.map(item => ({ + value: item.id, + iconUrl: item.icon, + actionId: ActionId.fromItemId(item.id), + tooltip: item.name, + })); return { type: 'iconEnum', tooltip: tooltip, numColumns: items.length > 5 ? 2 : 1, - values: [{ value: 0, iconUrl: '', tooltip: 'None' }].concat( - items.map(item => ({ - value: item.id, - iconUrl: item.icon, - actionId: ActionId.fromItemId(item.id), - tooltip: item.name, - })), - ), + values: [{ value: 0, iconUrl: '', tooltip: 'None' }].concat(valueOptions), equals: (a: number, b: number) => a === b, zeroValue: 0, changedEvent: (player: Player) => player.consumesChangeEmitter, getValue: (player: Player) => player.getConsumes()[options.consumesFieldName] as number, + showWhen: (_: Player) => !!valueOptions.length, setValue: (eventID: EventID, player: Player, newValue: number) => { if (options.setValue) { options.setValue(eventID, player, newValue); diff --git a/ui/core/components/inputs/other_inputs.ts b/ui/core/components/inputs/other_inputs.ts index 280b6f0d5c..9976398396 100644 --- a/ui/core/components/inputs/other_inputs.ts +++ b/ui/core/components/inputs/other_inputs.ts @@ -113,21 +113,6 @@ export const ChannelClipDelay = { }, }; -export const DarkIntentUptime = { - id: 'dark-intent-uptime', - type: 'number' as const, - label: 'Dark Intent Uptime', - labelTooltip: '% uptime on Dark Intent on the player (Only the stacking damage component)', - changedEvent: (player: Player) => TypedEvent.onAny([player.buffsChangeEmitter, player.miscOptionsChangeEmitter]), - getValue: (player: Player) => player.getDarkIntentUptime(), - setValue: (eventID: EventID, player: Player, newValue: number) => { - player.setDarkIntentUptime(eventID, newValue); - }, - showWhen: (player: Player) => { - return player.getBuffs().darkIntent; - }, -}; - export const InFrontOfTarget = { id: 'in-front-of-target', type: 'boolean' as const, @@ -291,21 +276,3 @@ export const HpPercentForDefensives = { player.setSimpleCooldowns(eventID, cooldowns); }, }; - -export const InspirationUptime = { - id: 'inspiration-uptime', - type: 'number' as const, - float: true, - label: 'Inspiration % Uptime', - labelTooltip: ` -

% average of Encounter Duration, during which you have the Inspiration buff.

-

If set to 0, the buff isn't applied.

- `, - changedEvent: (player: Player) => player.healingModelChangeEmitter, - getValue: (player: Player) => player.getHealingModel().inspirationUptime * 100, - setValue: (eventID: EventID, player: Player, newValue: number) => { - const healingModel = player.getHealingModel(); - healingModel.inspirationUptime = newValue / 100; - player.setHealingModel(eventID, healingModel); - }, -}; diff --git a/ui/core/components/pickers/icon_picker.tsx b/ui/core/components/pickers/icon_picker.tsx index 5c6f5b1deb..c3768735c3 100644 --- a/ui/core/components/pickers/icon_picker.tsx +++ b/ui/core/components/pickers/icon_picker.tsx @@ -85,15 +85,10 @@ export class IconPicker extends Input= 3 && this.config.improvedId) { - this.config.improvedId.fillAndSet(this.improvedAnchor, true, true); - } - if (this.config.states >= 4 && this.config.improvedId2) { - this.config.improvedId2.fillAndSet(this.improvedAnchor2, true, true); - } + this.updateButtonImage() const event = this.config.changedEvent(this.modObject).on(() => { - this.config.actionId.fillAndSet(this.rootAnchor, true, true); + this.updateButtonImage() if (this.showWhen()) { this.rootElem.classList.remove('hide'); @@ -139,6 +134,17 @@ export class IconPicker extends Input event.dispose()); } + updateButtonImage() { + this.config.actionId.fillAndSet(this.rootAnchor, true, true); + + if (this.config.states >= 3 && this.config.improvedId) { + this.config.improvedId.fillAndSet(this.improvedAnchor, true, true, { signal: this.signal }); + } + if (this.config.states >= 4 && this.config.improvedId2) { + this.config.improvedId2.fillAndSet(this.improvedAnchor2, true, true, { signal: this.signal }); + } + } + handleLeftClick() { if (this.config.states == 0 || this.currentValue + 1 < this.config.states) { this.currentValue++; diff --git a/ui/core/components/pickers/multi_icon_picker.ts b/ui/core/components/pickers/multi_icon_picker.tsx similarity index 81% rename from ui/core/components/pickers/multi_icon_picker.ts rename to ui/core/components/pickers/multi_icon_picker.tsx index 40f8e90333..36d8abcd05 100644 --- a/ui/core/components/pickers/multi_icon_picker.ts +++ b/ui/core/components/pickers/multi_icon_picker.tsx @@ -1,10 +1,12 @@ +import { ref } from 'tsx-vanilla'; + import { Player } from '../../player.js'; import { ActionId } from '../../proto_utils/action_id.js'; -import { SimUI } from '../../sim_ui.js'; +import { SimUI } from '../../sim_ui.jsx'; import { TypedEvent } from '../../typed_event.js'; import { existsInDOM, isRightClick } from '../../utils.js'; import { Component } from '../component.js'; -import { IconPicker, IconPickerConfig } from './icon_picker.js'; +import { IconPicker, IconPickerConfig } from './icon_picker.jsx'; export interface MultiIconPickerItemConfig extends IconPickerConfig {} @@ -40,30 +42,39 @@ export class MultiIconPicker extends Component { this.config = config; this.currentValue = null; - this.rootElem.innerHTML = ` -
- - -
- - `; - - const labelElem = this.rootElem.querySelector('.multi-icon-picker-label') as HTMLElement; + const buttonRef = ref(); + const dropdownRef = ref(); + const labelRef = ref(); + + this.rootElem.replaceChildren( + <> +
+ +
    +
    + + , + ); + + const labelElem = labelRef.value!; if (config.label) { labelElem.textContent = config.label; } else { labelElem.remove(); } - this.buttonElem = this.rootElem.querySelector('.icon-picker-button') as HTMLAnchorElement; - this.dropdownMenu = this.rootElem.querySelector('.dropdown-menu') as HTMLElement; + this.buttonElem = buttonRef.value!; + this.dropdownMenu = dropdownRef.value!; this.buttonElem.addEventListener( 'hide.bs.dropdown', @@ -148,14 +159,14 @@ export class MultiIconPicker extends Component { if (this.currentValue) { this.buttonElem.classList.add('active'); if (this.config.categoryId != null) { - this.config.categoryId.fillAndSet(this.buttonElem, false, true); + this.config.categoryId.fillAndSet(this.buttonElem, false, true, { signal: this.signal }); } else { - this.currentValue.fillAndSet(this.buttonElem, false, true); + this.currentValue.fillAndSet(this.buttonElem, false, true, { signal: this.signal }); } } else { this.buttonElem.classList.remove('active'); if (this.config.categoryId != null) { - this.config.categoryId.fillAndSet(this.buttonElem, false, true); + this.config.categoryId.fillAndSet(this.buttonElem, false, true, { signal: this.signal }); } else { this.buttonElem.style.backgroundImage = ''; } diff --git a/ui/core/individual_sim_ui.tsx b/ui/core/individual_sim_ui.tsx index 5bdfd151cf..6386947864 100644 --- a/ui/core/individual_sim_ui.tsx +++ b/ui/core/individual_sim_ui.tsx @@ -37,7 +37,7 @@ import { PresetBuild, PresetEpWeights, PresetGear, PresetItemSwap, PresetRotatio import { StatWeightsResult } from './proto/api'; import { APLRotation, APLRotation_Type as APLRotationType } from './proto/apl'; import { - ConsumesSpec, + ConsumesSpec, Cooldowns, Debuffs, Encounter as EncounterProto, @@ -86,7 +86,6 @@ export interface OtherDefaults { profession2?: Profession; distanceFromTarget?: number; channelClipDelay?: number; - darkIntentUptime?: number; highHpThreshold?: number; iterationCount?: number; } @@ -554,7 +553,6 @@ export abstract class IndividualSimUI extends SimUI { this.player.setDistanceFromTarget(eventID, this.individualConfig.defaults.other?.distanceFromTarget || 0); this.player.setChannelClipDelay(eventID, this.individualConfig.defaults.other?.channelClipDelay || 0); - this.player.setDarkIntentUptime(eventID, this.individualConfig.defaults.other?.darkIntentUptime || 100); if (this.isWithinRaidSim) { this.sim.raid.setTargetDummies(eventID, 0); diff --git a/ui/core/player.ts b/ui/core/player.ts index 2f29f5c81b..f25a51916f 100644 --- a/ui/core/player.ts +++ b/ui/core/player.ts @@ -250,7 +250,6 @@ export class Player { private channelClipDelay = 0; private inFrontOfTarget = false; private distanceFromTarget = 0; - private darkIntentUptime = 100; private healingModel: HealingModel = HealingModel.create(); private healingEnabled = false; @@ -990,17 +989,6 @@ export class Player { this.miscOptionsChangeEmitter.emit(eventID); } - getDarkIntentUptime(): number { - return this.darkIntentUptime; - } - - setDarkIntentUptime(eventID: EventID, newDarkIntentUptime: number) { - if (newDarkIntentUptime == this.darkIntentUptime) return; - - this.darkIntentUptime = newDarkIntentUptime; - this.miscOptionsChangeEmitter.emit(eventID); - } - getInFrontOfTarget(): boolean { return this.inFrontOfTarget; } @@ -1484,7 +1472,6 @@ export class Player { inFrontOfTarget: this.getInFrontOfTarget(), distanceFromTarget: this.getDistanceFromTarget(), healingModel: this.getHealingModel(), - darkIntentUptime: this.getDarkIntentUptime(), }); player = withSpec(this.getSpec(), player, this.getSpecOptions()); } @@ -1540,7 +1527,6 @@ export class Player { this.setInFrontOfTarget(eventID, proto.inFrontOfTarget); this.setDistanceFromTarget(eventID, proto.distanceFromTarget); this.setHealingModel(eventID, proto.healingModel || HealingModel.create()); - this.setDarkIntentUptime(eventID, proto.darkIntentUptime); } if (loadCategory(SimSettingCategories.External)) { this.setBuffs(eventID, proto.buffs || IndividualBuffs.create()); diff --git a/ui/core/proto_utils/action_id.ts b/ui/core/proto_utils/action_id.ts index 3d28409bef..85fd399190 100644 --- a/ui/core/proto_utils/action_id.ts +++ b/ui/core/proto_utils/action_id.ts @@ -232,8 +232,8 @@ export class ActionId { this.setWowheadHref(elem); } - async fillAndSet(elem: HTMLAnchorElement, setHref: boolean, setBackground: boolean): Promise { - const filled = await this.fill(); + async fillAndSet(elem: HTMLAnchorElement, setHref: boolean, setBackground: boolean, options: { signal?: AbortSignal } = {}): Promise { + const filled = await this.fill(undefined, options); if (setHref) { filled.setWowheadHref(elem); } diff --git a/ui/death_knight/blood/sim.ts b/ui/death_knight/blood/sim.ts index f1497b8eb6..95a863659e 100644 --- a/ui/death_knight/blood/sim.ts +++ b/ui/death_knight/blood/sim.ts @@ -83,29 +83,10 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecBloodDeathKnight, { // Default spec-specific settings. specOptions: Presets.DefaultOptions, // Default raid/party buffs settings. - raidBuffs: RaidBuffs.create({ - retributionAura: true, - powerWordFortitude: true, - markOfTheWild: true, - icyTalons: true, - hornOfWinter: true, - abominationsMight: true, - leaderOfThePack: true, - bloodlust: true, - arcaneTactics: true, - devotionAura: true, - resistanceAura: true, - }), + raidBuffs: RaidBuffs.create({}), partyBuffs: PartyBuffs.create({}), individualBuffs: IndividualBuffs.create({}), - debuffs: Debuffs.create({ - bloodFrenzy: true, - faerieFire: true, - ebonPlaguebringer: true, - criticalMass: true, - vindication: true, - frostFever: true, - }), + debuffs: Debuffs.create({}), }, // modifyDisplayStats: (player: Player) => { @@ -116,8 +97,8 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecBloodDeathKnight, { // Inputs to include in the 'Rotation' section on the settings tab. rotationInputs: BloodInputs.BloodDeathKnightRotationConfig, // Buff and Debuff inputs to include/exclude, overriding the EP-based defaults. - includeBuffDebuffInputs: [BuffDebuffInputs.SpellDamageDebuff, BuffDebuffInputs.SpellCritDebuff], - excludeBuffDebuffInputs: [BuffDebuffInputs.SpellHasteBuff, BuffDebuffInputs.BleedDebuff], + includeBuffDebuffInputs: [BuffDebuffInputs.SpellDamageDebuff], + excludeBuffDebuffInputs: [BuffDebuffInputs.SpellHasteBuff], // Inputs to include in the 'Other' section on the settings tab. otherInputs: { inputs: [ @@ -129,10 +110,8 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecBloodDeathKnight, { OtherInputs.HealingCadenceVariation, OtherInputs.AbsorbFrac, OtherInputs.BurstWindow, - OtherInputs.InspirationUptime, OtherInputs.InFrontOfTarget, DeathKnightInputs.StartingRunicPower(), - OtherInputs.DarkIntentUptime, ], }, itemSwapSlots: [ diff --git a/ui/death_knight/frost/sim.ts b/ui/death_knight/frost/sim.ts index 0219635f2b..377c61deb8 100644 --- a/ui/death_knight/frost/sim.ts +++ b/ui/death_knight/frost/sim.ts @@ -86,27 +86,10 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecFrostDeathKnight, { // Default spec-specific settings. specOptions: Presets.DefaultOptions, // Default raid/party buffs settings. - raidBuffs: RaidBuffs.create({ - devotionAura: true, - bloodlust: true, - markOfTheWild: true, - icyTalons: true, - leaderOfThePack: true, - powerWordFortitude: true, - hornOfWinter: true, - abominationsMight: true, - arcaneTactics: true, - }), - partyBuffs: PartyBuffs.create({ - heroicPresence: false, - }), + raidBuffs: RaidBuffs.create({}), + partyBuffs: PartyBuffs.create({}), individualBuffs: IndividualBuffs.create({}), - debuffs: Debuffs.create({ - faerieFire: true, - brittleBones: true, - ebonPlaguebringer: true, - shadowAndFlame: true, - }), + debuffs: Debuffs.create({}), }, autoRotation: (player: Player): APLRotation => { @@ -125,8 +108,8 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecFrostDeathKnight, { playerIconInputs: [], petConsumeInputs: [], // Buff and Debuff inputs to include/exclude, overriding the EP-based defaults. - includeBuffDebuffInputs: [BuffDebuffInputs.SpellDamageDebuff, BuffDebuffInputs.SpellCritDebuff], - excludeBuffDebuffInputs: [BuffDebuffInputs.DamageReduction, BuffDebuffInputs.MeleeAttackSpeedDebuff, BuffDebuffInputs.BleedDebuff], + includeBuffDebuffInputs: [BuffDebuffInputs.SpellDamageDebuff], + excludeBuffDebuffInputs: [BuffDebuffInputs.DamageReduction, BuffDebuffInputs.CastSpeedDebuff], // Inputs to include in the 'Other' section on the settings tab. otherInputs: { inputs: [ @@ -138,7 +121,6 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecFrostDeathKnight, { // OtherInputs.TankAssignment, OtherInputs.InFrontOfTarget, OtherInputs.InputDelay, - OtherInputs.DarkIntentUptime, ], }, itemSwapSlots: [ diff --git a/ui/death_knight/unholy/sim.ts b/ui/death_knight/unholy/sim.ts index 677b87fe7c..830fecf926 100644 --- a/ui/death_knight/unholy/sim.ts +++ b/ui/death_knight/unholy/sim.ts @@ -78,25 +78,10 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecUnholyDeathKnight, { // Default spec-specific settings. specOptions: Presets.DefaultOptions, // Default raid/party buffs settings. - raidBuffs: RaidBuffs.create({ - devotionAura: true, - bloodlust: true, - markOfTheWild: true, - icyTalons: true, - leaderOfThePack: true, - powerWordFortitude: true, - hornOfWinter: true, - abominationsMight: true, - arcaneTactics: true, - }), + raidBuffs: RaidBuffs.create({}), partyBuffs: PartyBuffs.create({}), individualBuffs: IndividualBuffs.create({}), - debuffs: Debuffs.create({ - faerieFire: true, - brittleBones: true, - ebonPlaguebringer: true, - shadowAndFlame: true, - }), + debuffs: Debuffs.create({}), }, autoRotation: (_: Player): APLRotation => Presets.DEFAULT_ROTATION_PRESET.rotation.rotation!, @@ -105,8 +90,8 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecUnholyDeathKnight, { playerIconInputs: [], petConsumeInputs: [], // Buff and Debuff inputs to include/exclude, overriding the EP-based defaults. - includeBuffDebuffInputs: [BuffDebuffInputs.SpellDamageDebuff, BuffDebuffInputs.SpellCritDebuff], - excludeBuffDebuffInputs: [BuffDebuffInputs.DamageReduction, BuffDebuffInputs.MeleeAttackSpeedDebuff, BuffDebuffInputs.BleedDebuff], + includeBuffDebuffInputs: [BuffDebuffInputs.SpellDamageDebuff], + excludeBuffDebuffInputs: [BuffDebuffInputs.DamageReduction, BuffDebuffInputs.CastSpeedDebuff], // Inputs to include in the 'Other' section on the settings tab. otherInputs: { inputs: [ @@ -119,7 +104,6 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecUnholyDeathKnight, { // OtherInputs.TankAssignment, OtherInputs.InFrontOfTarget, OtherInputs.InputDelay, - OtherInputs.DarkIntentUptime, ], }, itemSwapSlots: [ diff --git a/ui/druid/balance/presets.ts b/ui/druid/balance/presets.ts index 340436735f..c36879eea5 100644 --- a/ui/druid/balance/presets.ts +++ b/ui/druid/balance/presets.ts @@ -1,15 +1,5 @@ import * as PresetUtils from '../../core/preset_utils.js'; -import { - ConsumesSpec, - Debuffs, - Glyphs, - IndividualBuffs, - PartyBuffs, - Profession, - RaidBuffs, - Stat, - UnitReference, -} from '../../core/proto/common.js'; +import { ConsumesSpec, Debuffs, Glyphs, IndividualBuffs, PartyBuffs, Profession, RaidBuffs, Stat, UnitReference } from '../../core/proto/common.js'; import { BalanceDruid_Options as BalanceDruidOptions, DruidMajorGlyph } from '../../core/proto/druid.js'; import { SavedTalents } from '../../core/proto/ui.js'; import { Stats } from '../../core/proto_utils/stats'; @@ -70,45 +60,26 @@ export const DefaultConsumables = ConsumesSpec.create({ potId: 58091, // Volcanic Potion prepotId: 58091, // Volcanic Potion }); -export const DefaultRaidBuffs = RaidBuffs.create({ - arcaneBrilliance: true, - bloodlust: true, - markOfTheWild: true, - icyTalons: true, - moonkinForm: true, - leaderOfThePack: true, - powerWordFortitude: true, - strengthOfEarthTotem: true, - trueshotAura: true, - wrathOfAirTotem: true, - demonicPact: true, - blessingOfKings: true, - blessingOfMight: true, - communion: true, -}); +export const DefaultRaidBuffs = RaidBuffs.create({}); -export const DefaultIndividualBuffs = IndividualBuffs.create({ - vampiricTouch: true, - darkIntent: true, -}); +export const DefaultIndividualBuffs = IndividualBuffs.create({}); export const DefaultPartyBuffs = PartyBuffs.create({}); export const DefaultDebuffs = Debuffs.create({ - bloodFrenzy: true, - sunderArmor: true, - ebonPlaguebringer: true, - mangle: true, - criticalMass: true, - demoralizingShout: true, - frostFever: true, + // bloodFrenzy: true, + // sunderArmor: true, + // ebonPlaguebringer: true, + // mangle: true, + // criticalMass: true, + // demoralizingShout: true, + // frostFever: true, }); export const OtherDefaults = { distanceFromTarget: 20, profession1: Profession.Engineering, profession2: Profession.Tailoring, - darkIntentUptime: 100, }; export const PresetBuildPreraid = PresetUtils.makePresetBuild('Balance Pre-raid', { diff --git a/ui/druid/balance/sim.ts b/ui/druid/balance/sim.ts index 819e1f21b5..537903d269 100644 --- a/ui/druid/balance/sim.ts +++ b/ui/druid/balance/sim.ts @@ -70,18 +70,11 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecBalanceDruid, { // IconInputs to include in the 'Player' section on the settings tab. playerIconInputs: [DruidInputs.SelfInnervate()], // Buff and Debuff inputs to include/exclude, overriding the EP-based defaults. - includeBuffDebuffInputs: [ - BuffDebuffInputs.ReplenishmentBuff, - BuffDebuffInputs.CritBuff, - BuffDebuffInputs.MP5Buff, - BuffDebuffInputs.AttackPowerPercentBuff, - BuffDebuffInputs.StaminaBuff, - BuffDebuffInputs.ManaBuff, - ], + includeBuffDebuffInputs: [], excludeBuffDebuffInputs: [], // Inputs to include in the 'Other' section on the settings tab. otherInputs: { - inputs: [BalanceInputs.OkfUptime, OtherInputs.TankAssignment, OtherInputs.InputDelay, OtherInputs.DistanceFromTarget, OtherInputs.DarkIntentUptime], + inputs: [BalanceInputs.OkfUptime, OtherInputs.TankAssignment, OtherInputs.InputDelay, OtherInputs.DistanceFromTarget], }, itemSwapSlots: [ItemSlot.ItemSlotMainHand, ItemSlot.ItemSlotHands, ItemSlot.ItemSlotTrinket1, ItemSlot.ItemSlotTrinket2], encounterPicker: { diff --git a/ui/druid/feral/sim.ts b/ui/druid/feral/sim.ts index 719c8f6174..d96ef64fac 100644 --- a/ui/druid/feral/sim.ts +++ b/ui/druid/feral/sim.ts @@ -64,21 +64,10 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecFeralDruid, { // Default spec-specific settings. specOptions: Presets.DefaultOptions, // Default raid/party buffs settings. - raidBuffs: RaidBuffs.create({ - markOfTheWild: true, - strengthOfEarthTotem: true, - abominationsMight: true, - windfuryTotem: true, - bloodlust: true, - communion: true, - arcaneBrilliance: true, - manaSpringTotem: true, - }), + raidBuffs: RaidBuffs.create({}), partyBuffs: PartyBuffs.create({}), individualBuffs: IndividualBuffs.create({}), - debuffs: Debuffs.create({ - bloodFrenzy: true, - }), + debuffs: Debuffs.create({}), }, // IconInputs to include in the 'Player' section on the settings tab. @@ -86,7 +75,7 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecFeralDruid, { // Inputs to include in the 'Rotation' section on the settings tab. rotationInputs: FeralInputs.FeralDruidRotationConfig, // Buff and Debuff inputs to include/exclude, overriding the EP-based defaults. - includeBuffDebuffInputs: [BuffDebuffInputs.ManaBuff, BuffDebuffInputs.MP5Buff], + includeBuffDebuffInputs: [], excludeBuffDebuffInputs: [], // Inputs to include in the 'Other' section on the settings tab. otherInputs: { @@ -97,7 +86,6 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecFeralDruid, { OtherInputs.TankAssignment, OtherInputs.InFrontOfTarget, FeralInputs.CannotShredTarget, - OtherInputs.DarkIntentUptime, ], }, itemSwapSlots: [ItemSlot.ItemSlotMainHand, ItemSlot.ItemSlotHands, ItemSlot.ItemSlotTrinket1, ItemSlot.ItemSlotTrinket2], diff --git a/ui/druid/guardian/sim.ts b/ui/druid/guardian/sim.ts index 02c6cd67a0..362bad2760 100644 --- a/ui/druid/guardian/sim.ts +++ b/ui/druid/guardian/sim.ts @@ -106,23 +106,14 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecGuardianDruid, { // Default spec-specific settings. specOptions: Presets.DefaultOptions, // Default raid/party buffs settings. - raidBuffs: RaidBuffs.create({ - powerWordFortitude: true, - markOfTheWild: true, - bloodlust: true, - strengthOfEarthTotem: true, - abominationsMight: true, - windfuryTotem: true, - communion: true, - devotionAura: true, - }), + raidBuffs: RaidBuffs.create({}), partyBuffs: PartyBuffs.create({}), individualBuffs: IndividualBuffs.create({}), debuffs: Debuffs.create({ - ebonPlaguebringer: true, - criticalMass: true, - bloodFrenzy: true, - frostFever: true, + // ebonPlaguebringer: true, + // criticalMass: true, + // bloodFrenzy: true, + // frostFever: true, }), }, @@ -131,7 +122,7 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecGuardianDruid, { // Inputs to include in the 'Rotation' section on the settings tab. rotationInputs: DruidInputs.GuardianDruidRotationConfig, // Buff and Debuff inputs to include/exclude, overriding the EP-based defaults. - includeBuffDebuffInputs: [BuffDebuffInputs.SpellCritDebuff, BuffDebuffInputs.SpellDamageDebuff], + includeBuffDebuffInputs: [BuffDebuffInputs.SpellDamageDebuff], excludeBuffDebuffInputs: [], // Inputs to include in the 'Other' section on the settings tab. otherInputs: { @@ -143,7 +134,6 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecGuardianDruid, { OtherInputs.HealingCadenceVariation, OtherInputs.AbsorbFrac, OtherInputs.BurstWindow, - OtherInputs.InspirationUptime, OtherInputs.HpPercentForDefensives, DruidInputs.StartingRage, OtherInputs.InFrontOfTarget, diff --git a/ui/druid/restoration/presets.ts b/ui/druid/restoration/presets.ts index e7baea4fda..023b3318c8 100644 --- a/ui/druid/restoration/presets.ts +++ b/ui/druid/restoration/presets.ts @@ -71,37 +71,20 @@ export const DefaultConsumables = ConsumesSpec.create({ foodId: 62290, // Seafood Magnifique Feast potId: 57192, // Mythical Mana Potion }); -export const DefaultRaidBuffs = RaidBuffs.create({ - arcaneBrilliance: true, - bloodlust: true, - markOfTheWild: true, - icyTalons: true, - moonkinForm: true, - leaderOfThePack: true, - powerWordFortitude: true, - strengthOfEarthTotem: true, - trueshotAura: true, - wrathOfAirTotem: true, - demonicPact: true, - blessingOfKings: true, - blessingOfMight: true, - communion: true, -}); +export const DefaultRaidBuffs = RaidBuffs.create({}); -export const DefaultIndividualBuffs = IndividualBuffs.create({ - vampiricTouch: true, -}); +export const DefaultIndividualBuffs = IndividualBuffs.create({}); export const DefaultPartyBuffs = PartyBuffs.create({}); export const DefaultDebuffs = Debuffs.create({ - bloodFrenzy: true, - sunderArmor: true, - ebonPlaguebringer: true, - mangle: true, - criticalMass: true, - demoralizingShout: true, - frostFever: true, + // bloodFrenzy: true, + // sunderArmor: true, + // ebonPlaguebringer: true, + // mangle: true, + // criticalMass: true, + // demoralizingShout: true, + // frostFever: true, }); export const OtherDefaults = { diff --git a/ui/hunter/beast_mastery/sim.ts b/ui/hunter/beast_mastery/sim.ts index 1d9df72451..ba11229cf8 100644 --- a/ui/hunter/beast_mastery/sim.ts +++ b/ui/hunter/beast_mastery/sim.ts @@ -86,31 +86,14 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecBeastMasteryHunter, { // Default spec-specific settings. specOptions: Presets.BMDefaultOptions, // Default raid/party buffs settings. - raidBuffs: RaidBuffs.create({ - arcaneBrilliance: true, - bloodlust: true, - markOfTheWild: true, - icyTalons: true, - moonkinForm: true, - leaderOfThePack: true, - powerWordFortitude: true, - strengthOfEarthTotem: true, - trueshotAura: true, - wrathOfAirTotem: true, - demonicPact: true, - blessingOfKings: true, - blessingOfMight: true, - communion: true, - }), + raidBuffs: RaidBuffs.create({}), partyBuffs: PartyBuffs.create({}), - individualBuffs: IndividualBuffs.create({ - vampiricTouch: true, - }), + individualBuffs: IndividualBuffs.create({}), debuffs: Debuffs.create({ - faerieFire: true, - curseOfElements: true, - savageCombat: true, - bloodFrenzy: true, + // faerieFire: true, + // curseOfElements: true, + // savageCombat: true, + // bloodFrenzy: true, }), }, @@ -132,7 +115,6 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecBeastMasteryHunter, { OtherInputs.DistanceFromTarget, OtherInputs.TankAssignment, OtherInputs.InFrontOfTarget, - OtherInputs.DarkIntentUptime, ], }, encounterPicker: { diff --git a/ui/hunter/marksmanship/sim.ts b/ui/hunter/marksmanship/sim.ts index 249bb84681..2b96b4b4fc 100644 --- a/ui/hunter/marksmanship/sim.ts +++ b/ui/hunter/marksmanship/sim.ts @@ -86,32 +86,15 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecMarksmanshipHunter, { // Default spec-specific settings. specOptions: Presets.MMDefaultOptions, // Default raid/party buffs settings. - raidBuffs: RaidBuffs.create({ - arcaneBrilliance: true, - bloodlust: true, - markOfTheWild: true, - icyTalons: true, - moonkinForm: true, - leaderOfThePack: true, - powerWordFortitude: true, - strengthOfEarthTotem: true, - trueshotAura: true, - wrathOfAirTotem: true, - demonicPact: true, - blessingOfKings: true, - blessingOfMight: true, - communion: true, - }), + raidBuffs: RaidBuffs.create({}), partyBuffs: PartyBuffs.create({}), - individualBuffs: IndividualBuffs.create({ - vampiricTouch: true, - }), + individualBuffs: IndividualBuffs.create({}), debuffs: Debuffs.create({ - sunderArmor: true, - faerieFire: true, - curseOfElements: true, - savageCombat: true, - bloodFrenzy: true, + // sunderArmor: true, + // faerieFire: true, + // curseOfElements: true, + // savageCombat: true, + // bloodFrenzy: true, }), }, @@ -133,7 +116,6 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecMarksmanshipHunter, { OtherInputs.DistanceFromTarget, OtherInputs.TankAssignment, OtherInputs.InFrontOfTarget, - OtherInputs.DarkIntentUptime, ], }, encounterPicker: { diff --git a/ui/hunter/survival/sim.ts b/ui/hunter/survival/sim.ts index 2bc2b6ba0e..383c6bb4dd 100644 --- a/ui/hunter/survival/sim.ts +++ b/ui/hunter/survival/sim.ts @@ -93,31 +93,14 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecSurvivalHunter, { // Default spec-specific settings. specOptions: Presets.SVDefaultOptions, // Default raid/party buffs settings. - raidBuffs: RaidBuffs.create({ - arcaneBrilliance: true, - bloodlust: true, - markOfTheWild: true, - icyTalons: true, - moonkinForm: true, - leaderOfThePack: true, - powerWordFortitude: true, - strengthOfEarthTotem: true, - trueshotAura: true, - wrathOfAirTotem: true, - demonicPact: true, - blessingOfKings: true, - blessingOfMight: true, - communion: true, - }), + raidBuffs: RaidBuffs.create({}), partyBuffs: PartyBuffs.create({}), - individualBuffs: IndividualBuffs.create({ - vampiricTouch: true, - }), + individualBuffs: IndividualBuffs.create({}), debuffs: Debuffs.create({ - faerieFire: true, - curseOfElements: true, - savageCombat: true, - bloodFrenzy: true, + // faerieFire: true, + // curseOfElements: true, + // savageCombat: true, + // bloodFrenzy: true, }), }, @@ -139,7 +122,6 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecSurvivalHunter, { OtherInputs.DistanceFromTarget, OtherInputs.TankAssignment, OtherInputs.InFrontOfTarget, - OtherInputs.DarkIntentUptime, ], }, encounterPicker: { diff --git a/ui/mage/arcane/presets.ts b/ui/mage/arcane/presets.ts index 854ce177e7..7531164c8e 100644 --- a/ui/mage/arcane/presets.ts +++ b/ui/mage/arcane/presets.ts @@ -1,13 +1,5 @@ import * as PresetUtils from '../../core/preset_utils'; -import { - ConsumesSpec, - Debuffs, - Glyphs, - Profession, - RaidBuffs, - Stat, - UnitReference, -} from '../../core/proto/common'; +import { ConsumesSpec, Debuffs, Glyphs, Profession, RaidBuffs, Stat, UnitReference } from '../../core/proto/common'; import { ArcaneMage_Options as MageOptions, MageMajorGlyph as MajorGlyph } from '../../core/proto/mage'; import { SavedTalents } from '../../core/proto/ui'; import { Stats } from '../../core/proto_utils/stats'; @@ -74,26 +66,11 @@ export const DefaultConsumables = ConsumesSpec.create({ prepotId: 58091, // Volcanic Potion tinkerId: 82174, // Synapse Springs }); -export const DefaultRaidBuffs = RaidBuffs.create({ - arcaneBrilliance: true, - bloodlust: true, - markOfTheWild: true, - icyTalons: true, - moonkinForm: true, - leaderOfThePack: true, - powerWordFortitude: true, - strengthOfEarthTotem: true, - trueshotAura: true, - wrathOfAirTotem: true, - demonicPact: true, - blessingOfKings: true, - blessingOfMight: true, - communion: true, -}); +export const DefaultRaidBuffs = RaidBuffs.create({}); export const DefaultDebuffs = Debuffs.create({ - ebonPlaguebringer: true, - shadowAndFlame: true, + // ebonPlaguebringer: true, + // shadowAndFlame: true, }); export const OtherDefaults = { diff --git a/ui/mage/arcane/sim.ts b/ui/mage/arcane/sim.ts index d4345bdc72..f6a436add2 100644 --- a/ui/mage/arcane/sim.ts +++ b/ui/mage/arcane/sim.ts @@ -64,9 +64,7 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecArcaneMage, { partyBuffs: PartyBuffs.create({ manaTideTotems: 1, }), - individualBuffs: IndividualBuffs.create({ - vampiricTouch: true, - }), + individualBuffs: IndividualBuffs.create({}), debuffs: Presets.DefaultDebuffs, }, @@ -75,13 +73,7 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecArcaneMage, { // Inputs to include in the 'Rotation' section on the settings tab. rotationInputs: ArcaneInputs.MageRotationConfig, // Buff and Debuff inputs to include/exclude, overriding the EP-based defaults. - includeBuffDebuffInputs: [ - BuffDebuffInputs.ReplenishmentBuff, - BuffDebuffInputs.CritBuff, - BuffDebuffInputs.MP5Buff, - BuffDebuffInputs.StaminaBuff, - BuffDebuffInputs.ManaBuff, - ], + includeBuffDebuffInputs: [], excludeBuffDebuffInputs: [], // Inputs to include in the 'Other' section on the settings tab. otherInputs: { diff --git a/ui/mage/fire/presets.ts b/ui/mage/fire/presets.ts index 2f48608854..9b7556b355 100644 --- a/ui/mage/fire/presets.ts +++ b/ui/mage/fire/presets.ts @@ -1,15 +1,5 @@ import * as PresetUtils from '../../core/preset_utils'; -import { - ConsumesSpec, - Debuffs, - Glyphs, - Profession, - PseudoStat, - Race, - RaidBuffs, - Spec, - Stat, -} from '../../core/proto/common'; +import { ConsumesSpec, Debuffs, Glyphs, Profession, PseudoStat, Race, RaidBuffs, Spec, Stat } from '../../core/proto/common'; import { FireMage_Options as MageOptions, FireMage_Rotation, MageMajorGlyph as MajorGlyph, MageMinorGlyph as MinorGlyph } from '../../core/proto/mage'; import { SavedTalents } from '../../core/proto/ui'; import { Stats, UnitStat, UnitStatPresets } from '../../core/proto_utils/stats'; @@ -102,22 +92,7 @@ export const DefaultFireOptions = MageOptions.create({ classOptions: {}, }); -export const DefaultRaidBuffs = RaidBuffs.create({ - arcaneBrilliance: true, - bloodlust: true, - markOfTheWild: true, - icyTalons: true, - moonkinForm: true, - leaderOfThePack: true, - powerWordFortitude: true, - strengthOfEarthTotem: true, - trueshotAura: true, - wrathOfAirTotem: true, - demonicPact: true, - blessingOfKings: true, - blessingOfMight: true, - communion: true, -}); +export const DefaultRaidBuffs = RaidBuffs.create({}); export const DefaultFireConsumables = ConsumesSpec.create({ flaskId: 58086, // Flask of the Draconic Mind @@ -128,8 +103,8 @@ export const DefaultFireConsumables = ConsumesSpec.create({ }); export const DefaultDebuffs = Debuffs.create({ - ebonPlaguebringer: true, - shadowAndFlame: true, + // ebonPlaguebringer: true, + // shadowAndFlame: true, }); export const OtherDefaults = { diff --git a/ui/mage/fire/sim.tsx b/ui/mage/fire/sim.tsx index 231436ce99..57112d1424 100644 --- a/ui/mage/fire/sim.tsx +++ b/ui/mage/fire/sim.tsx @@ -84,7 +84,6 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecFireMage, { }), individualBuffs: IndividualBuffs.create({ innervateCount: 0, - vampiricTouch: true, }), debuffs: Presets.DefaultDebuffs, }, @@ -94,17 +93,11 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecFireMage, { // Inputs to include in the 'Rotation' section on the settings tab. rotationInputs: FireInputs.MageRotationConfig, // Buff and Debuff inputs to include/exclude, overriding the EP-based defaults. - includeBuffDebuffInputs: [ - BuffDebuffInputs.ReplenishmentBuff, - BuffDebuffInputs.CritBuff, - BuffDebuffInputs.MP5Buff, - BuffDebuffInputs.StaminaBuff, - BuffDebuffInputs.ManaBuff, - ], + includeBuffDebuffInputs: [], excludeBuffDebuffInputs: [], // Inputs to include in the 'Other' section on the settings tab. otherInputs: { - inputs: [OtherInputs.InputDelay, OtherInputs.DistanceFromTarget, OtherInputs.TankAssignment, OtherInputs.DarkIntentUptime], + inputs: [OtherInputs.InputDelay, OtherInputs.DistanceFromTarget, OtherInputs.TankAssignment], }, itemSwapSlots: [ItemSlot.ItemSlotMainHand, ItemSlot.ItemSlotHands, ItemSlot.ItemSlotTrinket1, ItemSlot.ItemSlotTrinket2], encounterPicker: { @@ -233,7 +226,6 @@ export class FireMageSimUI extends IndividualSimUI { updateSoftCaps: softCaps => { const raidBuffs = player.getRaid()?.getBuffs(); const hasBL = !!(raidBuffs?.bloodlust || raidBuffs?.timeWarp || raidBuffs?.heroism); - const hasPI = !!player.getBuffs().powerInfusionCount; const hasBerserking = player.getRace() === Race.RaceTroll; const modifyHaste = (oldHastePercent: number, modifier: number) => @@ -268,7 +260,7 @@ export class FireMageSimUI extends IndividualSimUI { } } } - if (hasPI && !isExcludedFromPiZerk) { + if (!isExcludedFromPiZerk) { const piBreakpoint = modifyHaste(breakpoint, 1.2); if (piBreakpoint > 0) { if (!hasCloseMatchingValue(piBreakpoint)) adjustedHastedBreakpoints.add(piBreakpoint); @@ -290,17 +282,15 @@ export class FireMageSimUI extends IndividualSimUI { [Stat.StatHasteRating]: () => { const raidBuffs = player.getRaid()?.getBuffs(); const hasBL = !!(raidBuffs?.bloodlust || raidBuffs?.timeWarp || raidBuffs?.heroism); - const hasPI = !!player.getBuffs().powerInfusionCount; const hasBerserking = player.getRace() === Race.RaceTroll; return ( <> - {(hasBL || hasPI || hasBerserking) && ( + {(hasBL || hasBerserking) && ( <>

    Additional breakpoints have been created using the following cooldowns:

      {hasBL &&
    • Bloodlust
    • } - {hasPI &&
    • Power Infusion
    • } {hasBerserking &&
    • Berserking
    • }
    diff --git a/ui/mage/frost/sim.ts b/ui/mage/frost/sim.ts index 0b367e539a..008146e6e0 100644 --- a/ui/mage/frost/sim.ts +++ b/ui/mage/frost/sim.ts @@ -46,33 +46,16 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecFrostMage, { specOptions: Presets.DefaultFrostOptions, other: Presets.OtherDefaults, // Default raid/party buffs settings. - raidBuffs: RaidBuffs.create({ - arcaneBrilliance: true, - bloodlust: true, - markOfTheWild: true, - icyTalons: true, - moonkinForm: true, - leaderOfThePack: true, - powerWordFortitude: true, - strengthOfEarthTotem: true, - trueshotAura: true, - wrathOfAirTotem: true, - demonicPact: true, - blessingOfKings: true, - blessingOfMight: true, - communion: true, - }), + raidBuffs: RaidBuffs.create({}), partyBuffs: PartyBuffs.create({ manaTideTotems: 1, }), individualBuffs: IndividualBuffs.create({ innervateCount: 0, - vampiricTouch: true, - focusMagic: true, }), debuffs: Debuffs.create({ - ebonPlaguebringer: true, - shadowAndFlame: true, + // ebonPlaguebringer: true, + // shadowAndFlame: true, }), }, diff --git a/ui/monk/brewmaster/sim.ts b/ui/monk/brewmaster/sim.ts index e047bbbe91..7a95468bc9 100644 --- a/ui/monk/brewmaster/sim.ts +++ b/ui/monk/brewmaster/sim.ts @@ -77,49 +77,26 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecBrewmasterMonk, { // Default spec-specific settings. specOptions: Presets.DefaultOptions, // Default raid/party buffs settings. - raidBuffs: RaidBuffs.create({ - arcaneBrilliance: true, - bloodlust: true, - markOfTheWild: true, - icyTalons: true, - moonkinForm: true, - leaderOfThePack: true, - powerWordFortitude: true, - strengthOfEarthTotem: true, - trueshotAura: true, - wrathOfAirTotem: true, - demonicPact: true, - blessingOfKings: true, - blessingOfMight: true, - legacyOfTheEmperor: true, - legacyOfTheWhiteTiger: true, - communion: true, - }), + raidBuffs: RaidBuffs.create({}), partyBuffs: PartyBuffs.create({}), individualBuffs: IndividualBuffs.create({}), debuffs: Debuffs.create({ - mangle: true, - sunderArmor: true, - shadowAndFlame: true, - earthAndMoon: true, - bloodFrenzy: true, + // mangle: true, + // sunderArmor: true, + // shadowAndFlame: true, + // earthAndMoon: true, + // bloodFrenzy: true, }), }, // IconInputs to include in the 'Player' section on the settings tab. playerIconInputs: [], // Buff and Debuff inputs to include/exclude, overriding the EP-based defaults. - includeBuffDebuffInputs: [ - BuffDebuffInputs.CritBuff, - BuffDebuffInputs.MajorArmorDebuff, - ], + includeBuffDebuffInputs: [BuffDebuffInputs.CritBuff, BuffDebuffInputs.MajorArmorDebuff], excludeBuffDebuffInputs: [], // Inputs to include in the 'Other' section on the settings tab. otherInputs: { - inputs: [ - OtherInputs.InFrontOfTarget, - OtherInputs.InputDelay, - ], + inputs: [OtherInputs.InFrontOfTarget, OtherInputs.InputDelay], }, encounterPicker: { // Whether to include 'Execute Duration (%)' in the 'Encounter' section of the settings tab. @@ -177,7 +154,7 @@ const getActiveEPWeight = (player: Player, sim: Sim): S } else { return Presets.PREPATCH_EP_PRESET.epWeights; } -} +}; export class BrewmasterMonkSimUI extends IndividualSimUI { constructor(parentElem: HTMLElement, player: Player) { @@ -197,11 +174,11 @@ export class BrewmasterMonkSimUI extends IndividualSimUI) => { return getActiveEPWeight(player, this.sim); @@ -209,4 +186,4 @@ export class BrewmasterMonkSimUI extends IndividualSimUI, sim: Sim): S } else { return Presets.PREPATCH_EP_PRESET.epWeights; } -} +}; export class MistweaverMonkSimUI extends IndividualSimUI { constructor(parentElem: HTMLElement, player: Player) { @@ -197,11 +174,11 @@ export class MistweaverMonkSimUI extends IndividualSimUI) => { return getActiveEPWeight(player, this.sim); @@ -209,4 +186,4 @@ export class MistweaverMonkSimUI extends IndividualSimUI player.getSpecOptions().classOptions?.totems?.earth == EarthTotem.StrengthOfEarthTotem, - ), + label: 'Trueshot Aura', + actionId: ActionId.fromSpellId(19506), + playerData: playerClass(Class.ClassHunter), }, { label: 'Horn of Winter', @@ -366,178 +363,107 @@ const RAID_STATS_OPTIONS: RaidStatsOptions = { ], }, { - label: 'Armor', + label: 'Attack Speed', effects: [ { - label: 'Devotion Aura', - actionId: ActionId.fromSpellId(465), - playerData: playerClass(Class.ClassPaladin), + label: 'Unholy Aura', + actionId: ActionId.fromSpellId(55610), + playerData: playerClass(Class.ClassDeathKnight), }, { - label: 'Stoneskin Totem', - actionId: ActionId.fromSpellId(8071), - playerData: playerClass( - Class.ClassShaman, - player => player.getSpecOptions().classOptions?.totems?.earth == EarthTotem.StoneskinTotem, - ), + label: "Serpent's Swiftness", + actionId: ActionId.fromSpellId(128433), + playerData: playerClass(Class.ClassHunter), }, - ], - }, - { - label: 'Attack Power %', - effects: [ { - label: 'Blessing of Might', - actionId: ActionId.fromSpellId(19740), - playerData: playerClass(Class.ClassPaladin), + label: "Swiftblade's Cunning", + actionId: ActionId.fromSpellId(113742), + playerData: playerClass(Class.ClassRogue), }, - // { - // label: 'Abominations Might', - // actionId: ActionId.fromSpellId(53138), - // playerData: playerClassAndTalent(Class.ClassDeathKnight, 'abominationsMight'), - // }, - // { - // label: 'Unleashed Rage', - // actionId: ActionId.fromSpellId(30808), - // playerData: playerClassAndTalent(Class.ClassShaman, 'unleashedRage'), - // }, { - label: 'Trueshot Aura', - actionId: ActionId.fromSpellId(19506), - playerData: playerClass(Class.ClassHunter), + label: 'Unleashed Rage', + actionId: ActionId.fromSpellId(30809), + playerData: playerClass(Class.ClassShaman), }, ], }, { label: 'Spell Power', effects: [ - // { - // label: 'Demonic Pact', - // actionId: ActionId.fromSpellId(47236), - // playerData: playerClassAndTalent(Class.ClassWarlock, 'demonicPact'), - // }, - // { - // label: 'Totemic Wrath', - // actionId: ActionId.fromSpellId(77746), - // playerData: playerClassAndTalent(Class.ClassShaman, 'totemicWrath'), - // }, { label: 'Arcane Brilliance', actionId: ActionId.fromSpellId(1459), playerData: playerClass(Class.ClassMage), }, { - label: 'Flametongue Totem', - actionId: ActionId.fromSpellId(8227), - playerData: playerClass( - Class.ClassShaman, - player => player.getSpecOptions().classOptions?.totems?.fire == FireTotem.FlametongueTotem, - ), + label: 'Still Water', + actionId: ActionId.fromSpellId(126309), + playerData: playerClass(Class.ClassPriest), + }, + { + label: 'Burning Wrath', + actionId: ActionId.fromSpellId(77747), + playerData: playerClass(Class.ClassShaman), }, - ], - }, - { - label: '+3% Damage', - effects: [ - // { - // label: 'Communion', - // actionId: ActionId.fromSpellId(31876), - // playerData: playerClassAndTalent(Class.ClassPaladin, 'communion'), - // }, - // { - // label: 'Arcane Tactics', - // actionId: ActionId.fromSpellId(82930), - // playerData: playerClassAndTalent(Class.ClassMage, 'arcaneTactics'), - // }, - // { - // label: 'Ferocious Inspiration', - // actionId: ActionId.fromSpellId(34460), - // playerData: playerClassAndTalent(Class.ClassHunter, 'ferociousInspiration'), - // }, - ], - }, - { - label: 'Melee Haste', - effects: [ - // { - // label: 'Icy Talons', - // actionId: ActionId.fromSpellId(55610), - // playerData: playerClassAndTalent(Class.ClassDeathKnight, 'improvedIcyTalons'), - // }, - // { - // label: 'Hunting Party', - // actionId: ActionId.fromSpellId(53290), - // playerData: playerClassAndTalent(Class.ClassHunter, 'huntingParty'), - // }, { - label: 'Windfury Totem', - actionId: ActionId.fromSpellId(8512), - playerData: playerClass(Class.ClassShaman, player => player.getSpecOptions().classOptions?.totems?.air == AirTotem.WindfuryTotem), + label: 'Dark Intent', + actionId: ActionId.fromSpellId(109773), + playerData: playerClass(Class.ClassWarlock), }, ], }, { label: 'Spell Haste', effects: [ - // { - // label: 'Shadow Form', - // actionId: ActionId.fromSpellId(15473), - // playerData: playerClassAndTalent(Class.ClassPriest, 'shadowform'), - // }, - // { - // label: 'Moonkin Form', - // actionId: ActionId.fromSpellId(24858), - // playerData: playerClassAndTalent(Class.ClassDruid, 'moonkinForm'), - // }, { - label: 'Wrath of Air Totem', - actionId: ActionId.fromSpellId(3738), - playerData: playerClass(Class.ClassShaman, player => player.getSpecOptions().classOptions?.totems?.air == AirTotem.WrathOfAirTotem), + label: 'Shadow Form', + actionId: ActionId.fromSpellId(15473), + playerData: playerClass(Class.ClassPriest), + }, + { + label: 'Moonkin Aura', + actionId: ActionId.fromSpellId(24907), + playerData: playerClass(Class.ClassDruid), + }, + { + label: 'Mind Quickening', + actionId: ActionId.fromSpellId(49868), + playerData: playerClass(Class.ClassPriest), + }, + { + label: 'Elemental Oath', + actionId: ActionId.fromSpellId(51470), + playerData: playerClass(Class.ClassShaman), }, ], }, { - label: '+5% Crit', - effects: [ - // { - // label: 'Leader of the Pack', - // actionId: ActionId.fromSpellId(17007), - // playerData: playerClassAndTalent(Class.ClassDruid, 'leaderOfThePack'), - // }, - // { - // label: 'Elemental Oath', - // actionId: ActionId.fromSpellId(51470), - // playerData: playerClassAndTalent(Class.ClassShaman, 'elementalOath'), - // }, - // { - // label: 'Honor Among Thieves', - // actionId: ActionId.fromSpellId(51701), - // playerData: playerClassAndTalent(Class.ClassRogue, 'honorAmongThieves'), - // }, - // { - // label: 'Rampage', - // actionId: ActionId.fromSpellId(29801), - // playerData: playerClassAndTalent(Class.ClassWarrior, 'rampage'), - // }, - ], - }, - { - label: 'Mana', + label: 'Crit %', effects: [ { - label: 'Arcane Brilliance', - actionId: ActionId.fromSpellId(1459), - playerData: playerClass(Class.ClassMage), + label: 'Leader of the Pack', + actionId: ActionId.fromSpellId(17007), + playerData: playerClass(Class.ClassDruid), }, { - label: 'Fel Intelligence', - actionId: ActionId.fromSpellId(54424), - playerData: playerClass(Class.ClassWarlock), + label: 'Furious Howl', + actionId: ActionId.fromSpellId(24604), + playerData: playerClass(Class.ClassHunter), + }, + { + label: 'Terrifying Roar', + actionId: ActionId.fromSpellId(90309), + playerData: playerClass(Class.ClassHunter), + }, + { + label: 'Legacy of the White Tiger', + actionId: ActionId.fromSpellId(116781), + playerData: playerClass(Class.ClassMonk), }, ], }, { - label: 'MP5', + label: 'Mastery', effects: [ { label: 'Blessing of Might', @@ -545,62 +471,34 @@ const RAID_STATS_OPTIONS: RaidStatsOptions = { playerData: playerClass(Class.ClassPaladin), }, { - label: 'Fel Intelligence', - actionId: ActionId.fromSpellId(54424), - playerData: playerClass(Class.ClassWarlock), + label: 'Roar of Courage', + actionId: ActionId.fromSpellId(93435), + playerData: playerClass(Class.ClassHunter), }, { - label: 'Mana Spring Totem', - actionId: ActionId.fromSpellId(5675), - playerData: playerClass( - Class.ClassShaman, - player => player.getSpecOptions().classOptions?.totems?.water == WaterTotem.ManaSpringTotem, - ), + label: 'Spirit Beast Blessing', + actionId: ActionId.fromSpellId(128997), + playerData: playerClass(Class.ClassHunter), + }, + { + label: 'Grace of Air', + actionId: ActionId.fromSpellId(116956), + playerData: playerClass(Class.ClassShaman), }, - ], - }, - { - label: 'Replenishment', - effects: [ - // { - // label: 'Vampiric Touch', - // actionId: ActionId.fromSpellId(34914), - // playerData: playerClassAndTalent(Class.ClassPriest, 'vampiricTouch'), - // }, - // { - // label: 'Communion', - // actionId: ActionId.fromSpellId(31876), - // playerData: playerClassAndTalent(Class.ClassPaladin, 'communion'), - // }, - // { - // label: 'Revitalize', - // actionId: ActionId.fromSpellId(48544), - // playerData: playerClassAndTalent(Class.ClassDruid, 'revitalize'), - // }, - // { - // label: 'Soul Leach', - // actionId: ActionId.fromSpellId(30295), - // playerData: playerClassAndTalent(Class.ClassWarlock, 'soulLeech'), - // }, - // { - // label: 'Enduring Winter', - // actionId: ActionId.fromSpellId(86508), - // playerData: playerClassAndTalent(Class.ClassMage, 'enduringWinter'), - // }, ], }, { label: 'Stamina', effects: [ { - label: 'Power Word Fortitude', + label: 'Power Word: Fortitude', actionId: ActionId.fromSpellId(21562), playerData: playerClass(Class.ClassPriest), }, { - label: 'Blood Pact', - actionId: ActionId.fromSpellId(6307), - playerData: playerClass(Class.ClassWarlock), + label: 'Qiraji Fortitude', + actionId: ActionId.fromSpellId(90364), + playerData: playerClass(Class.ClassHunter), }, { label: 'Commanding Shout', @@ -610,40 +508,12 @@ const RAID_STATS_OPTIONS: RaidStatsOptions = { ], }, { - label: 'Resistances', + label: 'Mana Regen', effects: [ { - label: 'Resistance Aura', - actionId: ActionId.fromSpellId(19891), - playerData: playerClass(Class.ClassPaladin), - }, - { - label: 'Elemental Resistance Totem', - actionId: ActionId.fromSpellId(8184), - playerData: playerClass( - Class.ClassShaman, - player => player.getSpecOptions().classOptions?.totems?.water == WaterTotem.ElementalResistanceTotem, - ), - }, - { - label: 'Aspect of the Wild', - actionId: ActionId.fromSpellId(20043), - playerData: playerClass(Class.ClassHunter), - }, - { - label: 'Shadow Protection', - actionId: ActionId.fromSpellId(27683), - playerData: playerClass(Class.ClassPriest), - }, - { - label: 'Blessing of Kings', - actionId: ActionId.fromSpellId(20217), - playerData: playerClass(Class.ClassPaladin), - }, - { - label: 'Mark of the Wild', - actionId: ActionId.fromSpellId(1126), - playerData: playerClass(Class.ClassDruid), + label: 'Mana Tide Totem', + actionId: ActionId.fromSpellId(5675), + playerData: playerClass(Class.ClassShaman), }, ], }, diff --git a/ui/rogue/assassination/sim.ts b/ui/rogue/assassination/sim.ts index ac6f5fc7d2..ee2238037b 100644 --- a/ui/rogue/assassination/sim.ts +++ b/ui/rogue/assassination/sim.ts @@ -85,30 +85,15 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecAssassinationRogue, { // Default spec-specific settings. specOptions: Presets.DefaultOptions, // Default raid/party buffs settings. - raidBuffs: RaidBuffs.create({ - arcaneBrilliance: true, - bloodlust: true, - markOfTheWild: true, - icyTalons: true, - moonkinForm: true, - leaderOfThePack: true, - powerWordFortitude: true, - strengthOfEarthTotem: true, - trueshotAura: true, - wrathOfAirTotem: true, - demonicPact: true, - blessingOfKings: true, - blessingOfMight: true, - communion: true, - }), + raidBuffs: RaidBuffs.create({}), partyBuffs: PartyBuffs.create({}), individualBuffs: IndividualBuffs.create({}), debuffs: Debuffs.create({ - mangle: true, - faerieFire: true, - earthAndMoon: true, - bloodFrenzy: true, - shadowAndFlame: true, + // mangle: true, + // faerieFire: true, + // earthAndMoon: true, + // bloodFrenzy: true, + // shadowAndFlame: true, }), }, @@ -118,12 +103,7 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecAssassinationRogue, { // IconInputs to include in the 'Player' section on the settings tab. playerIconInputs: [RogueInputs.MainHandImbue(), RogueInputs.OffHandImbue(), RogueInputs.ThrownImbue()], // Buff and Debuff inputs to include/exclude, overriding the EP-based defaults. - includeBuffDebuffInputs: [ - BuffDebuffInputs.CritBuff, - BuffDebuffInputs.SpellCritDebuff, - BuffDebuffInputs.SpellDamageDebuff, - BuffDebuffInputs.MajorArmorDebuff, - ], + includeBuffDebuffInputs: [BuffDebuffInputs.CritBuff, BuffDebuffInputs.SpellDamageDebuff, BuffDebuffInputs.MajorArmorDebuff], excludeBuffDebuffInputs: [], // Inputs to include in the 'Other' section on the settings tab. otherInputs: { diff --git a/ui/rogue/combat/sim.ts b/ui/rogue/combat/sim.ts index a28358d004..e8090b9db1 100644 --- a/ui/rogue/combat/sim.ts +++ b/ui/rogue/combat/sim.ts @@ -87,30 +87,15 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecCombatRogue, { // Default spec-specific settings. specOptions: Presets.DefaultOptions, // Default raid/party buffs settings. - raidBuffs: RaidBuffs.create({ - arcaneBrilliance: true, - bloodlust: true, - markOfTheWild: true, - icyTalons: true, - moonkinForm: true, - leaderOfThePack: true, - powerWordFortitude: true, - strengthOfEarthTotem: true, - trueshotAura: true, - wrathOfAirTotem: true, - demonicPact: true, - blessingOfKings: true, - blessingOfMight: true, - communion: true, - }), + raidBuffs: RaidBuffs.create({}), partyBuffs: PartyBuffs.create({}), individualBuffs: IndividualBuffs.create({}), debuffs: Debuffs.create({ - mangle: true, - faerieFire: true, - shadowAndFlame: true, - earthAndMoon: true, - bloodFrenzy: true, + // mangle: true, + // faerieFire: true, + // shadowAndFlame: true, + // earthAndMoon: true, + // bloodFrenzy: true, }), }, @@ -120,12 +105,7 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecCombatRogue, { // IconInputs to include in the 'Player' section on the settings tab. playerIconInputs: [RogueInputs.MainHandImbue(), RogueInputs.OffHandImbue(), RogueInputs.ThrownImbue()], // Buff and Debuff inputs to include/exclude, overriding the EP-based defaults. - includeBuffDebuffInputs: [ - BuffDebuffInputs.CritBuff, - BuffDebuffInputs.SpellCritDebuff, - BuffDebuffInputs.SpellDamageDebuff, - BuffDebuffInputs.MajorArmorDebuff, - ], + includeBuffDebuffInputs: [BuffDebuffInputs.CritBuff, BuffDebuffInputs.SpellDamageDebuff, BuffDebuffInputs.MajorArmorDebuff], excludeBuffDebuffInputs: [], // Inputs to include in the 'Other' section on the settings tab. otherInputs: { diff --git a/ui/rogue/subtlety/sim.ts b/ui/rogue/subtlety/sim.ts index b5b150b866..a816393335 100644 --- a/ui/rogue/subtlety/sim.ts +++ b/ui/rogue/subtlety/sim.ts @@ -84,30 +84,15 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecSubtletyRogue, { // Default spec-specific settings. specOptions: Presets.DefaultOptions, // Default raid/party buffs settings. - raidBuffs: RaidBuffs.create({ - arcaneBrilliance: true, - bloodlust: true, - markOfTheWild: true, - icyTalons: true, - moonkinForm: true, - leaderOfThePack: true, - powerWordFortitude: true, - strengthOfEarthTotem: true, - trueshotAura: true, - wrathOfAirTotem: true, - demonicPact: true, - blessingOfKings: true, - blessingOfMight: true, - communion: true, - }), + raidBuffs: RaidBuffs.create({}), partyBuffs: PartyBuffs.create({}), individualBuffs: IndividualBuffs.create({}), debuffs: Debuffs.create({ - mangle: true, - faerieFire: true, - shadowAndFlame: true, - earthAndMoon: true, - bloodFrenzy: true, + // mangle: true, + // faerieFire: true, + // shadowAndFlame: true, + // earthAndMoon: true, + // bloodFrenzy: true, }), }, @@ -117,12 +102,7 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecSubtletyRogue, { // IconInputs to include in the 'Player' section on the settings tab. playerIconInputs: [RogueInputs.MainHandImbue(), RogueInputs.OffHandImbue(), RogueInputs.ThrownImbue()], // Buff and Debuff inputs to include/exclude, overriding the EP-based defaults. - includeBuffDebuffInputs: [ - BuffDebuffInputs.CritBuff, - BuffDebuffInputs.SpellCritDebuff, - BuffDebuffInputs.SpellDamageDebuff, - BuffDebuffInputs.MajorArmorDebuff, - ], + includeBuffDebuffInputs: [BuffDebuffInputs.CritBuff, BuffDebuffInputs.SpellDamageDebuff, BuffDebuffInputs.MajorArmorDebuff], excludeBuffDebuffInputs: [], // Inputs to include in the 'Other' section on the settings tab. otherInputs: { diff --git a/ui/shaman/elemental/sim.ts b/ui/shaman/elemental/sim.ts index 1df1ecada9..ab6b15f840 100644 --- a/ui/shaman/elemental/sim.ts +++ b/ui/shaman/elemental/sim.ts @@ -77,35 +77,18 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecElementalShaman, { specOptions: Presets.DefaultOptions, other: Presets.OtherDefaults, // Default raid/party buffs settings. - raidBuffs: RaidBuffs.create({ - arcaneBrilliance: true, - bloodlust: true, - markOfTheWild: true, - icyTalons: true, - moonkinForm: true, - leaderOfThePack: true, - powerWordFortitude: true, - strengthOfEarthTotem: true, - trueshotAura: true, - wrathOfAirTotem: true, - demonicPact: true, - blessingOfKings: true, - blessingOfMight: true, - communion: true, - }), + raidBuffs: RaidBuffs.create({}), partyBuffs: PartyBuffs.create({}), - individualBuffs: IndividualBuffs.create({ - vampiricTouch: true, - }), + individualBuffs: IndividualBuffs.create({}), debuffs: Debuffs.create({ - curseOfElements: true, - shadowAndFlame: true, + // curseOfElements: true, + // shadowAndFlame: true, }), }, // IconInputs to include in the 'Player' section on the settings tab. playerIconInputs: [ShamanInputs.ShamanShieldInput()], // Buff and Debuff inputs to include/exclude, overriding the EP-based defaults. - includeBuffDebuffInputs: [BuffDebuffInputs.MP5Buff, BuffDebuffInputs.ReplenishmentBuff], + includeBuffDebuffInputs: [], excludeBuffDebuffInputs: [], // Inputs to include in the 'Other' section on the settings tab. otherInputs: { diff --git a/ui/shaman/enhancement/presets.ts b/ui/shaman/enhancement/presets.ts index 3531cc3983..c315ab98bb 100644 --- a/ui/shaman/enhancement/presets.ts +++ b/ui/shaman/enhancement/presets.ts @@ -129,29 +129,14 @@ export const DefaultConsumables = ConsumesSpec.create({ tinkerId: 82174, // Synapse Springs }); -export const DefaultRaidBuffs = RaidBuffs.create({ - arcaneBrilliance: true, - bloodlust: true, - markOfTheWild: true, - icyTalons: true, - moonkinForm: true, - leaderOfThePack: true, - powerWordFortitude: true, - strengthOfEarthTotem: true, - trueshotAura: true, - wrathOfAirTotem: true, - demonicPact: true, - blessingOfKings: true, - blessingOfMight: true, - communion: true, -}); +export const DefaultRaidBuffs = RaidBuffs.create({}); export const DefaultDebuffs = Debuffs.create({ - bloodFrenzy: true, - faerieFire: true, - ebonPlaguebringer: true, - mangle: true, - criticalMass: true, - demoralizingShout: true, - frostFever: true, + // bloodFrenzy: true, + // faerieFire: true, + // ebonPlaguebringer: true, + // mangle: true, + // criticalMass: true, + // demoralizingShout: true, + // frostFever: true, }); diff --git a/ui/shaman/enhancement/sim.ts b/ui/shaman/enhancement/sim.ts index 9dff6836de..3598366b28 100644 --- a/ui/shaman/enhancement/sim.ts +++ b/ui/shaman/enhancement/sim.ts @@ -108,25 +108,18 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecEnhancementShaman, { // Default raid/party buffs settings. raidBuffs: Presets.DefaultRaidBuffs, partyBuffs: PartyBuffs.create({}), - individualBuffs: IndividualBuffs.create({ - vampiricTouch: true, - }), + individualBuffs: IndividualBuffs.create({}), debuffs: Presets.DefaultDebuffs, }, // IconInputs to include in the 'Player' section on the settings tab. playerIconInputs: [ShamanInputs.ShamanShieldInput(), ShamanInputs.ShamanImbueMH(), EnhancementInputs.ShamanImbueOH], // Buff and Debuff inputs to include/exclude, overriding the EP-based defaults. - includeBuffDebuffInputs: [BuffDebuffInputs.ReplenishmentBuff, BuffDebuffInputs.MP5Buff, BuffDebuffInputs.SpellHasteBuff], - excludeBuffDebuffInputs: [BuffDebuffInputs.BleedDebuff], + includeBuffDebuffInputs: [], + excludeBuffDebuffInputs: [], // Inputs to include in the 'Other' section on the settings tab. otherInputs: { - inputs: [ - EnhancementInputs.SyncTypeInput, - OtherInputs.InputDelay, - OtherInputs.TankAssignment, - OtherInputs.InFrontOfTarget, - ], + inputs: [EnhancementInputs.SyncTypeInput, OtherInputs.InputDelay, OtherInputs.TankAssignment, OtherInputs.InFrontOfTarget], }, itemSwapSlots: [ ItemSlot.ItemSlotHead, diff --git a/ui/shaman/restoration/sim.ts b/ui/shaman/restoration/sim.ts index bcf1a29e0c..83b0b028ed 100644 --- a/ui/shaman/restoration/sim.ts +++ b/ui/shaman/restoration/sim.ts @@ -46,29 +46,12 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecRestorationShaman, { // Default spec-specific settings. specOptions: Presets.DefaultOptions, // Default raid/party buffs settings. - raidBuffs: RaidBuffs.create({ - arcaneBrilliance: true, - bloodlust: true, - markOfTheWild: true, - icyTalons: true, - moonkinForm: true, - leaderOfThePack: true, - powerWordFortitude: true, - strengthOfEarthTotem: true, - trueshotAura: true, - wrathOfAirTotem: true, - demonicPact: true, - blessingOfKings: true, - blessingOfMight: true, - communion: true, - }), + raidBuffs: RaidBuffs.create({}), partyBuffs: PartyBuffs.create({}), - individualBuffs: IndividualBuffs.create({ - vampiricTouch: true, - }), + individualBuffs: IndividualBuffs.create({}), debuffs: Debuffs.create({ - curseOfElements: true, - shadowAndFlame: true, + // curseOfElements: true, + // shadowAndFlame: true, }), }, // IconInputs to include in the 'Player' section on the settings tab. diff --git a/ui/warlock/affliction/presets.ts b/ui/warlock/affliction/presets.ts index 8c4a876743..824dac68bc 100644 --- a/ui/warlock/affliction/presets.ts +++ b/ui/warlock/affliction/presets.ts @@ -70,36 +70,18 @@ export const DefaultConsumables = ConsumesSpec.create({ tinkerId: 82174, // Synapse Springs }); -export const DefaultRaidBuffs = RaidBuffs.create({ - arcaneBrilliance: true, - bloodlust: true, - markOfTheWild: true, - icyTalons: true, - moonkinForm: true, - leaderOfThePack: true, - powerWordFortitude: true, - strengthOfEarthTotem: true, - trueshotAura: true, - wrathOfAirTotem: true, - demonicPact: true, - blessingOfKings: true, - blessingOfMight: true, - communion: true, -}); +export const DefaultRaidBuffs = RaidBuffs.create({}); -export const DefaultIndividualBuffs = IndividualBuffs.create({ - vampiricTouch: true, - darkIntent: true, -}); +export const DefaultIndividualBuffs = IndividualBuffs.create({}); export const DefaultDebuffs = Debuffs.create({ - bloodFrenzy: true, - sunderArmor: true, - ebonPlaguebringer: true, - mangle: true, - criticalMass: false, - demoralizingShout: true, - frostFever: true, + // bloodFrenzy: true, + // sunderArmor: true, + // ebonPlaguebringer: true, + // mangle: true, + // criticalMass: false, + // demoralizingShout: true, + // frostFever: true, }); export const OtherDefaults = { @@ -107,7 +89,6 @@ export const OtherDefaults = { profession1: Profession.Engineering, profession2: Profession.Tailoring, channelClipDelay: 150, - darkIntentUptime: 90, }; export const AFFLICTION_BREAKPOINTS = WARLOCK_BREAKPOINTS; diff --git a/ui/warlock/affliction/sim.ts b/ui/warlock/affliction/sim.ts index 7f9d6b293a..51b271fd06 100644 --- a/ui/warlock/affliction/sim.ts +++ b/ui/warlock/affliction/sim.ts @@ -82,17 +82,7 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecAfflictionWarlock, { playerIconInputs: [WarlockInputs.PetInput()], // Buff and Debuff inputs to include/exclude, overriding the EP-based defaults. - includeBuffDebuffInputs: [ - BuffDebuffInputs.ReplenishmentBuff, - BuffDebuffInputs.MajorArmorDebuff, - BuffDebuffInputs.PhysicalDamageDebuff, - BuffDebuffInputs.MeleeHasteBuff, - BuffDebuffInputs.CritBuff, - BuffDebuffInputs.MP5Buff, - BuffDebuffInputs.AttackPowerPercentBuff, - BuffDebuffInputs.StrengthAndAgilityBuff, - BuffDebuffInputs.StaminaBuff, - ], + includeBuffDebuffInputs: [], excludeBuffDebuffInputs: [], petConsumeInputs: [], // Inputs to include in the 'Other' section on the settings tab. @@ -101,7 +91,6 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecAfflictionWarlock, { WarlockInputs.DetonateSeed(), OtherInputs.InputDelay, OtherInputs.DistanceFromTarget, - OtherInputs.DarkIntentUptime, OtherInputs.TankAssignment, OtherInputs.ChannelClipDelay, ], diff --git a/ui/warlock/demonology/presets.ts b/ui/warlock/demonology/presets.ts index e37a9ed3fb..c9f8e395bb 100644 --- a/ui/warlock/demonology/presets.ts +++ b/ui/warlock/demonology/presets.ts @@ -98,36 +98,18 @@ export const DefaultConsumables = ConsumesSpec.create({ tinkerId: 82174, // Synapse Springs }); -export const DefaultRaidBuffs = RaidBuffs.create({ - arcaneBrilliance: true, - bloodlust: true, - markOfTheWild: true, - icyTalons: true, - moonkinForm: true, - leaderOfThePack: true, - powerWordFortitude: true, - strengthOfEarthTotem: true, - trueshotAura: true, - wrathOfAirTotem: true, - demonicPact: true, - blessingOfKings: true, - blessingOfMight: true, - communion: true, -}); +export const DefaultRaidBuffs = RaidBuffs.create({}); -export const DefaultIndividualBuffs = IndividualBuffs.create({ - vampiricTouch: true, - darkIntent: true, -}); +export const DefaultIndividualBuffs = IndividualBuffs.create({}); export const DefaultDebuffs = Debuffs.create({ - bloodFrenzy: true, - sunderArmor: true, - ebonPlaguebringer: true, - mangle: true, - criticalMass: false, - demoralizingShout: true, - frostFever: true, + // bloodFrenzy: true, + // sunderArmor: true, + // ebonPlaguebringer: true, + // mangle: true, + // criticalMass: false, + // demoralizingShout: true, + // frostFever: true, }); export const OtherDefaults = { @@ -135,7 +117,6 @@ export const OtherDefaults = { profession1: Profession.Engineering, profession2: Profession.Tailoring, channelClipDelay: 150, - darkIntentUptime: 90, }; export const PRESET_BUILD_SHADOWBOLT = PresetUtils.makePresetBuild('Shadow Bolt', { diff --git a/ui/warlock/demonology/sim.ts b/ui/warlock/demonology/sim.ts index d59aefbf53..216cd32c76 100644 --- a/ui/warlock/demonology/sim.ts +++ b/ui/warlock/demonology/sim.ts @@ -89,17 +89,7 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecDemonologyWarlock, { playerIconInputs: [WarlockInputs.PetInput()], // Buff and Debuff inputs to include/exclude, overriding the EP-based defaults. - includeBuffDebuffInputs: [ - BuffDebuffInputs.ReplenishmentBuff, - BuffDebuffInputs.MajorArmorDebuff, - BuffDebuffInputs.PhysicalDamageDebuff, - BuffDebuffInputs.MeleeHasteBuff, - BuffDebuffInputs.CritBuff, - BuffDebuffInputs.MP5Buff, - BuffDebuffInputs.AttackPowerPercentBuff, - BuffDebuffInputs.StrengthAndAgilityBuff, - BuffDebuffInputs.StaminaBuff, - ], + includeBuffDebuffInputs: [], excludeBuffDebuffInputs: [], petConsumeInputs: [], // Inputs to include in the 'Other' section on the settings tab. @@ -108,7 +98,6 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecDemonologyWarlock, { WarlockInputs.DetonateSeed(), OtherInputs.InputDelay, OtherInputs.DistanceFromTarget, - OtherInputs.DarkIntentUptime, OtherInputs.TankAssignment, OtherInputs.ChannelClipDelay, DemonologyInputs.AssumePrepullMasteryElixir, diff --git a/ui/warlock/destruction/presets.ts b/ui/warlock/destruction/presets.ts index 453c739ae0..f030b33b56 100644 --- a/ui/warlock/destruction/presets.ts +++ b/ui/warlock/destruction/presets.ts @@ -74,36 +74,18 @@ export const DefaultConsumables = ConsumesSpec.create({ tinkerId: 82174, // Synapse Springs }); -export const DefaultRaidBuffs = RaidBuffs.create({ - arcaneBrilliance: true, - bloodlust: true, - markOfTheWild: true, - icyTalons: true, - moonkinForm: true, - leaderOfThePack: true, - powerWordFortitude: true, - strengthOfEarthTotem: true, - trueshotAura: true, - wrathOfAirTotem: true, - demonicPact: true, - blessingOfKings: true, - blessingOfMight: true, - communion: true, -}); +export const DefaultRaidBuffs = RaidBuffs.create({}); -export const DefaultIndividualBuffs = IndividualBuffs.create({ - vampiricTouch: true, - darkIntent: true, -}); +export const DefaultIndividualBuffs = IndividualBuffs.create({}); export const DefaultDebuffs = Debuffs.create({ - bloodFrenzy: true, - sunderArmor: true, - ebonPlaguebringer: true, - mangle: true, - criticalMass: false, - demoralizingShout: true, - frostFever: true, + // bloodFrenzy: true, + // sunderArmor: true, + // ebonPlaguebringer: true, + // mangle: true, + // criticalMass: false, + // demoralizingShout: true, + // frostFever: true, }); export const OtherDefaults = { @@ -111,7 +93,6 @@ export const OtherDefaults = { profession1: Profession.Engineering, profession2: Profession.Tailoring, channelClipDelay: 150, - darkIntentUptime: 90, }; export const DESTRUCTION_BREAKPOINTS = WARLOCK_BREAKPOINTS; diff --git a/ui/warlock/destruction/sim.ts b/ui/warlock/destruction/sim.ts index eb9b039ef1..7d34e2819b 100644 --- a/ui/warlock/destruction/sim.ts +++ b/ui/warlock/destruction/sim.ts @@ -60,17 +60,7 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecDestructionWarlock, { playerIconInputs: [WarlockInputs.PetInput()], // Buff and Debuff inputs to include/exclude, overriding the EP-based defaults. - includeBuffDebuffInputs: [ - BuffDebuffInputs.ReplenishmentBuff, - BuffDebuffInputs.MajorArmorDebuff, - BuffDebuffInputs.PhysicalDamageDebuff, - BuffDebuffInputs.MeleeHasteBuff, - BuffDebuffInputs.CritBuff, - BuffDebuffInputs.MP5Buff, - BuffDebuffInputs.AttackPowerPercentBuff, - BuffDebuffInputs.StrengthAndAgilityBuff, - BuffDebuffInputs.StaminaBuff, - ], + includeBuffDebuffInputs: [], excludeBuffDebuffInputs: [], petConsumeInputs: [], // Inputs to include in the 'Other' section on the settings tab. @@ -79,7 +69,6 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecDestructionWarlock, { WarlockInputs.DetonateSeed(), OtherInputs.InputDelay, OtherInputs.DistanceFromTarget, - OtherInputs.DarkIntentUptime, OtherInputs.TankAssignment, OtherInputs.ChannelClipDelay, ], diff --git a/ui/warrior/arms/sim.ts b/ui/warrior/arms/sim.ts index a6f6019b23..e83b8c5500 100644 --- a/ui/warrior/arms/sim.ts +++ b/ui/warrior/arms/sim.ts @@ -67,30 +67,15 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecArmsWarrior, { // Default spec-specific settings. specOptions: Presets.DefaultOptions, // Default raid/party buffs settings. - raidBuffs: RaidBuffs.create({ - arcaneBrilliance: true, - bloodlust: true, - markOfTheWild: true, - icyTalons: true, - moonkinForm: true, - leaderOfThePack: true, - powerWordFortitude: true, - strengthOfEarthTotem: true, - trueshotAura: true, - wrathOfAirTotem: true, - demonicPact: true, - blessingOfKings: true, - blessingOfMight: true, - communion: true, - }), + raidBuffs: RaidBuffs.create({}), partyBuffs: PartyBuffs.create({}), individualBuffs: IndividualBuffs.create({}), debuffs: Debuffs.create({ - bloodFrenzy: true, - mangle: true, - faerieFire: true, - curseOfWeakness: true, - ebonPlaguebringer: true, + // bloodFrenzy: true, + // mangle: true, + // faerieFire: true, + // curseOfWeakness: true, + // ebonPlaguebringer: true, }), }, diff --git a/ui/warrior/fury/sim.ts b/ui/warrior/fury/sim.ts index 7ce472fb4a..2690c436e3 100644 --- a/ui/warrior/fury/sim.ts +++ b/ui/warrior/fury/sim.ts @@ -77,30 +77,15 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecFuryWarrior, { // Default spec-specific settings. specOptions: Presets.DefaultOptions, // Default raid/party buffs settings. - raidBuffs: RaidBuffs.create({ - arcaneBrilliance: true, - bloodlust: true, - markOfTheWild: true, - icyTalons: true, - moonkinForm: true, - leaderOfThePack: true, - powerWordFortitude: true, - strengthOfEarthTotem: true, - trueshotAura: true, - wrathOfAirTotem: true, - demonicPact: true, - blessingOfKings: true, - blessingOfMight: true, - communion: true, - }), + raidBuffs: RaidBuffs.create({}), partyBuffs: PartyBuffs.create({}), individualBuffs: IndividualBuffs.create({}), debuffs: Debuffs.create({ - bloodFrenzy: true, - mangle: true, - faerieFire: true, - curseOfElements: true, - ebonPlaguebringer: true, + // bloodFrenzy: true, + // mangle: true, + // faerieFire: true, + // curseOfElements: true, + // ebonPlaguebringer: true, }), }, diff --git a/ui/warrior/protection/sim.ts b/ui/warrior/protection/sim.ts index e6e8d60ee3..960bea5fe7 100644 --- a/ui/warrior/protection/sim.ts +++ b/ui/warrior/protection/sim.ts @@ -79,31 +79,15 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecProtectionWarrior, { // Default spec-specific settings. specOptions: Presets.DefaultOptions, // Default raid/party buffs settings. - raidBuffs: RaidBuffs.create({ - arcaneBrilliance: true, - bloodlust: true, - markOfTheWild: true, - icyTalons: true, - moonkinForm: true, - leaderOfThePack: true, - powerWordFortitude: true, - strengthOfEarthTotem: true, - trueshotAura: true, - wrathOfAirTotem: true, - demonicPact: true, - blessingOfMight: true, - communion: true, - devotionAura: true, - retributionAura: true, - }), + raidBuffs: RaidBuffs.create({}), partyBuffs: PartyBuffs.create({}), individualBuffs: IndividualBuffs.create({}), debuffs: Debuffs.create({ - faerieFire: true, - mangle: true, - vindication: true, - bloodFrenzy: true, - frostFever: true, + // faerieFire: true, + // mangle: true, + // vindication: true, + // bloodFrenzy: true, + // frostFever: true, }), }, @@ -123,7 +107,6 @@ const SPEC_CONFIG = registerSpecConfig(Spec.SpecProtectionWarrior, { OtherInputs.AbsorbFrac, OtherInputs.BurstWindow, OtherInputs.HpPercentForDefensives, - OtherInputs.InspirationUptime, ProtectionWarriorInputs.StartingRage(), OtherInputs.InFrontOfTarget, ],