@@ -1148,7 +1148,7 @@ struct warrior_action_t : public parse_action_effects_t<Base>
1148
1148
parse_effects( p()->buff.juggernaut );
1149
1149
parse_effects( p()->buff.merciless_bonegrinder );
1150
1150
parse_effects( p()->buff.storm_of_swords );
1151
- parse_effects( p()->buff.recklessness_warlords_torment );
1151
+ parse_effects( p()->buff.recklessness_warlords_torment, effect_mask_t( true ).disable( 10, 11, 12 ) );
1152
1152
1153
1153
parse_effects( p()->buff.strike_vulnerabilities ); // T29 arms
1154
1154
parse_effects( p()->buff.crushing_advance ); // T30 Arms 4pc
@@ -1745,6 +1745,147 @@ struct warrior_attack_t : public warrior_action_t<melee_attack_t>
1745
1745
}
1746
1746
};
1747
1747
1748
+ // Avatar ===================================================================
1749
+
1750
+ struct avatar_t : public warrior_spell_t
1751
+ {
1752
+ timespan_t warlords_torment_duration;
1753
+ timespan_t berserkers_torment_duration;
1754
+ timespan_t titans_torment_duration;
1755
+ timespan_t avatar_of_the_storm_duration;
1756
+ timespan_t immovable_object_duration;
1757
+ bool from_torment;
1758
+ bool from_avatar_of_the_storm;
1759
+ bool from_immovable_object;
1760
+ avatar_t( warrior_t* p, util::string_view options_str, util::string_view n, const spell_data_t* spell )
1761
+ : warrior_spell_t( n, p, spell ),
1762
+ warlords_torment_duration( 0_s ),
1763
+ berserkers_torment_duration( 0_s ),
1764
+ titans_torment_duration( 0_s ),
1765
+ avatar_of_the_storm_duration( 0_s ),
1766
+ immovable_object_duration( 0_s ),
1767
+ from_torment( false ),
1768
+ from_avatar_of_the_storm( false ),
1769
+ from_immovable_object( false )
1770
+ {
1771
+
1772
+ parse_options( options_str );
1773
+ harmful = false;
1774
+ target = p;
1775
+ }
1776
+
1777
+ avatar_t( util::string_view name, warrior_t* p )
1778
+ : warrior_spell_t( name, p, p->talents.warrior.avatar ),
1779
+ warlords_torment_duration( 0_s ),
1780
+ berserkers_torment_duration( 0_s ),
1781
+ titans_torment_duration( 0_s ),
1782
+ avatar_of_the_storm_duration( 0_s ),
1783
+ immovable_object_duration( 0_s ),
1784
+ from_torment( false ),
1785
+ from_avatar_of_the_storm( false ),
1786
+ from_immovable_object( false )
1787
+ {
1788
+ background = true;
1789
+ trigger_gcd = timespan_t::zero();
1790
+ harmful = false;
1791
+ target = p;
1792
+
1793
+ if ( p->talents.warrior.warlords_torment->ok() )
1794
+ warlords_torment_duration = p->talents.warrior.warlords_torment->effectN( 1 ).time_value();
1795
+
1796
+ if ( p->talents.warrior.berserkers_torment->ok() )
1797
+ berserkers_torment_duration = p->talents.warrior.berserkers_torment->effectN( 2 ).time_value();
1798
+
1799
+ if ( p->talents.warrior.titans_torment->ok() )
1800
+ titans_torment_duration = p->talents.warrior.titans_torment->effectN( 1 ).time_value();
1801
+
1802
+ if ( p->talents.warrior.immovable_object->ok() )
1803
+ immovable_object_duration = p->talents.warrior.immovable_object->effectN( 2 ).time_value();
1804
+
1805
+ if ( p->talents.mountain_thane.avatar_of_the_storm->ok() )
1806
+ avatar_of_the_storm_duration = timespan_t::from_seconds( p->talents.mountain_thane.avatar_of_the_storm->effectN( 3 ).base_value() );
1807
+ }
1808
+
1809
+ struct state_t : public action_state_t
1810
+ {
1811
+ using action_state_t::action_state_t;
1812
+
1813
+ proc_types2 cast_proc_type2() const override
1814
+ {
1815
+ // This spell can trigger on-cast procs even if it is backgrounded
1816
+ return PROC2_CAST_GENERIC;
1817
+ }
1818
+ };
1819
+
1820
+ action_state_t* new_state() override
1821
+ {
1822
+ return new state_t( this, target );
1823
+ }
1824
+
1825
+ void execute() override
1826
+ {
1827
+ warrior_spell_t::execute();
1828
+
1829
+ if ( !background ) // For Hard Cast Avatar
1830
+ {
1831
+ // Trigger main buff
1832
+ p()->buff.avatar->extend_duration_or_trigger();
1833
+
1834
+ // Arms
1835
+ if ( p()->talents.warrior.blademasters_torment.ok() )
1836
+ p()->buff.sweeping_strikes->extend_duration_or_trigger( p()->talents.warrior.blademasters_torment->effectN( 1 ).time_value() );
1837
+
1838
+ if ( p()->talents.warrior.warlords_torment->ok() )
1839
+ p()->buff.recklessness_warlords_torment->extend_duration_or_trigger( warlords_torment_duration );
1840
+
1841
+ // Fury
1842
+ if ( p()->talents.warrior.berserkers_torment.ok() )
1843
+ p()->active.torment_recklessness->schedule_execute();
1844
+
1845
+ if ( !p()->is_ptr() && p()->talents.warrior.titans_torment->ok() )
1846
+ p()->active.torment_odyns_fury->schedule_execute();
1847
+
1848
+ // Protection
1849
+ if ( p()->talents.warrior.immovable_object->ok() )
1850
+ p()->buff.shield_wall->extend_duration_or_trigger( immovable_object_duration );
1851
+
1852
+ // Hero Talents
1853
+ // Mountain Thane
1854
+ if ( p()->talents.mountain_thane.avatar_of_the_storm->ok() )
1855
+ {
1856
+ p()->buff.thunder_blast->trigger( as<int> ( p()->talents.mountain_thane.avatar_of_the_storm->effectN( 1 ).base_value() ) );
1857
+ p()->cooldown.thunder_clap->reset( true );
1858
+ }
1859
+ }
1860
+ else // For background triggered avatar procs
1861
+ {
1862
+ // Fury
1863
+ if ( p()->talents.warrior.berserkers_torment->ok() && from_torment )
1864
+ p()->buff.avatar->extend_duration_or_trigger( berserkers_torment_duration );
1865
+
1866
+ if ( !p()->is_ptr() && p()->talents.warrior.titans_torment->ok() && from_torment )
1867
+ p()->buff.avatar->extend_duration_or_trigger( titans_torment_duration );
1868
+
1869
+ // Protection
1870
+ if ( p()->talents.warrior.immovable_object->ok() && from_immovable_object )
1871
+ p()->buff.avatar->extend_duration_or_trigger( immovable_object_duration );
1872
+
1873
+ // Mountain Thane
1874
+ if ( from_avatar_of_the_storm )
1875
+ p()->buff.avatar->extend_duration_or_trigger( avatar_of_the_storm_duration );
1876
+ }
1877
+ }
1878
+
1879
+ bool verify_actor_spec() const override // no longer needed ?
1880
+ {
1881
+ // Do not check spec if Arms talent avatar is available, so that spec check on the spell (required: protection) does not fail.
1882
+ if ( p()->talents.warrior.avatar->ok() && p()->specialization() == WARRIOR_ARMS )
1883
+ return true;
1884
+
1885
+ return warrior_spell_t::verify_actor_spec();
1886
+ }
1887
+ };
1888
+
1748
1889
// Reap the Storm ===========================================================
1749
1890
1750
1891
struct reap_the_storm_t : public warrior_attack_t
@@ -2360,10 +2501,12 @@ struct ground_current_t : public warrior_attack_t
2360
2501
struct lightning_strike_t : public warrior_attack_t
2361
2502
{
2362
2503
action_t* ground_current;
2504
+ action_t* avatar;
2363
2505
double rage_from_thorims_might;
2364
2506
lightning_strike_t( util::string_view name, warrior_t* p )
2365
2507
: warrior_attack_t( name, p, p->spell.lightning_strike ),
2366
2508
ground_current( nullptr ),
2509
+ avatar( nullptr ),
2367
2510
rage_from_thorims_might( 0 )
2368
2511
{
2369
2512
background = true;
@@ -2379,6 +2522,12 @@ struct lightning_strike_t : public warrior_attack_t
2379
2522
{
2380
2523
rage_from_thorims_might = p->talents.mountain_thane.thorims_might->effectN( 1 ).resource( RESOURCE_RAGE );
2381
2524
}
2525
+
2526
+ if ( p->talents.mountain_thane.avatar_of_the_storm->ok() )
2527
+ {
2528
+ avatar = new avatar_t( "avatar_avatar_of_the_storm", p );
2529
+ debug_cast<avatar_t*>(avatar)->from_avatar_of_the_storm = true;
2530
+ }
2382
2531
}
2383
2532
2384
2533
void impact( action_state_t* s ) override
@@ -2405,7 +2554,7 @@ struct lightning_strike_t : public warrior_attack_t
2405
2554
if ( p()->talents.mountain_thane.avatar_of_the_storm->ok() && !p()->buff.avatar->check() )
2406
2555
{
2407
2556
if ( rng().roll( p()->talents.mountain_thane.avatar_of_the_storm->effectN( 2 ).percent() ) )
2408
- p()->buff. avatar->extend_duration_or_trigger( timespan_t::from_seconds( p()->talents.mountain_thane.avatar_of_the_storm->effectN( 3 ).base_value() ) );
2557
+ avatar->schedule_execute( );
2409
2558
}
2410
2559
}
2411
2560
};
@@ -5867,10 +6016,7 @@ struct odyns_fury_t : warrior_attack_t
5867
6016
oh_attack2->execute();
5868
6017
5869
6018
if ( !p()->is_ptr() && p()->talents.warrior.titans_torment->ok() )
5870
- {
5871
- action_t* torment_ability = p()->active.torment_avatar;
5872
- torment_ability->schedule_execute();
5873
- }
6019
+ p()->active.torment_avatar->schedule_execute();
5874
6020
5875
6021
if ( p()->tier_set.t31_fury_2pc->ok() )
5876
6022
{
@@ -7521,96 +7667,6 @@ struct champions_spear_t : public warrior_attack_t
7521
7667
// Warrior Spells
7522
7668
// ==========================================================================
7523
7669
7524
- // Avatar ===================================================================
7525
-
7526
- struct avatar_t : public warrior_spell_t
7527
- {
7528
- avatar_t( warrior_t* p, util::string_view options_str, util::string_view n, const spell_data_t* spell )
7529
- : warrior_spell_t( n, p, spell )
7530
- {
7531
-
7532
- parse_options( options_str );
7533
- callbacks = false;
7534
- harmful = false;
7535
- target = p;
7536
- }
7537
-
7538
- void execute() override
7539
- {
7540
- warrior_spell_t::execute();
7541
-
7542
- if ( p()->talents.warrior.immovable_object->ok() )
7543
- p()->buff.shield_wall->trigger( p()->talents.warrior.immovable_object->effectN( 2 ).time_value() );
7544
-
7545
- p()->buff.avatar->extend_duration_or_trigger();
7546
-
7547
- if ( p()->talents.warrior.berserkers_torment.ok() )
7548
- {
7549
- action_t* torment_ability = p()->active.torment_recklessness;
7550
- torment_ability->schedule_execute();
7551
- }
7552
- if ( p()->talents.warrior.blademasters_torment.ok() )
7553
- {
7554
- p()->buff.sweeping_strikes->extend_duration_or_trigger( p()->talents.warrior.blademasters_torment->effectN( 1 ).time_value() );
7555
- }
7556
- if ( !p()->is_ptr() && p()->talents.warrior.titans_torment->ok() )
7557
- {
7558
- action_t* torment_ability = p()->active.torment_odyns_fury;
7559
- torment_ability->schedule_execute();
7560
- }
7561
-
7562
- if ( p()->talents.warrior.warlords_torment->ok() )
7563
- {
7564
- const timespan_t trigger_duration = p()->talents.warrior.warlords_torment->effectN( 1 ).time_value();
7565
- p()->buff.recklessness_warlords_torment->extend_duration_or_trigger( trigger_duration );
7566
- }
7567
-
7568
- if ( p()->talents.mountain_thane.avatar_of_the_storm->ok() )
7569
- {
7570
- p()->buff.thunder_blast->trigger( as<int> ( p()->talents.mountain_thane.avatar_of_the_storm->effectN( 1 ).base_value() ) );
7571
- p()->cooldown.thunder_clap->reset( true );
7572
- }
7573
- }
7574
-
7575
- bool verify_actor_spec() const override // no longer needed ?
7576
- {
7577
- // Do not check spec if Arms talent avatar is available, so that spec check on the spell (required: protection) does not fail.
7578
- if ( p()->talents.warrior.avatar->ok() && p()->specialization() == WARRIOR_ARMS )
7579
- return true;
7580
-
7581
- return warrior_spell_t::verify_actor_spec();
7582
- }
7583
- };
7584
-
7585
- // Torment Avatar ===================================================================
7586
-
7587
- struct torment_avatar_t : public warrior_spell_t
7588
- {
7589
- torment_avatar_t( warrior_t* p, util::string_view options_str, util::string_view n, const spell_data_t* spell )
7590
- : warrior_spell_t( n, p, spell )
7591
- {
7592
- parse_options( options_str );
7593
- callbacks = false;
7594
- target = p;
7595
- }
7596
-
7597
- void execute() override
7598
- {
7599
- warrior_spell_t::execute();
7600
-
7601
- if ( p()->talents.warrior.berserkers_torment->ok() )
7602
- {
7603
- const timespan_t trigger_duration = p()->talents.warrior.berserkers_torment->effectN( 2 ).time_value();
7604
- p()->buff.avatar->extend_duration_or_trigger( trigger_duration );
7605
- }
7606
- if ( !p()->is_ptr() && p()->talents.warrior.titans_torment->ok() )
7607
- {
7608
- const timespan_t trigger_duration = p()->talents.warrior.titans_torment->effectN( 1 ).time_value();
7609
- p()->buff.avatar->extend_duration_or_trigger( trigger_duration );
7610
- }
7611
- }
7612
- };
7613
-
7614
7670
// Battle Shout ===================================================================
7615
7671
7616
7672
struct battle_shout_t : public warrior_spell_t
@@ -7983,15 +8039,10 @@ struct recklessness_t : public warrior_spell_t
7983
8039
p()->buff.recklessness->extend_duration_or_trigger();
7984
8040
7985
8041
if ( p()->talents.warrior.berserkers_torment.ok() )
7986
- {
7987
- action_t* torment_ability = p()->active.torment_avatar;
7988
- torment_ability->schedule_execute();
7989
- }
8042
+ p()->active.torment_avatar->schedule_execute();
7990
8043
7991
8044
if ( p()->talents.mountain_thane.snap_induction->ok() )
7992
- {
7993
8045
p()->buff.thunder_blast->trigger();
7994
- }
7995
8046
}
7996
8047
7997
8048
bool verify_actor_spec() const override
@@ -8151,12 +8202,21 @@ struct shield_block_t : public warrior_spell_t
8151
8202
8152
8203
struct shield_wall_t : public warrior_spell_t
8153
8204
{
8205
+ action_t* avatar;
8154
8206
shield_wall_t( warrior_t* p, util::string_view options_str )
8155
- : warrior_spell_t( "shield_wall", p, p->talents.protection.shield_wall )
8207
+ : warrior_spell_t( "shield_wall", p, p->talents.protection.shield_wall ),
8208
+ avatar( nullptr )
8156
8209
{
8157
8210
parse_options( options_str );
8158
8211
harmful = false;
8159
8212
range = -1;
8213
+
8214
+ if ( p->talents.warrior.immovable_object->ok() )
8215
+ {
8216
+ avatar = new avatar_t( "avatar_immovable_object", p );
8217
+ debug_cast<avatar_t*>(avatar)->from_immovable_object = true;
8218
+ }
8219
+
8160
8220
}
8161
8221
8162
8222
void execute() override
@@ -8166,7 +8226,7 @@ struct shield_wall_t : public warrior_spell_t
8166
8226
p()->buff.shield_wall->trigger( 1, p()->buff.shield_wall->data().effectN( 1 ).percent() );
8167
8227
8168
8228
if ( p()->talents.warrior.immovable_object->ok() )
8169
- p()->buff. avatar->trigger( p()->talents.warrior.immovable_object->effectN( 2 ).time_value() );
8229
+ avatar->schedule_execute( );
8170
8230
}
8171
8231
};
8172
8232
@@ -10105,7 +10165,8 @@ void warrior_t::create_actions()
10105
10165
if ( talents.warrior.berserkers_torment->ok() )
10106
10166
{
10107
10167
active.torment_recklessness = new torment_recklessness_t( this, "", "recklessness_torment", find_spell( 1719 ) );
10108
- active.torment_avatar = new torment_avatar_t( this, "", "avatar_torment", find_spell( 107574 ) );
10168
+ active.torment_avatar = new avatar_t( "avatar_torment", this );
10169
+ debug_cast<avatar_t*>(active.torment_avatar)->from_torment = true;
10109
10170
for ( action_t* action : { active.torment_recklessness, active.torment_avatar } )
10110
10171
{
10111
10172
action->background = true;
@@ -10114,7 +10175,8 @@ void warrior_t::create_actions()
10114
10175
}
10115
10176
if ( !is_ptr() && talents.warrior.titans_torment->ok() )
10116
10177
{
10117
- active.torment_avatar = new torment_avatar_t( this, "", "avatar_torment", find_spell( 107574 ) );
10178
+ active.torment_avatar = new avatar_t( "avatar_torment", this );
10179
+ debug_cast<avatar_t*>(active.torment_avatar)->from_torment = true;
10118
10180
active.torment_odyns_fury = new torment_odyns_fury_t( this, "", "odyns_fury_torment", find_spell( 385059 ) );
10119
10181
for ( action_t* action : { active.torment_avatar, active.torment_odyns_fury } )
10120
10182
{
0 commit comments