Johnny C. Lam [11-27-13 - 14:04]
diff --git a/OvaleAura.lua b/OvaleAura.lua
index abff51c..0563359 100644
--- a/OvaleAura.lua
+++ b/OvaleAura.lua
@@ -502,6 +502,17 @@ OvaleAura.statePrototype = {
}
--</public-static-properties>
+--<private-static-properties>
+local statePrototype = OvaleAura.statePrototype
+--</private-static-properties>
+
+--<state-properties>
+-- Aura database: aura[guid][auraId][casterId] = aura
+statePrototype.aura = nil
+-- Age of active auras in the simulator.
+statePrototype.serial = nil
+--</state-properties>
+
--<public-static-methods>
-- Initialize the state.
function OvaleAura:InitializeState(state)
@@ -545,359 +556,355 @@ end
--</public-static-methods>
--<state-methods>
-do
- local statePrototype = OvaleAura.statePrototype
-
- local function GetStateAura(state, guid, auraId, casterGUID)
- local auraFound = GetAura(state.aura, guid, auraId, casterGUID)
- if not state:IsActiveAura(auraFound) then
- auraFound = GetAura(self_aura, guid, auraId, casterGUID)
- end
- return auraFound
+local function GetStateAura(state, guid, auraId, casterGUID)
+ local auraFound = GetAura(state.aura, guid, auraId, casterGUID)
+ if not state:IsActiveAura(auraFound) then
+ auraFound = GetAura(self_aura, guid, auraId, casterGUID)
end
+ return auraFound
+end
- local function GetStateAuraAnyCaster(state, guid, auraId)
- local auraFound = GetAuraAnyCaster(state.aura, guid, auraId)
- local aura = GetAuraAnyCaster(self_aura, guid, auraId)
- local now = state.currentTime
- if OvaleAura:IsActiveAura(aura, now) then
- if not state:IsActiveAura(auraFound, now) or auraFound.ending < aura.ending then
- auraFound = aura
- end
+local function GetStateAuraAnyCaster(state, guid, auraId)
+ local auraFound = GetAuraAnyCaster(state.aura, guid, auraId)
+ local aura = GetAuraAnyCaster(self_aura, guid, auraId)
+ local now = state.currentTime
+ if OvaleAura:IsActiveAura(aura, now) then
+ if not state:IsActiveAura(auraFound, now) or auraFound.ending < aura.ending then
+ auraFound = aura
end
- return auraFound
end
+ return auraFound
+end
- local function GetStateDebuffType(state, guid, debuffType, filter, casterGUID)
- local auraFound = GetDebuffType(state.aura, guid, debuffType, filter, casterGUID)
- local aura = GetDebuffType(self_aura, guid, debuffType, filter, casterGUID)
- local now = state.currentTime
- if OvaleAura:IsActiveAura(aura, now) then
- if not state:IsActiveAura(auraFound, now) or auraFound.ending < aura.ending then
- auraFound = aura
- end
+local function GetStateDebuffType(state, guid, debuffType, filter, casterGUID)
+ local auraFound = GetDebuffType(state.aura, guid, debuffType, filter, casterGUID)
+ local aura = GetDebuffType(self_aura, guid, debuffType, filter, casterGUID)
+ local now = state.currentTime
+ if OvaleAura:IsActiveAura(aura, now) then
+ if not state:IsActiveAura(auraFound, now) or auraFound.ending < aura.ending then
+ auraFound = aura
end
- return auraFound
end
+ return auraFound
+end
- local function GetStateDebuffTypeAnyCaster(state, guid, debuffType, filter)
- local auraFound = GetDebuffTypeAnyCaster(state.aura, guid, debuffType, filter)
- local aura = GetDebuffTypeAnyCaster(self_aura, guid, debuffType, filter)
- local now = state.currentTime
- if OvaleAura:IsActiveAura(aura, now) then
- if not state:IsActiveAura(auraFound, now) or auraFound.ending < aura.ending then
- auraFound = aura
- end
+local function GetStateDebuffTypeAnyCaster(state, guid, debuffType, filter)
+ local auraFound = GetDebuffTypeAnyCaster(state.aura, guid, debuffType, filter)
+ local aura = GetDebuffTypeAnyCaster(self_aura, guid, debuffType, filter)
+ local now = state.currentTime
+ if OvaleAura:IsActiveAura(aura, now) then
+ if not state:IsActiveAura(auraFound, now) or auraFound.ending < aura.ending then
+ auraFound = aura
end
- return auraFound
end
+ return auraFound
+end
- local function GetStateAuraOnGUID(state, guid, auraId, filter, mine)
- local auraFound
- if DEBUFF_TYPES[auraId] then
- if mine then
- auraFound = GetStateDebuffType(state, guid, auraId, filter, self_guid)
- else
- auraFound = GetStateDebuffTypeAnyCaster(state, guid, auraId, filter)
- end
+local function GetStateAuraOnGUID(state, guid, auraId, filter, mine)
+ local auraFound
+ if DEBUFF_TYPES[auraId] then
+ if mine then
+ auraFound = GetStateDebuffType(state, guid, auraId, filter, self_guid)
else
- if mine then
- auraFound = GetStateAura(state, guid, auraId, self_guid)
- else
- auraFound = GetStateAuraAnyCaster(state, guid, auraId)
- end
+ auraFound = GetStateDebuffTypeAnyCaster(state, guid, auraId, filter)
+ end
+ else
+ if mine then
+ auraFound = GetStateAura(state, guid, auraId, self_guid)
+ else
+ auraFound = GetStateAuraAnyCaster(state, guid, auraId)
end
- return auraFound
end
+ return auraFound
+end
- -- Print the auras matching the filter on the unit in alphabetical order.
- do
- local array = {}
+-- Print the auras matching the filter on the unit in alphabetical order.
+do
+ local array = {}
- statePrototype.PrintUnitAuras = function(state, unitId, filter)
- wipe(array)
- local guid = OvaleGUID:GetGUID(unitId)
- if self_aura[guid] then
- for auraId, whoseTable in pairs(self_aura[guid]) do
- for casterGUID in pairs(whoseTable) do
- local aura = GetStateAura(state, guid, auraId, casterGUID)
- if state:IsActiveAura(aura, now) and aura.filter == filter and not aura.state then
- local name = aura.name or "Unknown spell"
- tinsert(array, name .. ": " .. auraId)
- end
+ statePrototype.PrintUnitAuras = function(state, unitId, filter)
+ wipe(array)
+ local guid = OvaleGUID:GetGUID(unitId)
+ if self_aura[guid] then
+ for auraId, whoseTable in pairs(self_aura[guid]) do
+ for casterGUID in pairs(whoseTable) do
+ local aura = GetStateAura(state, guid, auraId, casterGUID)
+ if state:IsActiveAura(aura, now) and aura.filter == filter and not aura.state then
+ local name = aura.name or "Unknown spell"
+ tinsert(array, name .. ": " .. auraId)
end
end
end
- if state.aura[guid] then
- for auraId, whoseTable in pairs(state.aura[guid]) do
- for casterGUID, aura in pairs(whoseTable) do
- if state:IsActiveAura(aura, now) and aura.filter == filter then
- local name = aura.name or "Unknown spell"
- tinsert(array, name .. ": " .. auraId)
- end
+ end
+ if state.aura[guid] then
+ for auraId, whoseTable in pairs(state.aura[guid]) do
+ for casterGUID, aura in pairs(whoseTable) do
+ if state:IsActiveAura(aura, now) and aura.filter == filter then
+ local name = aura.name or "Unknown spell"
+ tinsert(array, name .. ": " .. auraId)
end
end
end
- if next(array) then
- tsort(array)
- for _, v in ipairs(array) do
- Ovale:Print(v)
- end
+ end
+ if next(array) then
+ tsort(array)
+ for _, v in ipairs(array) do
+ Ovale:Print(v)
end
end
end
+end
- statePrototype.IsActiveAura = function(state, aura, now)
- now = now or state.currentTime
- local boolean = false
- if aura then
- if aura.state then
- boolean = (aura.serial == state.serial and aura.stacks > 0 and aura.start <= now and now <= aura.ending)
- else
- boolean = OvaleAura:IsActiveAura(aura, now)
- end
+statePrototype.IsActiveAura = function(state, aura, now)
+ now = now or state.currentTime
+ local boolean = false
+ if aura then
+ if aura.state then
+ boolean = (aura.serial == state.serial and aura.stacks > 0 and aura.start <= now and now <= aura.ending)
+ else
+ boolean = OvaleAura:IsActiveAura(aura, now)
end
- return boolean
end
+ return boolean
+end
- statePrototype.ApplySpellAuras = function(state, spellId, guid, startCast, endCast, isChanneled, auraList, spellcast)
- local unitId = OvaleGUID:GetUnitId(guid)
- for filter, filterInfo in pairs(auraList) do
- for auraId, spellData in pairs(filterInfo) do
- --[[
- For lists described by SpellAddBuff(), etc., use the following interpretation:
- auraId=refresh aura is refreshed, no change to stacks
- auraId=N, N > 0 N is duration if aura has no duration SpellInfo() [deprecated].
- auraId=N, N > 0 N is number of stacks added
- auraId=0 aura is removed
- auraId=N, N < 0 N is number of stacks of aura removed
- --]]
- local si = OvaleData.spellInfo[auraId]
- local duration, dotDuration, tick, numTicks = state:GetDuration(auraId, spellcast)
- local stacks = 1
-
- if type(spellData) == "number" and spellData > 0 then
- stacks = spellData
- -- Deprecated after transition.
- if not (si and si.duration) then
- -- Aura doesn't have duration SpellInfo(), so treat spell data as duration.
- duration = spellData
- stacks = 1
- end
+statePrototype.ApplySpellAuras = function(state, spellId, guid, startCast, endCast, isChanneled, auraList, spellcast)
+ local unitId = OvaleGUID:GetUnitId(guid)
+ for filter, filterInfo in pairs(auraList) do
+ for auraId, spellData in pairs(filterInfo) do
+ --[[
+ For lists described by SpellAddBuff(), etc., use the following interpretation:
+ auraId=refresh aura is refreshed, no change to stacks
+ auraId=N, N > 0 N is duration if aura has no duration SpellInfo() [deprecated].
+ auraId=N, N > 0 N is number of stacks added
+ auraId=0 aura is removed
+ auraId=N, N < 0 N is number of stacks of aura removed
+ --]]
+ local si = OvaleData.spellInfo[auraId]
+ local duration, dotDuration, tick, numTicks = state:GetDuration(auraId, spellcast)
+ local stacks = 1
+
+ if type(spellData) == "number" and spellData > 0 then
+ stacks = spellData
+ -- Deprecated after transition.
+ if not (si and si.duration) then
+ -- Aura doesn't have duration SpellInfo(), so treat spell data as duration.
+ duration = spellData
+ stacks = 1
end
+ end
- local auraFound = state:GetAuraByGUID(guid, auraId, filter, true)
- local atTime = isChanneled and startCast or endCast
+ local auraFound = state:GetAuraByGUID(guid, auraId, filter, true)
+ local atTime = isChanneled and startCast or endCast
- if state:IsActiveAura(auraFound, atTime) then
- local aura
- if auraFound.state then
- -- Re-use existing aura in the simulator.
- aura = auraFound
- else
- -- Add an aura in the simulator and copy the existing aura information over.
- aura = state:AddAuraToGUID(guid, auraId, self_guid, filter, 0, math.huge)
- for k, v in pairs(auraFound) do
- aura[k] = v
- end
- if auraFound.snapshot then
- aura.snapshot = OvalePaperDoll:GetSnapshot(auraFound.snapshot)
- end
- -- Reset the aura age relative to the state of the simulator.
- aura.serial = state.serial
- -- Information that needs to be set below: stacks, start, ending, duration, gain.
+ if state:IsActiveAura(auraFound, atTime) then
+ local aura
+ if auraFound.state then
+ -- Re-use existing aura in the simulator.
+ aura = auraFound
+ else
+ -- Add an aura in the simulator and copy the existing aura information over.
+ aura = state:AddAuraToGUID(guid, auraId, self_guid, filter, 0, math.huge)
+ for k, v in pairs(auraFound) do
+ aura[k] = v
end
- -- Spell starts channeling before the aura expires, or spellcast ends before the aura expires.
- if spellData == "refresh" or stacks > 0 then
- -- Adjust stack count.
- if spellData == "refresh" then
- Ovale:Logf("Aura %d is refreshed.", auraId)
- else -- if stacks > 0 then
- local maxstacks = si.maxstacks or 1
- aura.stacks = aura.stacks + stacks
- if aura.stacks > maxstacks then
- aura.stacks = maxstacks
- end
- Ovale:Logf("Aura %d gains %d stack(s) to %d because of spell %d.", auraId, stacks, aura.stacks, spellId)
- end
- -- Set start and duration for aura.
- if aura.tick and aura.tick > 0 then
- -- This is a periodic aura, so add new duration after the next tick is complete.
- local ticksRemain = floor((aura.ending - atTime) / aura.tick)
- aura.start = aura.ending - aura.tick * ticksRemain
- if OvaleData:NeedNewSnapshot(auraId, spellId) then
- -- Use duration and tick information based on spellcast snapshot.
- aura.duration = dotDuration
- aura.tick = tick
- OvaleFuture:UpdateSnapshotFromSpellcast(aura, spellcast)
- end
- else
- aura.start = atTime
- if OvaleData:NeedNewSnapshot(auraId, spellId) then
- aura.duration = duration
- end
- end
- aura.ending = aura.start + aura.duration
- aura.gain = atTime
- Ovale:Logf("Aura %d now ending at %f", auraId, aura.ending)
- elseif stacks == 0 or stacks < 0 then
- if stacks == 0 then
- aura.stacks = 0
- else -- if stacks < 0 then
- aura.stacks = aura.stacks + stacks
- if aura.stacks < 0 then
- aura.stacks = 0
- end
- Ovale:Logf("Aura %d loses %d stack(s) to %d because of spell %d.", auraId, -1 * stacks, aura.stacks, spellId)
- end
- -- An existing aura is losing stacks, so inherit start, duration, ending and gain information.
- if aura.stacks == 0 then
- Ovale:Logf("Aura %d is completely removed.", auraId)
- -- The aura is completely removed, so set ending to the time that the aura is removed.
- aura.ending = atTime
+ if auraFound.snapshot then
+ aura.snapshot = OvalePaperDoll:GetSnapshot(auraFound.snapshot)
+ end
+ -- Reset the aura age relative to the state of the simulator.
+ aura.serial = state.serial
+ -- Information that needs to be set below: stacks, start, ending, duration, gain.
+ end
+ -- Spell starts channeling before the aura expires, or spellcast ends before the aura expires.
+ if spellData == "refresh" or stacks > 0 then
+ -- Adjust stack count.
+ if spellData == "refresh" then
+ Ovale:Logf("Aura %d is refreshed.", auraId)
+ else -- if stacks > 0 then
+ local maxstacks = si.maxstacks or 1
+ aura.stacks = aura.stacks + stacks
+ if aura.stacks > maxstacks then
+ aura.stacks = maxstacks
end
+ Ovale:Logf("Aura %d gains %d stack(s) to %d because of spell %d.", auraId, stacks, aura.stacks, spellId)
end
- else
- -- Aura is not on the target.
- if stacks > 0 then
- -- Spellcast causes a new aura.
- Ovale:Logf("New aura %d at %f on %s", auraId, atTime, guid)
- -- Add an aura in the simulator and copy the existing aura information over.
- local aura = state:AddAuraToGUID(guid, auraId, self_guid, filter, 0, math.huge)
- -- Information that needs to be set below: stacks, start, ending, duration, gain.
- aura.stacks = stacks
- aura.start = atTime
- -- Set start and duration for aura.
- if si and si.tick then
- -- "tick" is set explicitly in SpellInfo, so this is a known periodic aura.
+ -- Set start and duration for aura.
+ if aura.tick and aura.tick > 0 then
+ -- This is a periodic aura, so add new duration after the next tick is complete.
+ local ticksRemain = floor((aura.ending - atTime) / aura.tick)
+ aura.start = aura.ending - aura.tick * ticksRemain
+ if OvaleData:NeedNewSnapshot(auraId, spellId) then
+ -- Use duration and tick information based on spellcast snapshot.
aura.duration = dotDuration
aura.tick = tick
- aura.ticksSeen = 0
- else
+ OvaleFuture:UpdateSnapshotFromSpellcast(aura, spellcast)
+ end
+ else
+ aura.start = atTime
+ if OvaleData:NeedNewSnapshot(auraId, spellId) then
aura.duration = duration
end
- aura.ending = aura.start + aura.duration
- aura.gain = aura.start
- OvaleFuture:UpdateSnapshotFromSpellcast(aura, spellcast)
+ end
+ aura.ending = aura.start + aura.duration
+ aura.gain = atTime
+ Ovale:Logf("Aura %d now ending at %f", auraId, aura.ending)
+ elseif stacks == 0 or stacks < 0 then
+ if stacks == 0 then
+ aura.stacks = 0
+ else -- if stacks < 0 then
+ aura.stacks = aura.stacks + stacks
+ if aura.stacks < 0 then
+ aura.stacks = 0
+ end
+ Ovale:Logf("Aura %d loses %d stack(s) to %d because of spell %d.", auraId, -1 * stacks, aura.stacks, spellId)
+ end
+ -- An existing aura is losing stacks, so inherit start, duration, ending and gain information.
+ if aura.stacks == 0 then
+ Ovale:Logf("Aura %d is completely removed.", auraId)
+ -- The aura is completely removed, so set ending to the time that the aura is removed.
+ aura.ending = atTime
end
end
+ else
+ -- Aura is not on the target.
+ if stacks > 0 then
+ -- Spellcast causes a new aura.
+ Ovale:Logf("New aura %d at %f on %s", auraId, atTime, guid)
+ -- Add an aura in the simulator and copy the existing aura information over.
+ local aura = state:AddAuraToGUID(guid, auraId, self_guid, filter, 0, math.huge)
+ -- Information that needs to be set below: stacks, start, ending, duration, gain.
+ aura.stacks = stacks
+ aura.start = atTime
+ -- Set start and duration for aura.
+ if si and si.tick then
+ -- "tick" is set explicitly in SpellInfo, so this is a known periodic aura.
+ aura.duration = dotDuration
+ aura.tick = tick
+ aura.ticksSeen = 0
+ else
+ aura.duration = duration
+ end
+ aura.ending = aura.start + aura.duration
+ aura.gain = aura.start
+ OvaleFuture:UpdateSnapshotFromSpellcast(aura, spellcast)
+ end
end
end
end
+end
- statePrototype.GetAuraByGUID = function(state, guid, auraId, filter, mine)
- local auraFound
- if OvaleData.buffSpellList[auraId] then
- for id in pairs(OvaleData.buffSpellList[auraId]) do
- local aura = GetStateAuraOnGUID(state, guid, id, filter, mine)
- if aura and (not auraFound or auraFound.ending < aura.ending) then
- auraFound = aura
- end
+statePrototype.GetAuraByGUID = function(state, guid, auraId, filter, mine)
+ local auraFound
+ if OvaleData.buffSpellList[auraId] then
+ for id in pairs(OvaleData.buffSpellList[auraId]) do
+ local aura = GetStateAuraOnGUID(state, guid, id, filter, mine)
+ if aura and (not auraFound or auraFound.ending < aura.ending) then
+ auraFound = aura
end
- else
- auraFound = GetStateAuraOnGUID(state, guid, auraId, filter, mine)
end
- return auraFound
+ else
+ auraFound = GetStateAuraOnGUID(state, guid, auraId, filter, mine)
end
+ return auraFound
+end
- statePrototype.GetAura = function(state, unitId, auraId, filter, mine)
- local guid = OvaleGUID:GetGUID(unitId)
- return state:GetAuraByGUID(guid, auraId, filter, mine)
- end
+statePrototype.GetAura = function(state, unitId, auraId, filter, mine)
+ local guid = OvaleGUID:GetGUID(unitId)
+ return state:GetAuraByGUID(guid, auraId, filter, mine)
+end
- -- Add a new aura to the unit specified by GUID.
- statePrototype.AddAuraToGUID = function(state, guid, auraId, casterGUID, filter, start, ending, snapshot)
- local aura = self_pool:Get()
- aura.state = true
- aura.serial = state.serial
- aura.filter = filter
- aura.mine = mine
- aura.start = start or 0
- aura.ending = ending or math.huge
- aura.duration = ending - start
- aura.gain = aura.start
- aura.stacks = 1
- if snapshot then
- aura.snapshot = OvalePaperDoll:GetSnapshot(snapshot)
- end
- PutAura(state.aura, guid, auraId, casterGUID, aura)
- return aura
- end
-
- do
- -- The total count of the matched aura.
- local count
- -- The start and ending times of the first aura to expire that will change the total count.
- local startChangeCount, endingChangeCount
- -- The time interval over which count > 0.
- local startFirst, endingLast
-
- local function CountMatchingActiveAura(aura)
- count = count + 1
- if aura.ending < endingChangeCount then
- startChangeCount, endingChangeCount = aura.start, aura.ending
- end
- if aura.start < startFirst then
- startFirst = aura.start
- end
- if aura.ending > endingLast then
- endingLast = aura.ending
- end
+-- Add a new aura to the unit specified by GUID.
+statePrototype.AddAuraToGUID = function(state, guid, auraId, casterGUID, filter, start, ending, snapshot)
+ local aura = self_pool:Get()
+ aura.state = true
+ aura.serial = state.serial
+ aura.filter = filter
+ aura.mine = mine
+ aura.start = start or 0
+ aura.ending = ending or math.huge
+ aura.duration = ending - start
+ aura.gain = aura.start
+ aura.stacks = 1
+ if snapshot then
+ aura.snapshot = OvalePaperDoll:GetSnapshot(snapshot)
+ end
+ PutAura(state.aura, guid, auraId, casterGUID, aura)
+ return aura
+end
+
+do
+ -- The total count of the matched aura.
+ local count
+ -- The start and ending times of the first aura to expire that will change the total count.
+ local startChangeCount, endingChangeCount
+ -- The time interval over which count > 0.
+ local startFirst, endingLast
+
+ local function CountMatchingActiveAura(aura)
+ count = count + 1
+ if aura.ending < endingChangeCount then
+ startChangeCount, endingChangeCount = aura.start, aura.ending
+ end
+ if aura.start < startFirst then
+ startFirst = aura.start
+ end
+ if aura.ending > endingLast then
+ endingLast = aura.ending
end
+ end
+
+ --[[
+ Return the total count of the given aura across all units, the start/end times of
+ the first aura to expire that will change the total count, and the time interval
+ over which the count is more than 0.
+ --]]
+ statePrototype.AuraCount = function(state, auraId, filter, mine)
+ -- Initialize.
+ count = 0
+ startChangeCount, endingChangeCount = math.huge, math.huge
+ startFirst, endingLast = math.huge, 0
+
+ local now = state.currentTime
- --[[
- Return the total count of the given aura across all units, the start/end times of
- the first aura to expire that will change the total count, and the time interval
- over which the count is more than 0.
- --]]
- statePrototype.AuraCount = function(state, auraId, filter, mine)
- -- Initialize.
- count = 0
- startChangeCount, endingChangeCount = math.huge, math.huge
- startFirst, endingLast = math.huge, 0
-
- local now = state.currentTime
-
- -- Loop through auras not kept in the simulator that match the criteria.
- for guid, auraTable in pairs(self_aura) do
- if auraTable[auraId] then
- if mine then
- local aura = GetStateAura(state, guid, auraId, self_guid)
+ -- Loop through auras not kept in the simulator that match the criteria.
+ for guid, auraTable in pairs(self_aura) do
+ if auraTable[auraId] then
+ if mine then
+ local aura = GetStateAura(state, guid, auraId, self_guid)
+ if state:IsActiveAura(aura, now) and aura.filter == filter and not aura.state then
+ CountMatchingActiveAura(aura)
+ end
+ else
+ for casterGUID in pairs(auraTable[auraId]) do
+ local aura = GetStateAura(state, guid, auraId, casterGUID)
if state:IsActiveAura(aura, now) and aura.filter == filter and not aura.state then
CountMatchingActiveAura(aura)
end
- else
- for casterGUID in pairs(auraTable[auraId]) do
- local aura = GetStateAura(state, guid, auraId, casterGUID)
- if state:IsActiveAura(aura, now) and aura.filter == filter and not aura.state then
- CountMatchingActiveAura(aura)
- end
- end
end
end
end
- -- Loop through auras in the simulator that match the criteria.
- for guid, auraTable in pairs(state.aura) do
- if auraTable[auraId] then
- if mine then
- local aura = auraTable[auraId][self_guid]
- if aura then
- if state:IsActiveAura(aura, now) and aura.filter == filter then
- CountMatchingActiveAura(aura)
- end
+ end
+ -- Loop through auras in the simulator that match the criteria.
+ for guid, auraTable in pairs(state.aura) do
+ if auraTable[auraId] then
+ if mine then
+ local aura = auraTable[auraId][self_guid]
+ if aura then
+ if state:IsActiveAura(aura, now) and aura.filter == filter then
+ CountMatchingActiveAura(aura)
end
- else
- for casterGUID, aura in pairs(auraTable[auraId]) do
- if state:IsActiveAura(aura, now) and aura.filter == filter then
- CountMatchingActiveAura(aura)
- end
+ end
+ else
+ for casterGUID, aura in pairs(auraTable[auraId]) do
+ if state:IsActiveAura(aura, now) and aura.filter == filter then
+ CountMatchingActiveAura(aura)
end
end
end
end
-
- return count, startChangeCount, endingChangeCount, startFirst, endingLast
end
+
+ return count, startChangeCount, endingChangeCount, startFirst, endingLast
end
end
--</state-methods>
diff --git a/OvaleComboPoints.lua b/OvaleComboPoints.lua
index 4faae32..28ffc21 100644
--- a/OvaleComboPoints.lua
+++ b/OvaleComboPoints.lua
@@ -112,11 +112,17 @@ end
--]]----------------------------------------------------------------------------
--<public-static-properties>
-OvaleComboPoints.statePrototype = {
- combo = nil,
-}
+OvaleComboPoints.statePrototype = {}
--</public-static-properties>
+--<private-static-properties>
+local statePrototype = OvaleComboPoints.statePrototype
+--</private-static-properties>
+
+--<state-properties>
+statePrototype.combo = nil
+--</state-properties>
+
--<public-static-methods>
-- Initialize the state.
function OvaleComboPoints:InitializeState(state)
diff --git a/OvaleCooldown.lua b/OvaleCooldown.lua
index 412fa51..dfb37f3 100644
--- a/OvaleCooldown.lua
+++ b/OvaleCooldown.lua
@@ -92,11 +92,17 @@ end
--]]----------------------------------------------------------------------------
--<public-static-properties>
-OvaleCooldown.statePrototype = {
- cd = nil,
-}
+OvaleCooldown.statePrototype = {}
--</public-static-properties>
+--<private-static-properties>
+local statePrototype = OvaleCooldown.statePrototype
+--</private-static-properties>
+
+--<state-properties>
+statePrototype.cd = nil
+--</state-properties>
+
--<public-static-methods>
-- Initialize the state.
function OvaleCooldown:InitializeState(state)
@@ -174,49 +180,45 @@ end
--</public-static-methods>
--<state-methods>
-do
- local statePrototype = OvaleCooldown.statePrototype
-
- -- Return the table holding the simulator's cooldown information for the given spell.
- statePrototype.GetCD = function(state, spellId)
- if spellId then
- local si = OvaleData.spellInfo[spellId]
- if si and si.cd then
- local cdname = si.sharedcd and si.sharedcd or spellId
- if not state.cd[cdname] then
- state.cd[cdname] = {}
- end
- return state.cd[cdname]
+-- Return the table holding the simulator's cooldown information for the given spell.
+statePrototype.GetCD = function(state, spellId)
+ if spellId then
+ local si = OvaleData.spellInfo[spellId]
+ if si and si.cd then
+ local cdname = si.sharedcd and si.sharedcd or spellId
+ if not state.cd[cdname] then
+ state.cd[cdname] = {}
end
+ return state.cd[cdname]
end
- return nil
end
+ return nil
+end
- -- Return the cooldown for the spell in the simulator.
- statePrototype.GetSpellCooldown = function(state, spellId)
- local start, duration, enable
- local cd = state:GetCD(spellId)
- if cd and cd.start then
- start = cd.start
- duration = cd.duration
- enable = cd.enable
- else
- start, duration, enable = OvaleData:GetSpellCooldown(spellId)
- end
- return start, duration, enable
+-- Return the cooldown for the spell in the simulator.
+statePrototype.GetSpellCooldown = function(state, spellId)
+ local start, duration, enable
+ local cd = state:GetCD(spellId)
+ if cd and cd.start then
+ start = cd.start
+ duration = cd.duration
+ enable = cd.enable
+ else
+ start, duration, enable = OvaleData:GetSpellCooldown(spellId)
end
+ return start, duration, enable
+end
- -- Force the cooldown of a spell to reset at the specified time.
- statePrototype.ResetSpellCooldown = function(state, spellId, atTime)
- if atTime >= state.currentTime then
- local start, duration, enable = state:GetSpellCooldown(spellId)
- if start + duration > state.currentTime then
- local cd = state:GetCD(spellId)
- if cd then
- cd.start = state.currentTime
- cd.duration = atTime - state.currentTime
- cd.enable = 1
- end
+-- Force the cooldown of a spell to reset at the specified time.
+statePrototype.ResetSpellCooldown = function(state, spellId, atTime)
+ if atTime >= state.currentTime then
+ local start, duration, enable = state:GetSpellCooldown(spellId)
+ if start + duration > state.currentTime then
+ local cd = state:GetCD(spellId)
+ if cd then
+ cd.start = state.currentTime
+ cd.duration = atTime - state.currentTime
+ cd.enable = 1
end
end
end
diff --git a/OvaleData.lua b/OvaleData.lua
index 07d5e2c..20b628b 100644
--- a/OvaleData.lua
+++ b/OvaleData.lua
@@ -358,55 +358,55 @@ end
OvaleData.statePrototype = {}
--</public-static-properties>
---<state-methods>
-do
- local statePrototype = OvaleData.statePrototype
+--<private-static-properties>
+local statePrototype = OvaleData.statePrototype
+--</private-static-properties>
- statePrototype.GetTickLength = function(state, auraId, snapshot)
- local tick = 3
- local si = OvaleData.spellInfo[auraId]
- if si then
- tick = si.tick or tick
- local hasteMultiplier = 1
- if si.haste then
- if si.haste == "spell" then
- hasteMultiplier = state:GetSpellHasteMultiplier(snapshot)
- elseif si.haste == "melee" then
- hasteMultiplier = state:GetMeleeHasteMultiplier(snapshot)
- end
- tick = tick / hasteMultiplier
+--<state-methods>
+statePrototype.GetTickLength = function(state, auraId, snapshot)
+ local tick = 3
+ local si = OvaleData.spellInfo[auraId]
+ if si then
+ tick = si.tick or tick
+ local hasteMultiplier = 1
+ if si.haste then
+ if si.haste == "spell" then
+ hasteMultiplier = state:GetSpellHasteMultiplier(snapshot)
+ elseif si.haste == "melee" then
+ hasteMultiplier = state:GetMeleeHasteMultiplier(snapshot)
end
+ tick = tick / hasteMultiplier
end
- return tick
end
+ return tick
+end
- -- Returns the raw duration, DoT duration, tick length, and number of ticks of an aura.
- statePrototype.GetDuration = function(state, auraId, spellcast)
- local snapshot, combo, holy
- if spellcast then
- snapshot, combo, holy = spellcast.snapshot, spellcast.combo, spellcast.holy
- else
- snapshot, combo, holy = state.snapshot, state.combo, state.holy
- end
+-- Returns the raw duration, DoT duration, tick length, and number of ticks of an aura.
+statePrototype.GetDuration = function(state, auraId, spellcast)
+ local snapshot, combo, holy
+ if spellcast then
+ snapshot, combo, holy = spellcast.snapshot, spellcast.combo, spellcast.holy
+ else
+ snapshot, combo, holy = state.snapshot, state.combo, state.holy
+ end
- local duration = math.huge
- local tick = state:GetTickLength(auraId, snapshot)
+ local duration = math.huge
+ local tick = state:GetTickLength(auraId, snapshot)
- local si = OvaleData.spellInfo[auraId]
- if si and si.duration then
- duration = si.duration
- if si.adddurationcp and combo then
- duration = duration + si.adddurationcp * combo
- end
- if si.adddurationholy and holy then
- duration = duration + si.adddurationholy * (holy - 1)
- end
+ local si = OvaleData.spellInfo[auraId]
+ if si and si.duration then
+ duration = si.duration
+ if si.adddurationcp and combo then
+ duration = duration + si.adddurationcp * combo
+ end
+ if si.adddurationholy and holy then
+ duration = duration + si.adddurationholy * (holy - 1)
end
+ end
- local numTicks = floor(duration/tick + 0.5)
- local dotDuration = tick * numTicks
+ local numTicks = floor(duration/tick + 0.5)
+ local dotDuration = tick * numTicks
- return duration, dotDuration, tick, numTicks
- end
+ return duration, dotDuration, tick, numTicks
end
--</state-methods>
diff --git a/OvaleEclipse.lua b/OvaleEclipse.lua
index 94a5b84..82c68d2 100644
--- a/OvaleEclipse.lua
+++ b/OvaleEclipse.lua
@@ -129,11 +129,18 @@ end
--]]----------------------------------------------------------------------------
--<public-static-properties>
-OvaleEclipse.statePrototype = {
- eclipseDirection = nil,
-}
+OvaleEclipse.statePrototype = {}
--</public-static-properties>
+--<private-static-properties>
+local statePrototype = OvaleEclipse.statePrototype
+--</private-static-properties>
+
+--<state-properties>
+-- Direction in which the Eclipse bar is moving.
+statePrototype.eclipseDirection = nil
+--</state-properties>
+
--<public-static-methods>
-- Initialize the state.
function OvaleEclipse:InitializeState(state)
diff --git a/OvaleFuture.lua b/OvaleFuture.lua
index 6012328..1baa087 100644
--- a/OvaleFuture.lua
+++ b/OvaleFuture.lua
@@ -581,11 +581,18 @@ end
--]]----------------------------------------------------------------------------
--<public-static-properties>
-OvaleFuture.statePrototype = {
- counter = nil,
-}
+OvaleFuture.statePrototype = {}
--</public-static-properties>
+--<private-static-properties>
+local statePrototype = OvaleFuture.statePrototype
+--</private-static-properties>
+
+--<state-properties>
+-- counter[name] = count
+statePrototype.counter = nil
+--</state-properties>
+
--<public-static-methods>
-- Initialize the state.
function OvaleFuture:InitializeState(state)
@@ -625,15 +632,11 @@ end
--</public-static-methods>
--<state-methods>
-do
- local statePrototype = OvaleFuture.statePrototype
-
- statePrototype.GetCounterValue = function(state, id)
- return state.counter[id] or 0
- end
+statePrototype.GetCounterValue = function(state, id)
+ return state.counter[id] or 0
+end
- statePrototype.GetDamageMultiplier = function(state, spellId)
- return GetDamageMultiplier(spellId, state)
- end
-end
+statePrototype.GetDamageMultiplier = function(state, spellId)
+ return GetDamageMultiplier(spellId, state)
+end
--</state-methods>
diff --git a/OvalePaperDoll.lua b/OvalePaperDoll.lua
index 5aa9710..b834ded 100644
--- a/OvalePaperDoll.lua
+++ b/OvalePaperDoll.lua
@@ -482,13 +482,22 @@ end
--]]----------------------------------------------------------------------------
--<public-static-properties>
-OvalePaperDoll.statePrototype = {
- level = nil,
- specialization = nil,
- snapshot = nil,
-}
+OvalePaperDoll.statePrototype = {}
--</public-static-properties>
+--<private-static-properties>
+local statePrototype = OvalePaperDoll.statePrototype
+--</private-static-properties>
+
+--<state-properties>
+-- Player's level.
+statePrototype.level = nil
+-- Player's chosen specialization/mastery.
+statePrototype.specialization = nil
+-- Player's current snapshot.
+statePrototype.snapshot = nil
+--</state-properties>
+
--<public-static-methods>
-- Initialize the state.
function OvalePaperDoll:InitializeState(state)
@@ -516,27 +525,23 @@ end
--</public-static-methods>
--<state-methods>
-do
- local statePrototype = OvalePaperDoll.statePrototype
-
- statePrototype.GetMasteryMultiplier = function(state, snapshot)
- snapshot = snapshot or state.snapshot
- return 1 + snapshot.masteryEffect / 100
- end
+statePrototype.GetMasteryMultiplier = function(state, snapshot)
+ snapshot = snapshot or state.snapshot
+ return 1 + snapshot.masteryEffect / 100
+end
- statePrototype.GetMeleeHasteMultiplier = function(state, snapshot)
- snapshot = snapshot or state.snapshot
- return 1 + snapshot.meleeHaste / 100
- end
+statePrototype.GetMeleeHasteMultiplier = function(state, snapshot)
+ snapshot = snapshot or state.snapshot
+ return 1 + snapshot.meleeHaste / 100
+end
- statePrototype.GetRangedHasteMultiplier = function(state, snapshot)
- snapshot = snapshot or state.snapshot
- return 1 + snapshot.rangedHaste / 100
- end
+statePrototype.GetRangedHasteMultiplier = function(state, snapshot)
+ snapshot = snapshot or state.snapshot
+ return 1 + snapshot.rangedHaste / 100
+end
- statePrototype.GetSpellHasteMultiplier = function(state, snapshot)
- snapshot = snapshot or state.snapshot
- return 1 + snapshot.spellHaste / 100
- end
+statePrototype.GetSpellHasteMultiplier = function(state, snapshot)
+ snapshot = snapshot or state.snapshot
+ return 1 + snapshot.spellHaste / 100
end
--</state-methods>
diff --git a/OvalePower.lua b/OvalePower.lua
index c9dfca5..0810177 100644
--- a/OvalePower.lua
+++ b/OvalePower.lua
@@ -210,11 +210,36 @@ end
--]]----------------------------------------------------------------------------
--<public-static-properties>
-OvalePower.statePrototype = {
- powerRate = nil,
-}
+OvalePower.statePrototype = {}
--</public-static-properties>
+--<private-static-properties>
+local statePrototype = OvalePower.statePrototype
+--</private-static-properties>
+
+--<state-properties>
+--[[
+ This block is here for compiler.pl to know that these properties are added to the state machine.
+
+ statePrototype.alternate = nil
+ statePrototype.burningembers = nil
+ statePrototype.chi = nil
+ statePrototype.demonicfury = nil
+ statePrototype.eclipse = nil
+ statePrototype.energy = nil
+ statePrototype.focus = nil
+ statePrototype.holy = nil
+ statePrototype.mana = nil
+ statePrototype.rage = nil
+ statePrototype.runicpower = nil
+ statePrototype.shadoworbs = nil
+ statePrototype.shards = nil
+--]]
+
+-- powerRate[powerType] = regen rate
+statePrototype.powerRate = nil
+--</state-properties>
+
--<public-static-methods>
-- Initialize the state.
function OvalePower:InitializeState(state)
@@ -317,14 +342,10 @@ end
--</public-static-methods>
--<state-methods>
-do
- local statePrototype = OvalePower.statePrototype
-
- -- Print out the levels of each power type in the current state.
- statePrototype.DebugPower = function(state)
- for powerType in pairs(OvalePower.POWER_INFO) do
- Ovale:FormatPrint("%s = %d", powerType, state[powerType])
- end
+-- Print out the levels of each power type in the current state.
+statePrototype.DebugPower = function(state)
+ for powerType in pairs(OvalePower.POWER_INFO) do
+ Ovale:FormatPrint("%s = %d", powerType, state[powerType])
end
end
---</state-methods>
\ No newline at end of file
+--</state-methods>
diff --git a/OvaleRunes.lua b/OvaleRunes.lua
index aa37d6d..f427aa8 100644
--- a/OvaleRunes.lua
+++ b/OvaleRunes.lua
@@ -179,11 +179,18 @@ end
--]]----------------------------------------------------------------------------
--<public-static-properties>
-OvaleRunes.statePrototype = {
- rune = nil, -- indexed by slot (1 through 6)
-}
+OvaleRunes.statePrototype = {}
--</public-static-properties>
+--<private-static-properties>
+local statePrototype = OvaleRunes.statePrototype
+--</private-static-properties>
+
+--<state-properties>
+-- indexed by slot (1 through 6)
+statePrototype.rune = nil
+--</state-properties>
+
--<public-static-methods>
-- Initialize the state.
function OvaleRunes:InitializeState(state)
@@ -230,124 +237,109 @@ end
--</public-static-methods>
--<state-methods>
-do
- local statePrototype = OvaleRunes.statePrototype
-
- statePrototype.DebugRunes = function(state)
- local now = state.currentTime
- for slot = 1, 6 do
- local rune = self.rune[slot]
- if rune.active then
- Ovale:FormatPrint("rune[%d] (%s) is active.", slot, RUNE_NAME[rune.type])
- else
- Ovale:FormatPrint("rune[%d] (%s) comes off cooldown in %f seconds.", slot, RUNE_NAME[rune.type], rune.endCooldown - now)
- end
+statePrototype.DebugRunes = function(state)
+ local now = state.currentTime
+ for slot = 1, 6 do
+ local rune = self.rune[slot]
+ if rune.active then
+ Ovale:FormatPrint("rune[%d] (%s) is active.", slot, RUNE_NAME[rune.type])
+ else
+ Ovale:FormatPrint("rune[%d] (%s) comes off cooldown in %f seconds.", slot, RUNE_NAME[rune.type], rune.endCooldown - now)
end
end
+end
- -- Consume a rune of the given type. Assume that the required runes are available.
- statePrototype.ConsumeRune = function(state, atTime, name, snapshot)
- --[[
- Find a usable rune, preferring a regular rune of that rune type over death
- runes of that rune type over death runes of any rune type.
- --]]
- local consumedRune
- local runeType = RUNE_TYPE[name]
- if runeType ~= DEATH_RUNE then
- -- Search for an active regular rune of the given rune type.
- for _, slot in ipairs(RUNE_SLOTS[runeType]) do
- local rune = state.rune[slot]
- if rune.type == runeType and rune.active then
- consumedRune = rune
- break
- end
- end
- if not consumedRune then
- -- Search for an active death rune of the given rune type.
- for _, slot in ipairs(RUNE_SLOTS[runeType]) do
- if rune.type == DEATH_RUNE and rune.active then
- consumedRune = rune
- break
- end
- end
+-- Consume a rune of the given type. Assume that the required runes are available.
+statePrototype.ConsumeRune = function(state, atTime, name, snapshot)
+ --[[
+ Find a usable rune, preferring a regular rune of that rune type over death
+ runes of that rune type over death runes of any rune type.
+ --]]
+ local consumedRune
+ local runeType = RUNE_TYPE[name]
+ if runeType ~= DEATH_RUNE then
+ -- Search for an active regular rune of the given rune type.
+ for _, slot in ipairs(RUNE_SLOTS[runeType]) do
+ local rune = state.rune[slot]
+ if rune.type == runeType and rune.active then
+ consumedRune = rune
+ break
end
end
- -- No runes of the right type are active, so look for any active death rune.
if not consumedRune then
- for _, slot in ipairs(DEATH_RUNE_PRIORITY) do
- local rune = state.rune[slot]
+ -- Search for an active death rune of the given rune type.
+ for _, slot in ipairs(RUNE_SLOTS[runeType]) do
if rune.type == DEATH_RUNE and rune.active then
consumedRune = rune
break
end
end
end
- if consumedRune then
- -- Put that rune on cooldown, starting when the other rune of that slot type comes off cooldown.
- local k = consumedRune.slotType
- local start = atTime
- for _, slot in ipairs(RUNE_SLOTS[consumedRune.slotType]) do
- local rune = state.rune[slot]
- if rune.endCooldown > start then
- start = rune.endCooldown
- end
- end
- local duration = 10 / state:GetSpellHasteMultiplier(snapshot)
- if OvaleStance:IsStance("death_knight_blood_presence") and OvaleSpellBook:IsKnownSpell(IMPROVED_BLOOD_PRESENCE) then
- -- Improved Blood Presence increases rune regeneration rate by 20%.
- duration = duration / 1.2
+ end
+ -- No runes of the right type are active, so look for any active death rune.
+ if not consumedRune then
+ for _, slot in ipairs(DEATH_RUNE_PRIORITY) do
+ local rune = state.rune[slot]
+ if rune.type == DEATH_RUNE and rune.active then
+ consumedRune = rune
+ break
end
- consumedRune.startCooldown = start
- consumedRune.endCooldown = start + duration
- consumedRune.active = false
-
- -- Each rune consumed generates 10 (12, if in Frost Presence) runic power.
- local runicpower = state.runicpower
- if OvaleStance:IsStance("death_knight_frost_presence") then
- runicpower = runicpower + 12
- else
- runicpower = runicpower + 10
+ end
+ end
+ if consumedRune then
+ -- Put that rune on cooldown, starting when the other rune of that slot type comes off cooldown.
+ local k = consumedRune.slotType
+ local start = atTime
+ for _, slot in ipairs(RUNE_SLOTS[consumedRune.slotType]) do
+ local rune = state.rune[slot]
+ if rune.endCooldown > start then
+ start = rune.endCooldown
end
- local maxi = OvalePower.maxPower.runicpower
- state.runicpower = (runicpower < maxi) and runicpower or maxi
+ end
+ local duration = 10 / state:GetSpellHasteMultiplier(snapshot)
+ if OvaleStance:IsStance("death_knight_blood_presence") and OvaleSpellBook:IsKnownSpell(IMPROVED_BLOOD_PRESENCE) then
+ -- Improved Blood Presence increases rune regeneration rate by 20%.
+ duration = duration / 1.2
+ end
+ consumedRune.startCooldown = start
+ consumedRune.endCooldown = start + duration
+ consumedRune.active = false
+
+ -- Each rune consumed generates 10 (12, if in Frost Presence) runic power.
+ local runicpower = state.runicpower
+ if OvaleStance:IsStance("death_knight_frost_presence") then
+ runicpower = runicpower + 12
else
- Ovale:Errorf("No %s rune available to consume!", RUNE_NAME[runeType])
+ runicpower = runicpower + 10
end
+ local maxi = OvalePower.maxPower.runicpower
+ state.runicpower = (runicpower < maxi) and runicpower or maxi
+ else
+ Ovale:Errorf("No %s rune available to consume!", RUNE_NAME[runeType])
end
+end
- statePrototype.RuneCount = function(state, name, death)
- local count = 0
- local startCooldown, endCooldown = math.huge, math.huge
- local runeType = RUNE_TYPE[name]
- if runeType ~= DEATH_RUNE then
- if deathCondition == "any" then
- -- Match runes of the given type or any death runes.
- for slot, rune in ipairs(state.rune) do
- if rune.type == runeType or rune.type == DEATH_RUNE then
- if rune.active then
- count = count + 1
- elseif rune.endCooldown < endCooldown then
- startCooldown, endCooldown = rune.startCooldown, rune.endCooldown
- end
- end
- end
- else
- -- Match only the runes of the given type.
- for _, slot in ipairs(RUNE_SLOTS[runeType]) do
- local rune = state.rune[slot]
- if not deathCondition or (deathCondition == "none" and rune.type ~= DEATH_RUNE) then
- if rune.active then
- count = count + 1
- elseif rune.endCooldown < endCooldown then
- startCooldown, endCooldown = rune.startCooldown, rune.endCooldown
- end
+statePrototype.RuneCount = function(state, name, death)
+ local count = 0
+ local startCooldown, endCooldown = math.huge, math.huge
+ local runeType = RUNE_TYPE[name]
+ if runeType ~= DEATH_RUNE then
+ if deathCondition == "any" then
+ -- Match runes of the given type or any death runes.
+ for slot, rune in ipairs(state.rune) do
+ if rune.type == runeType or rune.type == DEATH_RUNE then
+ if rune.active then
+ count = count + 1
+ elseif rune.endCooldown < endCooldown then
+ startCooldown, endCooldown = rune.startCooldown, rune.endCooldown
end
end
end
else
- -- Match any requested death runes.
- for slot, rune in ipairs(state.rune) do
- if rune.type == DEATH_RUNE then
+ -- Match only the runes of the given type.
+ for _, slot in ipairs(RUNE_SLOTS[runeType]) do
+ local rune = state.rune[slot]
+ if not deathCondition or (deathCondition == "none" and rune.type ~= DEATH_RUNE) then
if rune.active then
count = count + 1
elseif rune.endCooldown < endCooldown then
@@ -356,99 +348,110 @@ do
end
end
end
- return count, startCooldown, endCooldown
+ else
+ -- Match any requested death runes.
+ for slot, rune in ipairs(state.rune) do
+ if rune.type == DEATH_RUNE then
+ if rune.active then
+ count = count + 1
+ elseif rune.endCooldown < endCooldown then
+ startCooldown, endCooldown = rune.startCooldown, rune.endCooldown
+ end
+ end
+ end
end
+ return count, startCooldown, endCooldown
+end
- -- Returns the number of seconds before all of the required runes are available.
- statePrototype.GetRunesCooldown = nil
- do
- -- If the rune is active, then return the remaining active runes count requirement.
- -- Also return the time of the next rune becoming active.
- local function MatchRune(rune, count, endCooldown)
- if count > 0 then
- count = count - 1
- if rune.endCooldown > endCooldown then
- endCooldown = rune.endCooldown
- end
- else
- if rune.endCooldown < endCooldown then
- endCooldown = rune.endCooldown
- end
+-- Returns the number of seconds before all of the required runes are available.
+statePrototype.GetRunesCooldown = nil
+do
+ -- If the rune is active, then return the remaining active runes count requirement.
+ -- Also return the time of the next rune becoming active.
+ local function MatchRune(rune, count, endCooldown)
+ if count > 0 then
+ count = count - 1
+ if rune.endCooldown > endCooldown then
+ endCooldown = rune.endCooldown
+ end
+ else
+ if rune.endCooldown < endCooldown then
+ endCooldown = rune.endCooldown
end
- return count, endCooldown
end
+ return count, endCooldown
+ end
- -- The remaining count requirements, indexed by rune type.
- local runeCount = {}
- -- The latest time till a rune of that type is off cooldown, indexed by rune type.
- local runeEndCooldown = {}
-
- statePrototype.GetRunesCooldown = function(state, blood, unholy, frost, death, deathCondition)
- -- Initialize static variables.
- runeCount[BLOOD_RUNE] = blood or 0
- runeCount[UNHOLY_RUNE] = unholy or 0
- runeCount[FROST_RUNE] = frost or 0
- runeCount[DEATH_RUNE] = death or 0
- runeEndCooldown[BLOOD_RUNE] = 0
- runeEndCooldown[UNHOLY_RUNE] = 0
- runeEndCooldown[FROST_RUNE] = 0
- runeEndCooldown[DEATH_RUNE] = 0
-
- -- Use regular runes to meet the count requirements.
+ -- The remaining count requirements, indexed by rune type.
+ local runeCount = {}
+ -- The latest time till a rune of that type is off cooldown, indexed by rune type.
+ local runeEndCooldown = {}
+
+ statePrototype.GetRunesCooldown = function(state, blood, unholy, frost, death, deathCondition)
+ -- Initialize static variables.
+ runeCount[BLOOD_RUNE] = blood or 0
+ runeCount[UNHOLY_RUNE] = unholy or 0
+ runeCount[FROST_RUNE] = frost or 0
+ runeCount[DEATH_RUNE] = death or 0
+ runeEndCooldown[BLOOD_RUNE] = 0
+ runeEndCooldown[UNHOLY_RUNE] = 0
+ runeEndCooldown[FROST_RUNE] = 0
+ runeEndCooldown[DEATH_RUNE] = 0
+
+ -- Use regular runes to meet the count requirements.
+ for slot, rune in ipairs(state.rune) do
+ if rune.type ~= DEATH_RUNE then
+ local runeType = rune.type
+ local count, endCooldown = MatchRune(rune, runeCount[runeType], runeEndCooldown[runeType])
+ runeCount[runeType] = count
+ runeEndCooldown[runeType] = endCooldown
+ end
+ end
+ -- Use death runes of the matching rune type to meet the count requirements.
+ if deathCondition ~= "none" then
for slot, rune in ipairs(state.rune) do
- if rune.type ~= DEATH_RUNE then
- local runeType = rune.type
+ if rune.type == DEATH_RUNE then
+ local runeType = rune.slotType
local count, endCooldown = MatchRune(rune, runeCount[runeType], runeEndCooldown[runeType])
runeCount[runeType] = count
runeEndCooldown[runeType] = endCooldown
end
end
- -- Use death runes of the matching rune type to meet the count requirements.
- if deathCondition ~= "none" then
- for slot, rune in ipairs(state.rune) do
- if rune.type == DEATH_RUNE then
- local runeType = rune.slotType
- local count, endCooldown = MatchRune(rune, runeCount[runeType], runeEndCooldown[runeType])
- runeCount[runeType] = count
- runeEndCooldown[runeType] = endCooldown
- end
- end
- end
+ end
- -- Remaining rune requirements that have not yet been met.
- local remainingCount = 0
- for runeType = 1, 4 do
- remainingCount = remainingCount + runeCount[runeType]
- end
+ -- Remaining rune requirements that have not yet been met.
+ local remainingCount = 0
+ for runeType = 1, 4 do
+ remainingCount = remainingCount + runeCount[runeType]
+ end
- -- Use death runes of any type to meet any remaining count requirements.
- if deathCondition == "any" then
- for _, slot in ipairs(DEATH_RUNE_PRIORITY) do
- local rune = state.rune[slot]
- local runeType = DEATH_RUNE
- local count, endCooldown = MatchRune(rune, remainingCount, runeEndCooldown[runeType])
- remainingCount = count
- runeEndCooldown[runeType] = endCooldown
- end
+ -- Use death runes of any type to meet any remaining count requirements.
+ if deathCondition == "any" then
+ for _, slot in ipairs(DEATH_RUNE_PRIORITY) do
+ local rune = state.rune[slot]
+ local runeType = DEATH_RUNE
+ local count, endCooldown = MatchRune(rune, remainingCount, runeEndCooldown[runeType])
+ remainingCount = count
+ runeEndCooldown[runeType] = endCooldown
end
+ end
- -- This shouldn't happen because it means the rune requirements will never be met.
- if remainingCount > 0 then
- Ovale:Logf("Impossible rune count requirements: blood=%d, unholy=%d, frost=%d, death=%d", blood, unholy, frost, death)
- return math.huge
- end
+ -- This shouldn't happen because it means the rune requirements will never be met.
+ if remainingCount > 0 then
+ Ovale:Logf("Impossible rune count requirements: blood=%d, unholy=%d, frost=%d, death=%d", blood, unholy, frost, death)
+ return math.huge
+ end
- local maxEndCooldown = 0
- for runeType = 1, 4 do
- if runeEndCooldown[runeType] > maxEndCooldown then
- maxEndCooldown = runeEndCooldown[runeType]
- end
+ local maxEndCooldown = 0
+ for runeType = 1, 4 do
+ if runeEndCooldown[runeType] > maxEndCooldown then
+ maxEndCooldown = runeEndCooldown[runeType]
end
- if maxEndCooldown > 0 then
- return maxEndCooldown - state.currentTime
- end
- return 0
end
+ if maxEndCooldown > 0 then
+ return maxEndCooldown - state.currentTime
+ end
+ return 0
end
end
--</state-methods>
diff --git a/OvaleState.lua b/OvaleState.lua
index e162cce..a074bc9 100644
--- a/OvaleState.lua
+++ b/OvaleState.lua
@@ -175,26 +175,32 @@ end
--]]----------------------------------------------------------------------------
--<public-static-properties>
-OvaleState.statePrototype = {
- -- Whether the state of the simulator has been initialized.
- isInitialized = nil,
- -- The current time in the simulator.
- currentTime = nil,
- -- The spell being cast in the simulator.
- currentSpellId = nil,
- -- The starting cast time of the spell being cast in the simulator.
- startCast = nil,
- -- The ending cast time of the spell being cast in the simulator.
- endCast = nil,
- -- The time at which the next GCD spell can be cast in the simulator.
- nextCast = nil,
- -- Whether the player is channeling a spell in the simulator at the current time.
- isChanneling = nil,
- -- The previous spell cast in the simulator.
- lastSpellId = nil,
-}
+OvaleState.statePrototype = {}
--</public-static-properties>
+--<private-static-properties>
+local statePrototype = OvaleState.statePrototype
+--</private-static-properties>
+
+--<state-properties>
+-- Whether the state of the simulator has been initialized.
+statePrototype.isInitialized = nil
+-- The current time in the simulator.
+statePrototype.currentTime = nil
+-- The spell being cast in the simulator.
+statePrototype.currentSpellId = nil
+-- The starting cast time of the spell being cast in the simulator.
+statePrototype.startCast = nil
+-- The ending cast time of the spell being cast in the simulator.
+statePrototype.endCast = nil
+-- The time at which the next GCD spell can be cast in the simulator.
+statePrototype.nextCast = nil
+-- Whether the player is channeling a spell in the simulator at the current time.
+statePrototype.isChanneling = nil
+-- The previous spell cast in the simulator.
+statePrototype.lastSpellId = nil
+--</state-properties>
+
--<public-static-methods>
-- Initialize the state.
function OvaleState:InitializeState(state)
diff --git a/compiler.pl b/compiler.pl
index cc1260a..07b03ce 100644
--- a/compiler.pl
+++ b/compiler.pl
@@ -17,6 +17,9 @@
--<public-properties>
--</public-properties>
+--<state-properties>
+--</state-properties>
+
--<state-methods>
--</state-methods>
=cut
@@ -257,6 +260,15 @@ sub ParseDirectory
}
}
+ if ($content =~ m/<state-properties>(.*)<\/state-properties>/s)
+ {
+ my $p = $1;
+ while ($p =~ m/statePrototype\.(\w+)/g)
+ {
+ $smp{$1} = true;
+ }
+ }
+
if ($content =~ m/<state-methods>(.*)<\/state-methods>/s)
{
my $p = $1;
@@ -282,6 +294,14 @@ sub ParseDirectory
}
}
+ while ($content =~ m/\bstate\.(\w+)/g)
+ {
+ unless ($smp{$1})
+ {
+ $smp{$1} = $class;
+ }
+ }
+
while ($content =~ m/\bstate\:(\w+)/g)
{
unless ($smm{$1})
@@ -327,7 +347,7 @@ for my $class (keys %sm)
{
unless ($sm{$class}{$method} eq true)
{
- print "public static $class:$method $sm{$class}{$method}\n";
+ print "public static $class:$method used in $sm{$class}{$method}\n";
}
}
}
@@ -338,7 +358,7 @@ for my $class (keys %m)
{
unless ($m{$class}{$method} eq true)
{
- print "public $class:$method $m{$class}{$method}\n";
+ print "public $class:$method used in $m{$class}{$method}\n";
}
}
}
@@ -349,15 +369,23 @@ for my $class (keys %sp)
{
unless ($sp{$class}{$prop} eq true)
{
- print "public static $class.$prop $sp{$class}{$prop}\n";
+ print "public static $class.$prop used in $sp{$class}{$prop}\n";
}
}
}
+for my $prop (keys %smp)
+{
+ unless ($smp{$prop} eq true)
+ {
+ print "state machine property state.$prop used in $smp{$prop}\n";
+ }
+}
+
for my $method (keys %smm)
{
unless ($smm{$method} eq true)
{
- print "state matchine state:$method $smm{$method}\n";
+ print "state machine method state:$method used in $smm{$method}\n";
}
}