OP, for the purpose of DoT (or heavy casts like Chaos Bolt) snapshotting you might want to know only the present and future (I prefer to call it "projected") value of your stats. I use my custom rotation engine but I think the following approach could implemented in PE as well.
1. I use some abstract score of buff's utility called "Burst rating". The score for each buff of interest is set manually.
The table of such buffs of interest is as follows. I filled it with some sample content:
Code:
RRR_DB.bursts = {
--[<buff_id>] = { rating = <buff_burst_rating> },
--ratings are purely imaginary though they can be interpreted as "main stat value"
--general INT
[105702] = { rating = 4000 }, --potion MoP
[104993] = { rating = 1650 }, --jade spirit
[125487] = { rating = 2000 }, --lightweave INT
[96230] = { rating = 1920 }, --synapse springs INT
[126705] = { rating = 6750 }, --pvp proc trinket INT
[126683] = { rating = 5000 }, --pvp use trinket INT
--druid
[102560] = { rating = 9000 }, --incarnation
[112071] = { rating = 9000 }, --celestial alignment
[124974] = { rating = 4000 }, --nature's vigil
}
2. Then you need to store info of all buffs you get. How you do so is entirely of your choosing, but the result you should aim for is a table contating buff_id as keys and buff_info (table) as values, which would be updated on various events concerning your buffs.
3. Given the tables of bursts of interest and your current buffs, you need a function to calculate and project your burst rating.
Mine looks as follows:
Code:
function ProjectBurstRating(horizon)
--NOTE
--for every horizon, epsilon > 0 : ProjectBurstRating(horizon) >= ProjectBurstRating(horizon + epsilon)
horizon = horizon or 0
local current_time = GetTime()
local burst_rating = 1
local first_expiry_in = math.huge
for id, burst_info in pairs(RRR_DB.bursts) do
local buff = RRR_PlayerInfo.player_data.buffs[id] --it's the table of stored buffs
if buff then
burst_rating = burst_rating + burst_info.rating * buff.num_stacks
local buff_expiry_in = buff.expiry_time - current_time
if buff_expiry_in <= first_expiry_in then
first_expiry_in = buff_expiry_in
end
if buff.expiry_time - current_time <= horizon then
burst_rating = burst_rating - burst_info.rating * buff.num_stacks
end
end
end
return burst_rating, first_expiry_in
end
4. Given the knowledge of your current and future "power", it's easy to decide whether it's time to refresh your DoTs or cast a long yet powerful cast.
Chaos Bolt example:
Code:
local critical_ratio = 1.5
if ( ProjectBurstRating( CB_cast_time + 0.5 ) / ProjectBurstRating(0) ) >= critical_ratio then --our bursts are about to expire!
CastSpellByID(CB_id)
end