## Affliction Warlock ## December 27, 2021 ## Changes: ## - Added Spell Lock. ## - Added Devour Magic. ## - Added breakchannel logic for Drain Soul. ## - Tweak Malefic Rapture logic to work if you're missing a talent in that row. ## - Enable Rampant Afflictions PvP talent. ## - Tweaks to avoid blowing Darkglare in multi-target w/o DOTs up. ## - Condense some Darkglare Prep calls to reduce computation time. ## - Set some call_action_list entries to strict to avoid checking lists that won't be reached (again!). ## - Only Seed once pre-pull. ## - Adjust "burn CDs before end of fight" logic to apply only to boss fights (not trash packs). ## - Fleshcraft/Volatile Solvent cancel_if changed to interrupt_if. ## - Integrate Necro MW priority list. actions.precombat=fel_domination,if=time>0&!pet.alive&!buff.grimoire_of_sacrifice.up actions.precombat+=/summon_pet actions.precombat+=/use_item,name=tome_of_monstrous_constructions actions.precombat+=/use_item,name=soleahs_secret_technique actions.precombat+=/grimoire_of_sacrifice,if=talent.grimoire_of_sacrifice.enabled actions.precombat+=/fleshcraft actions.precombat+=/variable,name=dots_ready,value=active_dot.corruption>0&active_dot.agony>0&active_dot.unstable_affliction>0&(!talent.siphon_life.enabled|active_dot.siphon_life>0)&(dot.phantom_singularity.ticking|!talent.phantom_singularity.enabled) actions.precombat+=/use_item,name=azsharas_font_of_power actions.precombat+=/seed_of_corruption,line_cd=10,if=spell_targets.seed_of_corruption_aoe>=3 actions.precombat+=/haunt actions.precombat+=/unstable_affliction ## Executed every time the actor is available. actions=spell_lock actions+=/devour_magic actions+=/call_action_list,name=aoe,strict=1,if=active_enemies>3 # Call separate action list for Necrolord MW in ST. Currently only optimized for use with PS. actions+=/run_action_list,name=necro_mw,strict=1,if=covenant.necrolord&runeforge.malefic_wrath&active_enemies=1&talent.phantom_singularity # Action lists for trinket behavior. Stats are saved for before Soul Rot/Impending Catastrophe/Phantom Singularity, otherwise on cooldown. actions+=/call_action_list,name=trinket_split_check actions+=/call_action_list,name=delayed_trinkets actions+=/call_action_list,name=stat_trinkets,strict=1,if=(dot.soul_rot.ticking|dot.impending_catastrophe_dot.ticking|dot.phantom_singularity.ticking)&soul_shard>3|dot.vile_taint.ticking|talent.sow_the_seeds actions+=/call_action_list,name=damage_trinkets,if=covenant.night_fae&(!variable.trinket_split|cooldown.soul_rot.remains>20|(variable.trinket_one&cooldown.soul_rot.remains20|(variable.trinket_one&cooldown.impending_catastrophe.remains20|(variable.trinket_one&cooldown.phantom_singularity.remains20|(variable.trinket_one&cooldown.summon_darkglare.remains2|!talent.phantom_singularity))|(covenant.night_fae&dot.soul_rot.ticking&cooldown.summon_darkglare.remains<2&(dot.phantom_singularity.remains>2|!talent.phantom_singularity))|((covenant.necrolord|covenant.kyrian|covenant.none)&dot.phantom_singularity.ticking&dot.phantom_singularity.remains<2) # Refresh dots early if going into a shard spending phase actions+=/call_action_list,name=dot_prep,if=(covenant.night_fae&!dot.soul_rot.ticking&cooldown.soul_rot.remains<4)|(covenant.venthyr&!dot.impending_catastrophe_dot.ticking&cooldown.impending_catastrophe.remains<4)|((covenant.necrolord|covenant.kyrian|covenant.none)&talent.phantom_singularity&!dot.phantom_singularity.ticking&cooldown.phantom_singularity.remains<4) # If Phantom Singularity is ticking, it is safe to use Dark Soul actions+=/dark_soul,if=dot.phantom_singularity.ticking actions+=/dark_soul,if=!talent.phantom_singularity&(dot.soul_rot.ticking|dot.impending_catastrophe_dot.ticking) # Sync Phantom Singularity with Venthyr/Night Fae covenant dot, otherwise use on cooldown. If Empyreal Ordnance buff is incoming, hold until it's ready (18 seconds after use) actions+=/phantom_singularity,if=covenant.night_fae&time>5&cooldown.soul_rot.remains<1&(trinket.empyreal_ordnance.cooldown.remains<162|!equipped.empyreal_ordnance) actions+=/phantom_singularity,if=covenant.venthyr&time>5&cooldown.impending_catastrophe.remains<1&(trinket.empyreal_ordnance.cooldown.remains<162|!equipped.empyreal_ordnance) # Necrolord with Malefic Wrath casts phantom singularity in line with Decimating Bolt actions+=/phantom_singularity,if=covenant.necrolord&runeforge.malefic_wrath&time>5&cooldown.decimating_bolt.remains<3&(trinket.empyreal_ordnance.cooldown.remains<162|!equipped.empyreal_ordnance) # Other covenants (including non-MW Necro) cast PS on cooldown actions+=/phantom_singularity,if=(covenant.kyrian|covenant.none|(covenant.necrolord&!runeforge.malefic_wrath))&(trinket.empyreal_ordnance.cooldown.remains<162|!equipped.empyreal_ordnance) actions+=/phantom_singularity,if=boss&fight_remains<16 # If Phantom Singularity is ticking, it's time to use other major dots actions+=/call_action_list,name=covenant,strict=1,if=dot.phantom_singularity.ticking&(covenant.night_fae|covenant.venthyr) actions+=/agony,cycle_targets=1,if=dot.agony.remains<4 actions+=/haunt # Sow the Seeds on 3 targets if it isn't currently in flight or on the target. With Siphon Life it's also better to use Seed over manually applying 3 Corruptions. actions+=/seed_of_corruption,if=active_enemies>2&talent.sow_the_seeds&!dot.seed_of_corruption.ticking&!in_flight actions+=/seed_of_corruption,if=active_enemies>2&talent.siphon_life&!dot.seed_of_corruption.ticking&!in_flight&dot.corruption.remains<4 actions+=/vile_taint,if=(soul_shard>1|active_enemies>2)&cooldown.summon_darkglare.remains>12 actions+=/unstable_affliction,if=active_dot.unstable_affliction=0|ticking&dot.unstable_affliction.remains<4 actions+=/siphon_life,cycle_targets=1,if=dot.siphon_life.remains<4 actions+=/call_action_list,name=covenant,strict=1,if=!covenant.necrolord # Apply Corruption manually on 1-2 targets, or on 3 with Absolute Corruption actions+=/corruption,cycle_targets=1,if=active_enemies<4-(talent.sow_the_seeds|talent.siphon_life)&dot.corruption.remains<2 # After the opener, spend a shard when at 5 on Malefic Rapture to avoid overcapping actions+=/malefic_rapture,if=soul_shard>4&time>21 # When not syncing Phantom Singularity to Venthyr/Night Fae, Summon Darkglare if all dots are applied actions+=/call_action_list,name=darkglare_prep,if=(covenant.venthyr&!talent.phantom_singularity&dot.impending_catastrophe_dot.ticking&cooldown.summon_darkglare.ready)|(covenant.night_fae&!talent.phantom_singularity&dot.soul_rot.ticking&cooldown.summon_darkglare.ready)|((covenant.necrolord|covenant.kyrian|covenant.none)&cooldown.summon_darkglare.ready) # Use Dark Soul if Darkglare won't be ready again, or if there will be at least 2 more Darkglare uses actions+=/dark_soul,if=boss&cooldown.summon_darkglare.remains>fight_remains&(!talent.phantom_singularity|cooldown.phantom_singularity.remains>fight_remains) actions+=/dark_soul,if=boss&!talent.phantom_singularity&cooldown.summon_darkglare.remains+cooldown.summon_darkglare.duration1) # Use Malefic Rapture to maintain the malefic wrath buff until shards need to be generated for the next burst window (20 seconds is more than sufficient to generate 3 shards) actions+=/malefic_rapture,if=runeforge.malefic_wrath&cooldown.soul_rot.remains>20&buff.malefic_wrath.remains<4 # Maintain Malefic Wrath at all times for the Necrolord or Kyrian covenant actions+=/malefic_rapture,if=runeforge.malefic_wrath&(covenant.necrolord|covenant.kyrian)&buff.malefic_wrath.remains<4 # Use Malefic Rapture on Phantom Singularity casts, making sure to save a shard to stack Malefic Wrath if using it actions+=/malefic_rapture,if=talent.phantom_singularity&(dot.phantom_singularity.ticking|cooldown.phantom_singularity.remains>25|boss&time_to_die1) actions+=/malefic_rapture,if=talent.sow_the_seeds # Drain Life is only a DPS gain with Inevitable Demise near max stacks. If fight is about to end do not miss spending the stacks actions+=/drain_life,if=buff.inevitable_demise.stack>40|buff.inevitable_demise.up&boss&fight_remains<4 actions+=/call_action_list,name=covenant actions+=/agony,cycle_targets=1,if=refreshable actions+=/unstable_affliction,if=active_dot.unstable_affliction=0|ticking&refreshable actions+=/siphon_life,cycle_targets=1,if=refreshable actions+=/corruption,cycle_targets=1,if=refreshable&active_enemies<4-(talent.sow_the_seeds|talent.siphon_life) actions+=/fleshcraft,if=soulbind.volatile_solvent,interrupt_if=buff.volatile_solvent.up actions+=/drain_soul,interrupt=1 actions+=/shadow_bolt actions.aoe=phantom_singularity actions.aoe+=/haunt actions.aoe+=/call_action_list,name=darkglare_prep,if=covenant.venthyr&dot.impending_catastrophe_dot.ticking&cooldown.summon_darkglare.ready&(dot.phantom_singularity.remains>2|!talent.phantom_singularity)|covenant.night_fae&dot.soul_rot.ticking&cooldown.summon_darkglare.ready&(dot.phantom_singularity.remains>2|!talent.phantom_singularity)|(covenant.necrolord|covenant.kyrian|covenant.none)&dot.phantom_singularity.ticking&dot.phantom_singularity.remains<2 actions.aoe+=/seed_of_corruption,if=talent.sow_the_seeds&can_seed actions.aoe+=/seed_of_corruption,if=!talent.sow_the_seeds&!dot.seed_of_corruption.ticking&!in_flight&dot.corruption.refreshable actions.aoe+=/agony,cycle_targets=1,if=active_dot.agony<4&!dot.agony.ticking actions.aoe+=/agony,cycle_targets=1,if=active_dot.agony>=4&refreshable&dot.agony.ticking actions.aoe+=/unstable_affliction,if=active_dot.unstable_affliction=0|ticking&refreshable actions.aoe+=/unstable_affliction,cycle_targets=1,if=!ticking&pvptalent.rampant_afflictions.enabled&active_dot.unstable_affliction<3 actions.aoe+=/vile_taint,if=soul_shard>1 actions.aoe+=/call_action_list,name=covenant,strict=1,if=!covenant.necrolord actions.aoe+=/call_action_list,name=darkglare_prep,if=(covenant.venthyr&(cooldown.impending_catastrophe.ready|dot.impending_catastrophe_dot.ticking)&cooldown.summon_darkglare.ready&(dot.phantom_singularity.remains>2|!talent.phantom_singularity))&((covenant.necrolord|covenant.kyrian|covenant.none)&cooldown.summon_darkglare.remains<2&(dot.phantom_singularity.remains>2|!talent.phantom_singularity))|(covenant.night_fae&(cooldown.soul_rot.ready|dot.soul_rot.ticking)&cooldown.summon_darkglare.remains<2&(dot.phantom_singularity.remains>2|!talent.phantom_singularity)) actions.aoe+=/dark_soul,if=boss&cooldown.summon_darkglare.remains>fight_remains&(!talent.phantom_singularity|cooldown.phantom_singularity.remains>fight_remains) actions.aoe+=/dark_soul,if=boss&cooldown.summon_darkglare.remains+cooldown.summon_darkglare.duration4 actions.aoe+=/siphon_life,cycle_targets=1,if=active_dot.siphon_life<=3&refreshable&!dot.siphon_life.ticking actions.aoe+=/call_action_list,name=covenant,strict=1,if=covenant.necrolord actions.aoe+=/drain_life,if=buff.inevitable_demise.stack>=50|boss&buff.inevitable_demise.up&fight_remains<5|buff.inevitable_demise.stack>=35&dot.soul_rot.ticking actions.aoe+=/fleshcraft,if=soulbind.volatile_solvent,interrupt_if=buff.volatile_solvent.up actions.aoe+=/drain_soul,interrupt=1 actions.aoe+=/shadow_bolt actions.covenant=impending_catastrophe,if=!talent.phantom_singularity&(cooldown.summon_darkglare.remains<10|cooldown.summon_darkglare.remains>50|cooldown.summon_darkglare.remains>25&conduit.corrupting_leer) actions.covenant+=/impending_catastrophe,if=talent.phantom_singularity&dot.phantom_singularity.ticking actions.covenant+=/decimating_bolt,if=cooldown.summon_darkglare.remains>5&(debuff.haunt.remains>4|!talent.haunt) actions.covenant+=/soul_rot,if=!talent.phantom_singularity&(cooldown.summon_darkglare.remains<5|cooldown.summon_darkglare.remains>50|cooldown.summon_darkglare.remains>25&conduit.corrupting_leer) actions.covenant+=/soul_rot,if=talent.phantom_singularity&dot.phantom_singularity.ticking actions.covenant+=/scouring_tithe actions.damage_trinkets=use_item,name=soul_igniter actions.damage_trinkets+=/use_item,name=dreadfire_vessel actions.damage_trinkets+=/use_item,name=glyph_of_assimilation actions.damage_trinkets+=/use_item,name=unchained_gladiators_shackles actions.damage_trinkets+=/use_item,name=ebonsoul_vice actions.darkglare_prep=vile_taint actions.darkglare_prep+=/dark_soul actions.darkglare_prep+=/potion actions.darkglare_prep+=/fireblood actions.darkglare_prep+=/blood_fury actions.darkglare_prep+=/berserking actions.darkglare_prep+=/call_action_list,name=covenant,strict=1,if=!covenant.necrolord actions.darkglare_prep+=/summon_darkglare actions.delayed_trinkets=use_item,name=empyreal_ordnance,if=(covenant.night_fae&cooldown.soul_rot.remains<20)|(covenant.venthyr&cooldown.impending_catastrophe.remains<20)|(covenant.necrolord|covenant.kyrian|covenant.none) actions.delayed_trinkets+=/use_item,name=sunblood_amethyst,if=(covenant.night_fae&cooldown.soul_rot.remains<6)|(covenant.venthyr&cooldown.impending_catastrophe.remains<6)|(covenant.necrolord|covenant.kyrian|covenant.none) actions.delayed_trinkets+=/use_item,name=soulletting_ruby,if=(covenant.night_fae&cooldown.soul_rot.remains<8)|(covenant.venthyr&cooldown.impending_catastrophe.remains<8)|(covenant.necrolord|covenant.kyrian|covenant.none) actions.delayed_trinkets+=/use_item,name=shadowed_orb_of_torment,if=(covenant.night_fae&cooldown.soul_rot.remains<4)|(covenant.venthyr&cooldown.impending_catastrophe.remains<4)|(covenant.necrolord|covenant.kyrian|covenant.none) actions.dot_prep=agony,if=dot.agony.remains<8&cooldown.summon_darkglare.remains>dot.agony.remains actions.dot_prep+=/siphon_life,if=dot.siphon_life.remains<8&cooldown.summon_darkglare.remains>dot.siphon_life.remains actions.dot_prep+=/unstable_affliction,if=dot.unstable_affliction.remains<8&cooldown.summon_darkglare.remains>dot.unstable_affliction.remains actions.dot_prep+=/corruption,if=dot.corruption.remains<8&cooldown.summon_darkglare.remains>dot.corruption.remains actions.item=use_items actions.necro_mw=variable,name=dots_ticking,value=dot.corruption.remains>2&dot.agony.remains>2&dot.unstable_affliction.remains>2&(!talent.siphon_life|dot.siphon_life.remains>2) # Trinkets align with PS for Shadow Embrace, DB for Haunt. actions.necro_mw+=/variable,name=trinket_delay,value=cooldown.phantom_singularity.remains,value_else=cooldown.decimating_bolt.remains,op=setif,condition=talent.shadow_embrace,if=covenant.necrolord # Burn soul shards if the fight will be ending soon. actions.necro_mw+=/malefic_rapture,if=time_to_die7&buff.malefic_wrath.remains0 # If the player is using SE, fire DB on cooldown then following with PS actions.necro_mw+=/decimating_bolt,if=talent.shadow_embrace&variable.dots_ticking actions.necro_mw+=/phantom_singularity,if=talent.shadow_embrace&cooldown.decimating_bolt.remains>0 actions.necro_mw+=/unstable_affliction,if=dot.unstable_affliction.remains<6 actions.necro_mw+=/agony,if=dot.agony.remains<4 actions.necro_mw+=/siphon_life,if=dot.siphon_life.remains<4 actions.necro_mw+=/corruption,if=dot.corruption.remains<4 # Refresh MW after the opener if darkglare_prep would cause us to miss a MW refresh actions.necro_mw+=/malefic_rapture,if=time>7&buff.malefic_wrath.remains<2*gcd.max+execute_time # Call darkglare_prep if Phantom Singularity is currently ticking actions.necro_mw+=/call_action_list,name=darkglare_prep,strict=1,if=dot.phantom_singularity.ticking # Utilize any other stat trinkets if Phantom Singularity is ticking actions.necro_mw+=/call_action_list,name=stat_trinkets,strict=1,if=dot.phantom_singularity.ticking # Stack Malefic Wrath to 3, or refresh when getting low (ideally looking for a calculated number, but 4.5s remaining is the result of testing with T27) actions.necro_mw+=/malefic_rapture,if=time>7&(buff.malefic_wrath.stack<3|buff.malefic_wrath.remains<4.5) # Additional MR spends when extra shards are available and either Phantom Singularity is ticking, or the fight is ending. actions.necro_mw+=/malefic_rapture,if=(dot.phantom_singularity.ticking|time_to_die1) # Additional Drain Soul cast when PS is ticking actions.necro_mw+=/drain_soul,if=dot.phantom_singularity.ticking # Low - priority dot refresh when refreshable. actions.necro_mw+=/agony,if=refreshable actions.necro_mw+=/unstable_affliction,if=refreshable actions.necro_mw+=/corruption,if=refreshable actions.necro_mw+=/siphon_life,if=talent.siphon_life&refreshable # Fleshcraft to maintain Volatile Solvent. actions.necro_mw+=/fleshcraft,if=soulbind.volatile_solvent,cancel_if=buff.volatile_solvent_humanoid.up # Low-priority haunt refresh. actions.necro_mw+=/haunt,if=dot.haunt.remains<3 # Uninterruptible DS channel if we have the DB buff. actions.necro_mw+=/drain_soul,if=buff.decimating_bolt.up actions.necro_mw+=/drain_soul,if=talent.shadow_embrace&debuff.shadow_embrace.remains<3|debuff.shadow_embrace.stack<3,interrupt_if=debuff.shadow_embrace.stack>=3&debuff.shadow_embrace.remains>3 actions.necro_mw+=/drain_soul,interrupt=1 actions.necro_mw+=/shadow_bolt actions.se=haunt actions.se+=/drain_soul,interrupt_global=1,interrupt_if=debuff.shadow_embrace.stack>=3 actions.se+=/shadow_bolt actions.stat_trinkets=use_item,name=inscrutable_quantum_device actions.stat_trinkets+=/use_item,name=instructors_divine_bell actions.stat_trinkets+=/use_item,name=overflowing_anima_cage actions.stat_trinkets+=/use_item,name=darkmoon_deck_putrescence actions.stat_trinkets+=/use_item,name=macabre_sheet_music actions.stat_trinkets+=/use_item,name=flame_of_battle actions.stat_trinkets+=/use_item,name=wakeners_frond actions.stat_trinkets+=/use_item,name=tablet_of_despair actions.stat_trinkets+=/use_item,name=sinful_aspirants_badge_of_ferocity actions.stat_trinkets+=/use_item,name=sinful_gladiators_badge_of_ferocity actions.stat_trinkets+=/blood_fury actions.stat_trinkets+=/fireblood actions.stat_trinkets+=/berserking # We don't support ^ as XOR in Lua, so I've converted this to arithmetic. actions.trinket_split_check=variable,name=special_equipped,value=((1*equipped.empyreal_ordnance)+(1*equipped.inscrutable_quantum_device)+(1*equipped.soulletting_ruby)+(1*equipped.sunblood_amethyst))=1 actions.trinket_split_check+=/variable,name=trinket_one,value=(trinket.1.has_proc&trinket.1.has_cooldown) actions.trinket_split_check+=/variable,name=trinket_two,value=(trinket.2.has_proc&trinket.2.has_cooldown) actions.trinket_split_check+=/variable,name=damage_trinket,value=(!(trinket.1.has_proc&trinket.1.has_cooldown))|(!(trinket.2.has_proc&trinket.2.has_cooldown))|equipped.glyph_of_assimilation actions.trinket_split_check+=/variable,name=trinket_split,value=(variable.trinket_one&variable.damage_trinket)|(variable.trinket_two&variable.damage_trinket)|(1*variable.trinket_one)+(1*variable.special_equipped)=1|(1*variable.trinket_two)+(1*variable.special_equipped)=1