Johnny C. Lam [11-27-13 - 14:04]
diff --git a/OvaleAura.lua b/OvaleAura.lua
index 4de92c6..abff51c 100644
--- a/OvaleAura.lua
+++ b/OvaleAura.lua
@@ -823,5 +823,81 @@ do
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
+
+ -- 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
+ 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
+ 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
+ end
+
+ return count, startChangeCount, endingChangeCount, startFirst, endingLast
+ end
+ end
end
--</state-methods>
diff --git a/conditions/BuffCount.lua b/conditions/BuffCount.lua
new file mode 100644
index 0000000..95c871b
--- /dev/null
+++ b/conditions/BuffCount.lua
@@ -0,0 +1,51 @@
+--[[--------------------------------------------------------------------
+ Ovale Spell Priority
+ Copyright (C) 2013 Johnny C. Lam
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License in the LICENSE
+ file accompanying this program.
+--]]--------------------------------------------------------------------
+
+local _, Ovale = ...
+
+do
+ local OvaleCondition = Ovale.OvaleCondition
+ local OvaleState = Ovale.OvaleState
+
+ local Compare = OvaleCondition.Compare
+ local ParseCondition = OvaleCondition.ParseCondition
+ local TestValue = OvaleCondition.TestValue
+ local state = OvaleState.state
+
+ --- Get the total count of the given aura across all targets.
+ -- @name BuffCount
+ -- @paramsig number or boolean
+ -- @param id The spell ID of the aura or the name of a spell list.
+ -- @param operator Optional. Comparison operator: less, atMost, equal, atLeast, more.
+ -- @param number Optional. The number to compare against.
+ -- @param any Optional. Sets by whom the aura was applied. If the aura can be applied by anyone, then set any=1.
+ -- Defaults to any=0.
+ -- Valid values: 0, 1.
+ -- @return The total aura count.
+ -- @return A boolean value for the result of the comparison.
+ -- @see DebuffCount
+
+ local function BuffCount(condition)
+ local auraId, comparator, limit = condition[1], condition[2], condition[3]
+ local _, filter, mine = ParseCondition(condition)
+
+ local count, startChangeCount, endingChangeCount, startFirst, endingLast = state:AuraCount(auraId, filter, mine)
+ Ovale:Logf("BuffCount(%d) is %d, %d, %d, %d, %d", auraId, count, startChangeCount, endingChangeCount, startFirst, endingLast)
+ if count > 0 then
+ local origin = startChangeCount
+ local rate = -1 / (endingChangeCount - startChangeCount)
+ local start, ending = startFirst, endingLast
+ return TestValue(start, ending, count, origin, rate, comparator, limit)
+ end
+ return Compare(count, comparator, limit)
+ end
+
+ OvaleCondition:RegisterCondition("buffcount", false, BuffCount)
+ OvaleCondition:RegisterCondition("debuffcount", false, BuffCount)
+end
diff --git a/conditions/conditions.xml b/conditions/conditions.xml
index 27362f7..4c086df 100644
--- a/conditions/conditions.xml
+++ b/conditions/conditions.xml
@@ -3,6 +3,7 @@
<Script file="ArmorSetParts.lua" />
<Script file="BuffAmount.lua" />
<Script file="BuffComboPoints.lua" />
+ <Script file="BuffCount.lua" />
<Script file="BuffDamageMultiplier.lua" />
<Script file="BuffDuration.lua" />
<Script file="BuffExpires.lua" />