diff --git a/GuildSkadaHighScore.toc b/GuildSkadaHighScore.toc
index c6c6c00..70c0f0a 100644
--- a/GuildSkadaHighScore.toc
+++ b/GuildSkadaHighScore.toc
@@ -1,10 +1,10 @@
## Interface: 60000
## Author: Verath (Peter Eliasson)
-## Version: 0.0.2
+## Version: 0.0.3
## Title: Guild Skada High Score
## Notes: Tracking and ranking of dps/hps in a guild.
## SavedVariables: GuildSkadaHighScoreDB
-## Dependencies: Skada
+## Dependencies:
lib\lib_include.xml
src\src_include.xml
diff --git a/src/main.lua b/src/main.lua
index 1bbcf1a..c9360a7 100644
--- a/src/main.lua
+++ b/src/main.lua
@@ -4,7 +4,7 @@ local tinsert = tinsert;
local tremove = tremove;
-- Create ACE3 addon
-local addon = LibStub("AceAddon-3.0"):NewAddon(addonName, "AceConsole-3.0", "AceEvent-3.0", "AceHook-3.0")
+local addon = LibStub("AceAddon-3.0"):NewAddon(addonName, "AceConsole-3.0", "AceEvent-3.0")
tinsert(addonTable, addon);
_G[addonName] = addon
@@ -130,16 +130,33 @@ function addon:GetGuildPlayersFromSet(skadaSet)
return players
end
-function addon:SetRoleForPlayers(players)
- for _, player in ipairs(players) do
- player.role = UnitGroupRolesAssigned(player.name);
+function addon:OnEncounterEndSuccess()
+ self:Debug("OnEncounterEndSuccess")
+
+ local guildName = self.guildName;
+ if not guildName then
+ self:Debug("Not in a guild");
+ return;
end
-end
-function addon:SetClassForPlayers(players)
- for _, player in ipairs(players) do
- player.class = UnitClass(player.name);
+ local encounter = self.currentEncounter;
+ if not encounter then
+ self:Debug("No current encounter");
+ return
end
+
+ local pmc = self.parseModulesCore;
+ pmc:GetParsesForEncounter(encounter, function(success, startTime, duration, players)
+ if not success then return end;
+
+ encounter.startTime = startTime;
+ encounter.duration = duration;
+ self.inspect:GetInspectDataForPlayers(players, function()
+ self.highscore:AddEncounterParsesForPlayers(guildName, encounter, players);
+ end)
+ end)
+
+ self:UnsetCurrentEncounter();
end
function addon:PLAYER_GUILD_UPDATE(evt, unitId)
@@ -156,9 +173,10 @@ end
function addon:ENCOUNTER_END(evt, encounterId, encounterName, difficultyId, raidSize, endStatus)
self:Debug("ENCOUNTER_END", encounterId, encounterName, difficultyId, raidSize, endStatus)
if endStatus == 1 then -- Success
- self:SetCurrentEncounter(encounterId, encounterName, difficultyId, raidSize)
+ self:SetCurrentEncounter(encounterId, encounterName, difficultyId, raidSize);
+ self:OnEncounterEndSuccess();
else
- self:UnsetCurrentEncounter()
+ self:UnsetCurrentEncounter();
end
end
@@ -166,43 +184,6 @@ function addon:ZONE_CHANGED_NEW_AREA(evt)
self:UpdateCurrentZone();
end
-function addon:EndSegment()
- self:Debug("EndSegment")
-
- -- Find the skada set matching the encounter
- -- Looking only at the lastest set should make sense,
- -- as that set should be the boss segment we just ended.
- local _, skadaSet = next(Skada:GetSets());
- local encounter = self.currentEncounter;
-
- if not self.guildName then
- self:Debug("Not in a guild");
- return;
- end
-
- if not encounter then
- self:Debug("No current encounter");
- return
- end
-
- if not skadaSet or not skadaSet.gotboss or skadaSet.mobname ~= encounter.name then
- self:Debug("No Skada set found for boss");
- return;
- end
-
- encounter.duration = skadaSet.time;
- encounter.startTime = skadaSet.starttime;
-
- local players = self:GetGuildPlayersFromSet(skadaSet);
- self:SetRoleForPlayers(players);
- self:SetClassForPlayers(players);
- self.inspect:GetInspectDataForPlayers(players, function()
- self.highscore:AddEncounterParsesForPlayers(self.guildName, encounter, players);
- end)
-
- self:UnsetCurrentEncounter();
-end
-
function addon:OnInitialize()
self.db = LibStub("AceDB-3.0"):New("GuildSkadaHighScoreDB", addon.dbDefaults, true)
@@ -237,8 +218,6 @@ function addon:OnEnable()
self:RegisterEvent("PLAYER_GUILD_UPDATE")
self:RegisterEvent("ZONE_CHANGED_NEW_AREA")
- self:SecureHook(Skada, "EndSegment")
-
self:RegisterChatCommand("gshs", function()
self.gui:ShowMainFrame();
end)
@@ -257,7 +236,5 @@ function addon:OnDisable()
self:UnregisterEvent("PLAYER_GUILD_UPDATE")
self:UnregisterEvent("ZONE_CHANGED_NEW_AREA")
- self:UnHook(Skada, "EndSegment");
-
self:UnregisterChatCommand("gshs");
end
diff --git a/src/parse_modules/parse_modules_core.lua b/src/parse_modules/parse_modules_core.lua
new file mode 100644
index 0000000..ff21f3f
--- /dev/null
+++ b/src/parse_modules/parse_modules_core.lua
@@ -0,0 +1,105 @@
+--
+-- The parseModulesCore is a container module for our
+-- parse provider modules.
+--
+
+local addonName, addonTable = ...
+local addon = addonTable[1];
+
+-- Global functions for faster access
+local tinsert = tinsert;
+
+-- Create the parseModulesCore
+local pmc = addon:NewModule("parseModulesCore")
+addon.parseModulesCore = pmc;
+
+-- Set up the prototype for parse providers
+do
+ local proto = {}
+
+ function proto:Debug(...)
+ pmc:Debug(...);
+ end
+
+ -- Function called by the Parse Module Core to determine
+ -- if this module can be enabled or not. Should test that
+ -- all dependencies are loaded.
+ function proto:IsActivatable()
+ return false;
+ end
+
+ -- Function that must be called for each player before it
+ -- can be included in the parses returned.
+ -- Returns true if the player should be included.
+ function proto:ShouldIncludePlayer(playerId, playerName)
+ return addon:IsInMyGuild(playerName);
+ end
+
+ -- Should get a list of player parses for the specified encounter.
+ --
+ -- The callback function should be called with (success, startTime, duration, parses)
+ -- success - boolean indicating if parses were found.
+ -- startTime - the time when the encounter started.
+ -- duration - the time in seconds of the encounter.
+ -- players - list of player parse objects ({id="", name="", damage=0, healing=0})
+ -- of players passing the ShouldIncludePlayer test.
+ --
+ -- Params:
+ -- encounter - An object describing the encounter with the following keys:
+ -- zoneId, zoneName, id, name, difficultyId, difficultyName, raidSize
+ -- callback - The function to be called when the parse is ready.
+ function proto:GetParsesForEncounter(encounter, callback)
+ callback(false);
+ end
+
+ pmc:SetDefaultModulePrototype(proto);
+ -- Parse provider modules are disabled by default,
+ -- as only one should be used at a time
+ pmc:SetDefaultModuleState(false);
+end
+
+
+local function setAdditionalDataForPlayers(players)
+ for _, player in ipairs(players) do
+ player.role = UnitGroupRolesAssigned(player.name);
+ player.class = UnitClass(player.name);
+ end
+end
+
+-- Function for getting parses for an encounter. This
+-- function will forward the call to the selected parse
+-- provider if available. Will also add additional information
+-- like spec and role to successful parse fetches
+function pmc:GetParsesForEncounter(encounter, callback)
+ local parseProvider = self.selectedParseProvider
+ if parseProvider then
+ parseProvider:GetParsesForEncounter(encounter, function(success, startTime, duration, players)
+ if success then
+ setAdditionalDataForPlayers(players);
+ end
+ callback(success, startTime, duration, players);
+ end);
+ else
+ callback(false);
+ end
+end
+
+function pmc:SelectParseProvider()
+ for name, mod in self:IterateModules() do
+ if mod:IsActivatable() then
+ self:Debug("Using " .. name .. " as parse provider.");
+ self.selectedParseProvider = mod;
+ mod:Enable();
+ break;
+ end
+ end
+end
+
+function pmc:OnEnable()
+ self.selectedParseProvider = nil;
+ self:SelectParseProvider();
+end
+
+function pmc:OnDisable()
+ self.selectedParseProvider = nil;
+end
\ No newline at end of file
diff --git a/src/parse_modules/parse_modules_include.xml b/src/parse_modules/parse_modules_include.xml
new file mode 100644
index 0000000..747f042
--- /dev/null
+++ b/src/parse_modules/parse_modules_include.xml
@@ -0,0 +1,4 @@
+<Ui xsi:schemaLocation="http://www.blizzard.com/wow/ui/ ..\..\FrameXML\UI.xsd">
+ <Script file="parse_modules_core.lua"/>
+ <Script file="skada.lua"/>
+</Ui>
\ No newline at end of file
diff --git a/src/parse_modules/skada.lua b/src/parse_modules/skada.lua
new file mode 100644
index 0000000..a60e56b
--- /dev/null
+++ b/src/parse_modules/skada.lua
@@ -0,0 +1,88 @@
+local addonName, addonTable = ...
+local addon = addonTable[1];
+local pmc = addon.parseModulesCore;
+
+local mod = pmc:NewModule("Skada", "AceHook-3.0");
+if not mod then return end;
+
+-- Global functions
+local wipe = wipe;
+local tinsert = tinsert;
+
+
+function mod:IsActivatable()
+ return IsAddOnLoaded("Skada");
+end
+
+function mod:GetPlayersFromSet(skadaSet)
+ local players = {}
+
+ -- Have to copy the data as skadaSet.players is a direct reference
+ -- to the skada set.
+ for i, player in ipairs(skadaSet.players) do
+ if self:ShouldIncludePlayer(player.id, player.name) then
+ local playerData = {
+ id = player.id,
+ name = player.name,
+ damage = player.damage,
+ healing = player.healing
+ };
+ tinsert(players, playerData);
+ end
+ end
+ return players
+end
+
+function mod:ProcessParseRequest(encounter, callback)
+ -- Find the skada set matching the encounter. Looking only
+ -- at the lastest set should make sense, as that set
+ -- should be the boss segment we just ended.
+ local _, skadaSet = next(Skada:GetSets());
+
+ if not skadaSet or not skadaSet.gotboss or skadaSet.mobname ~= encounter.name then
+ self:Debug("No Skada set found for boss");
+ return callback(false);
+ end
+
+ local duration = skadaSet.time;
+ local startTime = skadaSet.starttime;
+ local playerParses = self:GetPlayersFromSet(skadaSet);
+
+ return callback(true, startTime, duration, playerParses);
+end
+
+
+function mod:GetParsesForEncounter(encounter, callback)
+ -- If Skada hasn't finshed the segment, wait for it
+ if Skada.current then
+ tinsert(self.pendingParseRequests, {encounter = encounter, callback = callback});
+ else
+ self:ProcessParseRequest(encounter, callback);
+ end
+end
+
+function mod:EndSegment()
+ self:Debug("Skada: EndSegment")
+
+ -- If we have requests waiting for EndSegment, process them now.
+ if #self.pendingParseRequests then
+ for _, pendingRequest in ipairs(self.pendingParseRequests) do
+ local encounter = pendingRequest.encounter;
+ local callback = pendingRequest.callback;
+ self:ProcessParseRequest(encounter, callback);
+ end
+ wipe(self.pendingParseRequests);
+ end
+end
+
+function mod:OnEnable()
+ self.pendingParseRequests = {};
+
+ self:SecureHook(Skada, "EndSegment");
+end
+
+function mod:OnDisable()
+ wipe(self.pendingParseRequests);
+
+ self:UnHook(Skada, "EndSegment");
+end
diff --git a/src/src_include.xml b/src/src_include.xml
index be9fd62..1ad2cc5 100644
--- a/src/src_include.xml
+++ b/src/src_include.xml
@@ -3,4 +3,5 @@
<Script file="inspect.lua"/>
<Script file="highscore.lua"/>
<Script file="gui.lua"/>
+ <Include file="parse_modules\parse_modules_include.xml"/>
</Ui>
\ No newline at end of file