|
You're forgetting that soothing's tick frequency (and by extension chi generation rate) scales with haste. At 3145 haste you get an average of 0.41 chi per second, or 7.3 seconds on average to get 3 chi. So I was a little off in saying you could get 100% uptime just from soothing at that particular haste level.
|
Note that Enveloping's tick rate scales at exactly the same rate as Soothing's, so really the only thing that matters for Enveloping uptime is chi per tick, not chi per second.
Assuming sub-5380 haste rating (so Enveloping has 7 ticks), we need to generate at least 3 Chi in 7 ticks to maintain 100% uptime. There has a 46.8% chance of this occurring. 53.2% of the time, we'll end up failing to get the Chi for 100% uptime.
Given 7 ticks, we can refresh Enveloping without clipping no earlier than the 6th tick. The probability of getting 4 or more Chi (and thus potentially wasting 1) in 6 ticks of Soothing is 11.7%.
Unfortunately, calculating the actual average downtime is difficult without a sim, as binomials can't account for the ability to "pool" chi. For example, if you overgenerate during the duration of one Enveloping, those chi are not necessarily wasted. Let's say you cast Enveloping right at 3 Chi, then generate 5 Chi over the next 6 ticks. You refresh Enveloping just after the 6th tick, dropping back down to 2 Chi, but then only generate 1 more Chi over the next 7 ticks (this assume you have Ascension, for the record). You still have enough Chi to cast Enveloping again, and despite the fact that you overgenerate on the first cast and undergenerated on the second, you had no wasted chi or downtime. This probably
can be analytically evaluated, but is beyond my capabilities. I'll see if I can scratch together a rough sim to test it.
Edit: Thrown together, it's showing an average of 19.6% downtime and 1.77% Chi waste over 100k iteration at 300 ± 60 seconds duration. Assumptions: Ascension talented, no other spells used, Soothing Mist refreshing ignored entirely. Removal of Ascension raises downtime to 21.2% and Chi waste to 3.78%.
Bumping to 8 tick duration (5380 breakpoint) gives 11.6% downtime and 4.94% waste with Ascension, 13.79% downtime and 7.67% waste without.

// PROVIDED BY: M. Scott Leuthaeuser
// CONTACT E-MAIL: michael (dot) leuthaeuser [at] gmail (dot) com
// FILE: ChiSim.cpp
// VERSION: 0.1.0.A
// PURPOSE: Simulate Enveloping Mist uptime under ideal conditions
// DIRECTIVES -----------------------------------------------------------------
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <ctime>
#include <string>
#include <conio.h>
using namespace std;
// ----------------------------------------------------------------------------
// STRUCTURES------------------------------------------------------------------
struct Sim
{
float time;
int chiGenerated;
int chiWasted;
float downtime;
};
// ----------------------------------------------------------------------------
// GLOBAL CONSTANTS -----------------------------------------------------------
const int G_CHI_PROBABILITY = 35; // Probability of generating 1 Chi each tick
const int G_ITERATIONS = 100000; // Number of iterations
const float G_TIME = 300.0; // Average total sim duration
const float G_VARIANCE = 0.2; // Variation on total sim duration as a percent of G_TIME
const float G_DURATION = 7.0; // Enveloping duration in ticks
const float G_REFRESH = 1.0; // Number of ticks you can fresh early and still get full duration
const int G_CHI_MAX = 4; // Max Chi pool
const int G_CHI_INIT = 3; // How much Chi you start with
const int G_CHI_REQ = 3; // How much Chi Enveloping consumes
// ----------------------------------------------------------------------------
// FUNCTION PROTOTYPES --------------------------------------------------------
Sim simulate(float time);
// ----------------------------------------------------------------------------
// ============================================================================
int main()
{
Sim total, iteration;
total.time = 0;
total.chiGenerated = 0;
total.chiWasted = 0;
total.downtime = 0;
srand(time(0));
// Simulate
for(int c = 0; c < G_ITERATIONS; ++c)
{
iteration = simulate(G_TIME * (1.0 +
(G_VARIANCE*2*((rand()%101)/100.0) - G_VARIANCE)));
total.time += iteration.time;
total.chiGenerated += iteration.chiGenerated;
total.chiWasted += iteration.chiWasted;
total.downtime += iteration.downtime;
}
// Output results
cout << "AVERAGE DOWNTIME: " << total.downtime/G_ITERATIONS << " / " << total.time/G_ITERATIONS << " (" << total.downtime/total.time*100 << "%)" << endl;
cout << "AVERAGE CHI WASTED: " << (float)total.chiWasted/G_ITERATIONS << " / " << (float)total.chiGenerated/G_ITERATIONS << " (" << (float)total.chiWasted/(float)total.chiGenerated*100 << "%)" << endl;
// Pause
cout << endl << "Press any key to continue...";
cin.sync();
_getch();
// Exit
return 0;
}
// ============================================================================
Sim simulate(float time)
{
Sim i;
i.time = 0;
i.chiGenerated = 0;
i.chiWasted = 0;
i.downtime = 0;
int chi = G_CHI_INIT;
float remDuration = 0;
for(i.time; i.time < time; i.time++)
{
// cout << "TIME: " << i.time << ", CHI: " << chi << ", DURATION: " << remDuration;
if(remDuration < G_REFRESH && chi >= G_CHI_REQ)
{
// cout << " REFRESH!";
chi -= G_CHI_REQ;
remDuration += G_DURATION;
}
if(remDuration == 0)
{
// cout << " DOWNTIME!";
i.downtime++;
}
if(rand()%100 < G_CHI_PROBABILITY)
{
if(chi == G_CHI_MAX)
{
// cout << " CHI WASTED!";
i.chiWasted++;
}
else
{
// cout << " CHI GENERATED!";
chi++;
}
i.chiGenerated++;
}
// cout << endl;
if(remDuration > 1.0)
remDuration--;
else
remDuration = 0;
}
return i;
}