From bb3b75a93e31ac73dd09986dd1a62ba3f1c5ca4c Mon Sep 17 00:00:00 2001 From: BrewingCoder Date: Fri, 15 Mar 2024 17:58:12 -0400 Subject: [PATCH] DK Unholy/Brew BM DK Unholy, don't try cast DnD if moving Monk BM: just more progression --- .../Death Knight/Unholy/BrewUnholyDK.lua | 6 +- Rotations/Monk/BrewMaster/BrewBrewMaster.lua | 628 +++++++++++++----- 2 files changed, 456 insertions(+), 178 deletions(-) diff --git a/Rotations/Death Knight/Unholy/BrewUnholyDK.lua b/Rotations/Death Knight/Unholy/BrewUnholyDK.lua index 452a858bf..57efed831 100644 --- a/Rotations/Death Knight/Unholy/BrewUnholyDK.lua +++ b/Rotations/Death Knight/Unholy/BrewUnholyDK.lua @@ -485,7 +485,7 @@ actionList.GargSetup = function() if cast.defile("target") then ui.debug("GARGSETUP.08: Defile") return true; end; end else - if cast.able.deathAndDecay("target") and unit.distance("target") <= 10 and not unit.moving("target") ( + if cast.able.deathAndDecay("target") and unit.distance("target") <= 10 and not unit.moving() ( not buff.deathAndDecay.exists("player") and debuff.festeringWound.stack("target") > 0 ) then if cast.deathAndDecay("target") then ui.debug("GARGSETUP.09: Death and Decay") return true; end; @@ -517,7 +517,7 @@ actionList.St = function() end --any_dnd,if=!death_and_decay.ticking&(active_enemies>=2|talent.unholy_ground&(pet.apoc_ghoul.active&pet.apoc_ghoul.remains>=13|pet.gargoyle.active&pet.gargoyle.remains>8|pet.army_ghoul.active&pet.army_ghoul.remains>8|!variable.pop_wounds&debuff.festering_wound.stack>=4)|talent.defile&(pet.gargoyle.active|pet.apoc_ghoul.active|pet.army_ghoul.active|buff.dark_transformation.up))&(death_knight.fwounded_targets=active_enemies|active_enemies=1) - if cast.able.deathAndDecay("target") and not unit.moving("target") and ( + if cast.able.deathAndDecay("target") and not unit.moving() and ( true--not buff.deathAndDecay.exists() and (#enemies.yards5 >= 2 or talent.unholyGround and (var.hasGargoyle or var.GargoyleTTL > 8 or cast.last.armyOfTheDead(30) or not var.pop_wounds==1 and debuff.festeringWound.stack("target")>=4) or talent.defile and (var.hasGargoyle or cast.last.armyOfTheDead(30) or buff.darkTransformation.exist())) ) then if cast.deathAndDecay("target") then ui.debug("ST.03: Death and Decay") return true; end; @@ -711,7 +711,7 @@ end actionList.AOESetup = function() --actions.aoe_setup=any_dnd,if=(!talent.bursting_sores|death_knight.fwounded_targets=active_enemies|death_knight.fwounded_targets>=8|raid_event.adds.exists&raid_event.adds.remains<=11&raid_event.adds.remains>5) --basically going to cast DnD regardless, just check and see if we are standing in it or not - if not buff.deathAndDecay.exists() and cast.able.deathAndDecay("playerGround") then + if not buff.deathAndDecay.exists() and cast.able.deathAndDecay("playerGround") and not unit.moving("player") then if cast.deathAndDecay("playerGround") then ui.debug("AOESetup: DnD") return true; end end --actions.aoe_setup+=/festering_strike,target_if=min:debuff.festering_wound.stack,if=death_knight.fwounded_targets 5 and cast.able.roll() then debugMessage(text.preCombat.rollToEngage) return true; end; + end + if unit.valid("target") and unit.facing("target") and ui.checked(text.preCombat.chiTorpedoToEngage) then + if unit.distance("target") > 5 and cast.able.chiTorpedo() then debugMessage(text.preCombat.chiTorpedoToEngage) return true; end; + end if unit.valid("target") then -- Abilities below this only used when target is valid -- Start Attack if unit.distance("target") < 5 then -- Starts attacking if enemy is within 5yrds @@ -195,7 +253,194 @@ actionList.PreCombat = function() end end end -- End No Combat -end -- End Action List - PreCombat +end +actionList.RotationBoc = function () + --purifying_brew,if=(buff.blackout_combo.down&(buff.recent_purifies.down|cooldown.purifying_brew.charges_fractional>(1+talent.improved_purifying_brew.enabled-0.1))) + --&talent.improved_invoke_niuzao_the_black_ox.enabled&(cooldown.weapons_of_order.remains>40|cooldown.weapons_of_order.remains<5) + + if (buff.blackoutCombo.down() and (charges.purifyingBrew.frac() > (1 + boolNumeric(talent.improvedPurifyingBrew)-0.1))) and + talent.improvedInvokeNiuzaoTheBlackOx and (cd.weaponsOfOrder.remains() > 40 or cd.weaponsOfOrder.remains() <5) then + if cast.able.purifyingBrew() then + if cast.purifyingBrew() then ui.debug("01.BOC: Purifying Brew") return true end; + end + end + --weapons_of_order,if=(buff.recent_purifies.up)&talent.improved_invoke_niuzao_the_black_ox.enabled + if (var.recent_purifies) and talent.improvedInvokeNiuzaoTheBlackOx then + if cast.able.weaponsOfOrder() then + if cast.weaponsOfOrder() then ui.debug("02.BOC: Weapons of Order") return true end; + end + end + + --/invoke_niuzao_the_black_ox,if=(buff.invoke_niuzao_the_black_ox.down&buff.recent_purifies.up&buff.weapons_of_order.remains<14) + --&talent.improved_invoke_niuzao_the_black_ox.enabled + if (buff.invokeNiuzaoTheBlackOx.down() and var.recent_purifies and buff.weaponsOfOrder.remains() < 14) and talent.improvedInvokeNiuzaoTheBlackOx then + if cast.able.invokeNiuzaoTheBlackOx() then + if cast.invokeNiuzaoTheBlackOx() then ui.debug("03.BOC: Niuzao The Black Ox") return true; end + end + end + + --invoke_niuzao_the_black_ox,if=(debuff.weapons_of_order_debuff.stack>3)&!talent.improved_invoke_niuzao_the_black_ox.enabled + if debuff.weaponsOfOrder.stack("target") > 3 and not talent.improvedInvokeNiuzaoTheBlackOx then + if cast.able.invokeNiuzaoTheBlackOx() then + if cast.invokeNiuzaoTheBlackOx() then ui.debug("04.BOC: Niuzao The Black Ox") return true; end + end + end + + --/invoke_niuzao_the_black_ox,if=(!talent.weapons_of_order.enabled) + if not talent.weaponsOfOrder and cast.able.invokeNiuzaoTheBlackOx() then + if cast.invokeNiuzaoTheBlackOx() then ui.debug("05.BOC: Invoke Niuzao The Black Ox") return true; end + end + + --/weapons_of_order,if=(talent.weapons_of_order.enabled)&!talent.improved_invoke_niuzao_the_black_ox.enabled + if(talent.weaponsOfOrder) and not talent.improvedInvokeNiuzaoTheBlackOx and cast.able.weaponsOfOrder() then + if cast.weaponsOfOrder() then ui.debug("06.BOC: Weapons of Order") return true; end + end + + --/keg_smash,if=(time-action.weapons_of_order.last_used<2) + if cast.last.weaponsOfOrder(2) and cast.able.kegSmash("target") then + if cast.kegSmash("target") then ui.debug("07.BOC: Keg Smash") return true; end; + end + + --/keg_smash,if=(buff.weapons_of_order.remains3) + if (debuff.weaponsOfOrder.stack("target") > 3) then + if cast.able.summonWhiteTigerStatue("target") then + if cast.summonWhiteTigerStatue("target") then ui.debug("16.BOC: White Tiger Statue") return true; end; + end + end + + --/summon_white_tiger_statue,if=(!talent.weapons_of_order.enabled) + if not talent.weaponsOfOrder and cast.able.summonWhiteTigerStatue("target") then + if cast.summonWhiteTigerStatue("target") then ui.debug("17.BOC: White Tiger Statue") return true; end; + end + + --/bonedust_brew,if=(time<10&debuff.weapons_of_order_debuff.stack>3)|(time>10&talent.weapons_of_order.enabled) + --TODO figure out what the "time" variable means. + if (debuff.weaponsOfOrder.stack("target") > 3 and unit.combatTime("player") < 10) or (unit.combatTime("player") > 10 and talent.weaponsOfOrder) then + if cast.able.bonedustBrew("target") then + if cast.bonedustBrew("target") then ui.debug("18.BOC: Bone Dust Brew") return true; end + end + end + + --/bonedust_brew,if=(!talent.weapons_of_order.enabled) + if not talent.weaponsOfOrder and cast.able.bonedustBrew("target") then + if cast.bonedustBrew("target") then ui.debug("19.BOC: Bonedustd Brew") return true; end + end + + --/exploding_keg,if=(buff.bonedust_brew.up) + if buff.bonedustBrew.exists() then + if cast.able.explodingKeg("target") then + if cast.explodingKeg("target") then ui.debug("20.BOC: Exploding Keg") return true; end + end + end + + --/exploding_keg,if=(cooldown.bonedust_brew.remains>=20) + if cd.bonedustBrew.remains() >= 20 or not talent.bonedustBrew then + if cast.able.explodingKeg("target") then + if cast.explodingKeg("target") then ui.debug("21.BOC: Exploding Keg") return true; end + end + end + + if cast.able.kegSmash("target") then + if cast.kegSmash("target") then ui.debug("22.BOC: Keg Smash") return true; end; + end + + if talent.rushingJadeWind and cast.able.rushingJadeWind() then + if cast.rushingJadeWind() then ui.debug("23.BOC: Rushing Jade Wind") return true; end + end + if cast.able.breathOfFire("target") then + if cast.breathOfFire("target") then ui.debug("24.BOC: Breath of Fire") return true; end + end + + --/tiger_palm,if=active_enemies=1&!talent.blackout_combo.enabled + if #enemies.yards5 == 1 and not talent.blackoutCombo then + if cast.able.tigerPalm("target") then + if cast.tigerPalm("target") then ui.debug("25.BOC: Tiger Palm") return true; end + end + end + + if #enemies.yards5 > 1 and cast.able.spinningCraneKick() then + if cast.spinningCraneKick() then ui.debug("26.BOC: Spinning Crane Kick") return true; end; + end + + if cast.able.expelHarm() then + if cast.expelHarm() then ui.debug("27.BOC: Expel Harm") return true; end; + end + + if cast.able.chiWave("target") then + if cast.chiWave("target") then ui.debug("28.BOC: Chi Wave") return true; end; + end + + if cast.able.chiBurst("target") then + if cast.chiBurst("Target") then ui.debug("29.BOC: Chi Burst") return true; end; + end +end + +actionList.Defensive = function() + if unit.hp() <= 90 and cast.able.expelHarm("player") then + if cast.expelHarm("player") then ui.debug("DEF: ExpelHarm") return true;end; + end + if (debuff.moderateStagger.exists("player") or debuff.heavyStagger.exists("player")) and cast.able.purifyingBrew("player") then + if cast.purifyingBrew("player") then ui.debug("DEF: Purifying Brew") return true; end; + end + if unit.hp() <= 80 and cast.able.healingElixir("player") then + if cast.healingElixir("player") then ui.debug("DEF: Healing Elixir") return true; end; + end + if unit.hp() <= 70 and cast.able.invokeNiuzao() then + if cast.invokeNiuzao() then ui.debug("DEF: Invoking Niuzao") return true; end; + end + if unit.hp() <= 50 and cast.able.dampenHarm("player") then + if cast.dampenHarm("player") then ui.debug("DEF: Dampen Harm") return true; end; + end + if unit.hp() <= 40 and cast.able.fortifyingBrew("player") then + if cast.fortifyingBrew("player") then ui.debug("DEF: Fortifying Brew") return true; end; + end +end -- End Action List - Defensive ---------------- --- ROTATION --- @@ -219,6 +464,11 @@ local function runRotation() -- This is the main profile loop, any below this po var = br.player.variables debuff = br.player.debuff + ui.mode.debug = br.data.settings[br.selectedSpec].toggles["DebugMode"] + + --TODO this needs to be replaced with some sort of real calculation, in the mean time we're just looking for having cast Purifying Brew in the last 10 seconds + var.recent_purifies = cast.last.purifyingBrew(10) + -- Explanations on the Units and Enemies functions can be found in System/API/Units.lua and System/API/Enemies.lua ------------- --- Units --- @@ -241,98 +491,126 @@ local function runRotation() -- This is the main profile loop, any below this po enemies.get(30,"player",false,true) enemies.get(40,"player",false,true) + var.MistBallsInWorld = 0 + for i=1,br._G.GetObjectCount() do + local name = br._G.ObjectName(br._G.GetObjectWithIndex(i)) + local creator = br._G.UnitCreator(br._G.GetObjectWithIndex(i)) + if creator == br._G.UnitGUID("player") and br._G.ObjectType(br._G.GetObjectWithIndex(i)) ==11 then + var.MistBallsInWorld = var.MistBallsInWorld +1 + -- elseif creator == br._G.UnitGUID("player") then + -- print("Unknown obj type: " .. br._G.ObjectType(br._G.GetObjectWithIndex(i))) + end + end + + if ui.mode.debug==1 then + local n,r,i,ct,mr,mxr = GetSpellInfo("Recent Purifies") + + for i=1,40 do + local name, rank, icon, count, debuffType, duration, expirationTime, unitCaster, isStealable, shouldConsolidate, spellIdbuff = UnitBuff("player", i); + if name then + if name=="Recent Purifies" then + print(name,spellIdbuff) + print("---------------------------------------------") + end + end + end + + end ------------------------ --- Custom Variables --- ------------------------ -- Any other local varaible from above would also need to be defined here to be use. - if var.profileStop == nil then var.profileStop = false end -- Trigger variable to help when needing to stop a profile. - + if var.profileStop == nil then var.profileStop = false end - --------------------- - --- Begin Profile --- - --------------------- -- Profile Stop | Pause if not unit.inCombat() and not unit.exists("target") and var.profileStop then -- Reset profile stop once stopped var.profileStop = false elseif (unit.inCombat() and var.profileStop) or ui.pause() or unit.mounted() or unit.flying() or ui.mode.rotation == 4 then -- If profile triggered to stop go here until it has. return true - else -- Profile is free to perform actions - -------------- - --- Extras --- - -------------- - if actionList.Extra() then return true end -- This runs the Extra Action List and anything in it will run in or out of combat, this generally contains utility functions. - ----------------- - --- Defensive --- - ----------------- - if actionList.Defensive() then return true end -- This runs the Defensive Action List and anything in it will run in or out of combat, this generally contains defensive functions. - ------------------ - --- Pre-Combat --- - ------------------ - if actionList.PreCombat() then return true end -- This runs the Pre-Combat Action List and anything in it will run in or out of combat, this generally includes functions that prepare for or start combat. - ----------------- - --- In Combat --- - ----------------- - if unit.inCombat() and unit.valid("target") and not var.profileStop then -- Everything below this line only run if you are in combat and the selected target is validated and not triggered to stop. - ------------------ - --- Interrupts --- - ------------------ - if actionList.Interrupt() then return true end -- This runs the Interrupt Action List, this generally contains interrupt functions. - ------------ - --- Main --- - ------------ - --Always Maintain Buffs - if not buff.rushingJadeWind.exists("player") and cast.able.rushingJadeWind() then - if cast.rushingJadeWind() then ui.debug("Rushing Jade Wind") return true;end; - end + else - if cast.able.chiWave("target") and unit.distance("target") >= 8 then - if cast.chiWave("target") then ui.debug("Chi Wave") return true; end; + if actionList.Extra() then return true end + + if unit.inCombat() and unit.valid("target") and not var.profileStop then + if actionList.Interrupt() then return true; end + if actionList.Defensive() then return true; end + if not talent.pressTheAdvantage then + if actionList.RotationBoc() then return true; end end + end - --Melee Range Attacks - if unit.distance("target") <= 5 then - if buff.hitScheme.exists() and buff.hitScheme.stack("player") >= 3 and cast.able.kegSmash("target") then - if cast.kegSmash("target") then ui.debug("Proc Hit Scheme: Keg Smash") return true; end; - end - if cast.able.celestialBrew() and not buff.celestialBrew.exists("player") then - if cast.celestialBrew("player") then ui.debug("Celestial Brew") return true; end; - end - --Make sure shuffle is being maintained - -- +5 sec for Keg Smash, 3 sec for Blackout kick, max 15 sec. - if (not buff.shuffle.exists() or (buff.shuffle.remains() <= 3)) then - if cast.able.kegSmash("target") then - if cast.kegSmash("target") then ui.debug("SHUFFLE +5: Keg Smash") return true; end; - elseif cast.able.blackoutKick("target") then - if cast.blackoutKick("target") then ui.debug("SHUFFLE +3: Blackout Kick") return true; end; - else - if cast.able.spinningCraneKick() then - if cast.spinningCraneKick() then ui.debug("SHUFFLE PUSH: Spinning Crane Kick") return true; end; - end - end - end + -- --- Defensive --- + -- ----------------- + -- if actionList.Defensive() then return true end -- This runs the Defensive Action List and anything in it will run in or out of combat, this generally contains defensive functions. + -- ------------------ + -- --- Pre-Combat --- + -- ------------------ + -- if actionList.PreCombat() then return true end -- This runs the Pre-Combat Action List and anything in it will run in or out of combat, this generally includes functions that prepare for or start combat. + -- ----------------- + -- --- In Combat --- + -- ----------------- + -- if unit.inCombat() and unit.valid("target") and not var.profileStop then -- Everything below this line only run if you are in combat and the selected target is validated and not triggered to stop. + -- ------------------ + -- --- Interrupts --- + -- ------------------ + -- if actionList.Interrupt() then return true end -- This runs the Interrupt Action List, this generally contains interrupt functions. + -- ------------ + -- --- Main --- + -- ------------ + -- --Always Maintain Buffs + -- if not buff.rushingJadeWind.exists("player") and cast.able.rushingJadeWind() then + -- if cast.rushingJadeWind() then ui.debug("Rushing Jade Wind") return true;end; + -- end - if cast.able.breathOfFire("target") then - if cast.breathOfFire("target") then ui.debug("Breath of Fire") return true; end; - end - if cast.able.weaponsOfOrder("target") then - if cast.weaponsOfOrder("target") then ui.debug("WOE") return true; end; - end - if cast.able.risingSunKick("target") then - if cast.risingSunKick("target") then ui.debug("Rising Sun Kick") return true; end; - end - if cast.able.touchOfDeath("target") then - if cast.touchOfDeath("target") then ui.debug("Touch of Death") return true; end; - end - if cast.able.summonWhiteTigerStatue("target") then - if cast.summonWhiteTigerStatue("target") then ui.debug("White Target Statue") return true; end; - end - if cast.able.bonedustBrew("playerGround") then - if cast.bonedustBrew("playerGround") then ui.debug("Bone Dust Brew") return true; end; - end - if buff.rushingJadeWind.exists("player") and cast.able.explodingKeg("target") then - if cast.explodingKeg("target") then ui.debug("Exploding Keg") return true; end; - end + -- if cast.able.chiWave("target") and unit.distance("target") >= 8 then + -- if cast.chiWave("target") then ui.debug("Chi Wave") return true; end; + -- end + + -- --Melee Range Attacks + -- if unit.distance("target") <= 5 then + -- if buff.hitScheme.exists() and buff.hitScheme.stack("player") >= 3 and cast.able.kegSmash("target") then + -- if cast.kegSmash("target") then ui.debug("Proc Hit Scheme: Keg Smash") return true; end; + -- end + -- if cast.able.celestialBrew() and not buff.celestialBrew.exists("player") then + -- if cast.celestialBrew("player") then ui.debug("Celestial Brew") return true; end; + -- end + + -- --Make sure shuffle is being maintained + -- -- +5 sec for Keg Smash, 3 sec for Blackout kick, max 15 sec. + -- if (not buff.shuffle.exists() or (buff.shuffle.remains() <= 3)) then + -- if cast.able.kegSmash("target") then + -- if cast.kegSmash("target") then ui.debug("SHUFFLE +5: Keg Smash") return true; end; + -- elseif cast.able.blackoutKick("target") then + -- if cast.blackoutKick("target") then ui.debug("SHUFFLE +3: Blackout Kick") return true; end; + -- else + -- if cast.able.spinningCraneKick() then + -- if cast.spinningCraneKick() then ui.debug("SHUFFLE PUSH: Spinning Crane Kick") return true; end; + -- end + -- end + -- end + + -- if cast.able.breathOfFire("target") then + -- if cast.breathOfFire("target") then ui.debug("Breath of Fire") return true; end; + -- end + -- if cast.able.weaponsOfOrder("target") then + -- if cast.weaponsOfOrder("target") then ui.debug("WOE") return true; end; + -- end + -- if cast.able.risingSunKick("target") then + -- if cast.risingSunKick("target") then ui.debug("Rising Sun Kick") return true; end; + -- end + -- if cast.able.touchOfDeath("target") then + -- if cast.touchOfDeath("target") then ui.debug("Touch of Death") return true; end; + -- end + -- if cast.able.summonWhiteTigerStatue("target") then + -- if cast.summonWhiteTigerStatue("target") then ui.debug("White Target Statue") return true; end; + -- end + -- if cast.able.bonedustBrew("playerGround") then + -- if cast.bonedustBrew("playerGround") then ui.debug("Bone Dust Brew") return true; end; + -- end + -- if buff.rushingJadeWind.exists("player") and cast.able.explodingKeg("target") then + -- if cast.explodingKeg("target") then ui.debug("Exploding Keg") return true; end; + -- end -- We need to ocassionally cast a damage spell; but the tigerPalm vs Spinning Crane kick options -- Would depend on # of enemies as well as if we need to collect globes. Not sure we can get the -- # of globes on the ground nearby. @@ -353,15 +631,15 @@ local function runRotation() -- This is the main profile loop, any below this po -- if cast.able.tigerPalm("target") then -- if cast.tigerPalm("target") then ui.debug("tiger Palm") return true; end; -- end - if cast.able.tigersLust("player") then - if cast.tigersLust("player") then ui.debug("tiger's Lust") return true; end; - end + -- if cast.able.tigersLust("player") then + -- if cast.tigersLust("player") then ui.debug("tiger's Lust") return true; end; + -- end - if cast.able.autoAttack("target") then - if cast.autoAttack("target") then ui.debug("Casting Auto Attack [Pre-Combat]") return true end - end - end - end -- End In Combat Rotation + -- if cast.able.autoAttack("target") then + -- if cast.autoAttack("target") then ui.debug("Casting Auto Attack [Pre-Combat]") return true end + -- end + --end + --end -- End In Combat Rotation end -- Pause end -- End runRotation local id = 268 -- Change to the spec id profile is for. Spec ID can be found at: https://wowpedia.fandom.com/wiki/SpecializationID