tjc12821

Untitled

Sep 24th, 2016
173
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.47 KB | None | 0 0
  1. struct voidform_t final : public priest_buff_t<buff_t>
  2. {
  3. struct insanity_loss_event_t final : public player_event_t
  4. {
  5. voidform_t* vf;
  6.  
  7. insanity_loss_event_t( voidform_t* s )
  8. : player_event_t( *s->player ), vf( s )
  9. {
  10. add_event( timespan_t::from_seconds( 0.05 ) ); // See note below.
  11. }
  12.  
  13. const char* name() const override
  14. {
  15. return "voidform_insanity_loss";
  16. }
  17.  
  18. void execute() override
  19. {
  20. // Updated 2016-06-08 by Twintop:
  21. // ---
  22. // http://us.battle.net/wow/en/forum/topic/20743504316?page=2#31
  23. // http://us.battle.net/wow/en/forum/topic/20743504316?page=4#71
  24. // ---
  25. // Drain starts at 9 over 1 second and increases by 1 over 2 seconds per
  26. // stack of Voidform. I.E.: 9 over t=0->1, 9.5 over t=1->2, etc.
  27. // Drain happens continuously, like energy in reverse.
  28. // We make ticks happen every 0.05sec to get as close to contiunuous as
  29. // possible without killing simulation lengths.
  30. // CHECK ME: Triggering Voidform in-game and not using any abilities
  31. // results in 10 stacks, rarely 11 stacks if you have high latency.
  32. // Sim seems to mostly get 9 stacks, rarely 10 stacks.
  33. // ---
  34. // 2016/06/05 update by Twintop:
  35. // The drain amount for Insanity is tracked separately from the Voidform
  36. // stacks. "Insanity Drain Stacks" always begins at 1 (Legendary Shoulders
  37. // can let you start with more stacks of Voidform). Using Dispersion or
  38. // Void Torrent cause these "Insanity Drain Stacks" to pause while being
  39. // channeled.
  40. auto priest = debug_cast<priest_t*>( player() );
  41.  
  42. // LOGIC/SANITY CHECK:
  43. // Stack 1 = 9 insanity = ( -4500 / -500 ) + ( (1 - 1) / 2 ) = 9 + (0 /
  44. // 2) = 9
  45. // Stack 2 = 9.5 insanity = ( -4500) / -500 ) + ( (2 - 1) / 2 ) = 9 +
  46. // (1/2) = 9.5
  47. double insanity_loss =
  48. ( ( priest->buffs.voidform->data().effectN( 2 ).base_value() /
  49. -500 ) +
  50. ( ( priest->buffs.insanity_drain_stacks->check() - 1 ) / 2 ) ) *
  51. 0.05;
  52.  
  53. if ( insanity_loss > priest->resources.current[ RESOURCE_INSANITY ] )
  54. {
  55. insanity_loss = priest->resources.current[ RESOURCE_INSANITY ];
  56. }
  57.  
  58. priest->resource_loss( RESOURCE_INSANITY, insanity_loss,
  59. priest->gains.insanity_drain );
  60.  
  61. if ( priest->buffs.dispersion->check() )
  62. {
  63. priest->resource_gain( RESOURCE_INSANITY, insanity_loss,
  64. priest->gains.insanity_dispersion );
  65. }
  66.  
  67. if ( priest->buffs.void_torrent->check() )
  68. {
  69. priest->resource_gain( RESOURCE_INSANITY, insanity_loss,
  70. priest->gains.insanity_void_torrent );
  71. }
  72.  
  73. // If you don't have enough insanity for the drain, you drop out
  74. // with however much insanity you had left. HOWEVER, there is a
  75. // bug presently where this extra insanity doesn't count towards
  76. // your next Voidform. We're going to just remove this extra
  77. // insanity and drop down to 0 until this bug is fixed, one way
  78. // or another. -- 2014/04/17 Twintop
  79. if ( priest->resources.current[ RESOURCE_INSANITY ] == 0 )
  80. {
  81. if ( sim().debug )
  82. {
  83. sim().out_debug << "Insanity-loss event cancels voidform because "
  84. "priest is out of insanity.";
  85. }
  86. vf->insanity_loss = nullptr; // avoid double-canceling
  87. priest->buffs.voidform->expire();
  88. priest->buffs.sphere_of_insanity->expire();
  89. return;
  90. }
  91.  
  92. vf->insanity_loss = new ( sim() ) insanity_loss_event_t( vf );
  93. }
  94. };
  95.  
  96. insanity_loss_event_t* insanity_loss;
  97.  
  98. voidform_t( priest_t& p )
  99. : base_t( p, buff_creator_t( &p, "voidform" )
  100. .spell( p.find_spell( 194249 ) )
  101. .add_invalidate( CACHE_PLAYER_DAMAGE_MULTIPLIER )
  102. .add_invalidate( CACHE_HASTE )
  103. .add_invalidate( CACHE_PLAYER_HEAL_MULTIPLIER ) ),
  104. insanity_loss( nullptr )
  105. {
  106. }
  107.  
  108. bool trigger( int stacks, double value, double chance,
  109. timespan_t duration ) override
  110. {
  111. bool r = base_t::trigger( stacks, value, chance, duration );
  112.  
  113. assert( insanity_loss == nullptr );
  114. insanity_loss = new ( *sim ) insanity_loss_event_t( this );
  115.  
  116. priest.buffs.insanity_drain_stacks->trigger();
  117. priest.buffs.the_twins_painful_touch->trigger();
  118.  
  119. return r;
  120. }
  121.  
  122. void expire_override( int expiration_stacks,
  123. timespan_t remaining_duration ) override
  124. {
  125. if ( priest.buffs.lingering_insanity->check() )
  126. priest.buffs.lingering_insanity->expire();
  127.  
  128. priest.buffs.insanity_drain_stacks->expire();
  129.  
  130. priest.buffs.lingering_insanity->trigger( expiration_stacks );
  131.  
  132. priest.buffs.the_twins_painful_touch->expire();
  133.  
  134. if ( priest.buffs.surrender_to_madness->check() )
  135. {
  136. if ( sim->log )
  137. {
  138. sim->out_log.printf(
  139. "%s %s: Surrender to Madness kills you. You die. Horribly.",
  140. priest.name(), name() );
  141. }
  142. priest.demise();
  143. priest.arise();
  144. priest.buffs.surrender_to_madness_death->trigger();
  145. }
  146.  
  147. event_t::cancel( insanity_loss );
  148.  
  149. base_t::expire_override( expiration_stacks, remaining_duration );
  150. }
  151.  
  152. void reset() override
  153. {
  154. base_t::reset();
  155.  
  156. event_t::cancel( insanity_loss );
  157. }
  158. };
Advertisement
Add Comment
Please, Sign In to add comment