diff --git a/engine/class_modules/warlock/sc_warlock.cpp b/engine/class_modules/warlock/sc_warlock.cpp index 5523d5efcac..47a58dd2530 100644 --- a/engine/class_modules/warlock/sc_warlock.cpp +++ b/engine/class_modules/warlock/sc_warlock.cpp @@ -639,16 +639,8 @@ stat_e warlock_t::convert_hybrid_stat( stat_e s ) const bool warlock_t::validate_actor() { - // TODO: Remove this when Midnight is properly supported - if ( sim->dbc->wowv() < wowv_t( 13, 0, 0 ) ) - { - std::string patch = "Midnight prepatch"; - if ( sim->dbc->wowv() > wowv_t( 12, 0, 0 ) ) - patch = "Midnight"; - throw sc_unsupported_specialization( fmt::format( "Warlock sims are non functional for {}", patch ) ); - return false; - } - + // Warlock Midnight support: guard removed — all three specs now sim + // with vilefiend and dimensional_rift fixes below return true; } diff --git a/engine/class_modules/warlock/sc_warlock_actions.cpp b/engine/class_modules/warlock/sc_warlock_actions.cpp index 90b06eb6371..b7689bf0f17 100644 --- a/engine/class_modules/warlock/sc_warlock_actions.cpp +++ b/engine/class_modules/warlock/sc_warlock_actions.cpp @@ -3303,15 +3303,20 @@ using namespace helpers; { harmful = may_crit = false; + // The talent spell (1251778) has 0s cooldown in Midnight DBC data, + // but the actual in-game cooldown is 45s. Hardcode until DBC is fixed. + cooldown->duration = timespan_t::from_seconds( 45.0 ); + triggers.diabolic_ritual = p->hero.diabolic_ritual.ok(); } void execute() override { warlock_spell_t::execute(); - + p()->buffs.vilefiend->trigger( -1, 1.0 ); // Set value to 1.0 to allow Houndmasters Gambit talent to apply - p()->warlock_pet_list.vilefiends.spawn( p()->talents.summon_vilefiend->duration() ); + // Talent spell 1251778 has 0s duration — spell 1251781 has the correct 15s + p()->warlock_pet_list.vilefiends.spawn( p()->find_spell( 1251781 )->duration() ); } }; @@ -4181,6 +4186,10 @@ using namespace helpers; energize_type = action_energize::ON_CAST; energize_amount = p->talents.dimensional_rift->effectN( 2 ).base_value() / 10.0; + + // Spell data has 3 charges / 45s recharge but the charge system + // was never initialized, causing infinite-cast loops + cooldown->charges = as( data().charges() ); } void execute() override diff --git a/engine/class_modules/warlock/sc_warlock_init.cpp b/engine/class_modules/warlock/sc_warlock_init.cpp index 28940714bae..7f41753c5f7 100644 --- a/engine/class_modules/warlock/sc_warlock_init.cpp +++ b/engine/class_modules/warlock/sc_warlock_init.cpp @@ -376,6 +376,9 @@ namespace warlock warlock_pet_list.doomguards.set_default_duration( talents.doomguard->duration() ); warlock_pet_list.greater_dreadstalkers.set_default_duration( tier.greater_dreadstalker->duration() ); + + // Talent spell 1251778 has 0s duration — spell 1251781 has the correct 15s + warlock_pet_list.vilefiends.set_default_duration( find_spell( 1251781 )->duration() ); } void warlock_t::init_spells_destruction() @@ -773,8 +776,9 @@ namespace warlock buffs.dreadstalkers = make_buff( this, "dreadstalkers" )->set_max_stack( 8 ) ->set_duration( talents.call_dreadstalkers_2->duration() ); + // Talent spell 1251778 has 0s duration — spell 1251781 has the correct 15s buffs.vilefiend = make_buff( this, "vilefiend" )->set_max_stack( 2 ) - ->set_duration( talents.summon_vilefiend->duration() ); + ->set_duration( find_spell( 1251781 )->duration() ); buffs.tyrant = make_buff( this, "tyrant" )->set_max_stack( 1 ) ->set_duration( talents.summon_demonic_tyrant->duration() );