local _, L = ...
local LMB, RMB = CreateAtlasMarkup("NPE_LeftClick", 18, 18), CreateAtlasMarkup("NPE_RightClick", 18,18);
--EVENTS_TRACKER_MODULE = ObjectiveTracker_GetModuleInfoTable("EVENTS_TRACKER_MODULE");
--EVENTS_TRACKER_MODULE.updateReasonModule = OBJECTIVE_TRACKER_UPDATE_MODULE_EVENTS;
--EVENTS_TRACKER_MODULE:SetHeader(ObjectiveTrackerFrame.BlocksFrame.ProfessionHeader, PROFESSIONS_TRACKER_HEADER_PROFESSION);
EventsTrackerMixin = {}
local eventFrame = {}
local selfName
---------------------------------------------
-- Default config
local DefaultConfig = {
collapsed = false,
iconSize = 26,
iconSpace = 8,
iconsInRow = 8,
fontSize = 10,
speakVolume = 70,
timeBefore = 300,
extendedTooltip = true,
events = {
[1] = { name = "Community feast",
texture = "MajorFactions_MapIcons_Tuskarr64",
eventRegionOffset = {
[1] = 52, -- us
[2] = 52, -- kr
[3] = 52, -- eu
[4] = 52, -- tw
[5] = 52,}, -- ch
eventDuration = 900,
eventInterval = 5400,
enable = true,
sound = false,
voice_before = false,
voice_active = false,
anim = true,
questIDs = {70893},
findEventOnMap = {},
coor = {2024, 13.4, 48.4},
datablock = {},
},
[2] = { name = "Researchers under fire",
texture = "MajorFactions_MapIcons_Niffen64",
eventRegionOffset = {
[1] = 1800,
[2] = 1800,
[3] = 1800,
[4] = 1800,
[5] = 1800,},
eventDuration = 1500,
eventInterval = 3600,
enable = true,
sound = false,
voice_before = false,
voice_active = false,
anim = true,
questIDs = {75627, 75628, 75629, 75630}, -- Epic 75630, Rare 75629, Uncommon, 75628, Common 75627
findEventOnMap = {},
coor = {2133, 47.6, 56.7},
datablock = {},
},
[3] = { name = "Dragonbane Keep",
texture = "MajorFactions_MapIcons_Expedition64",
eventRegionOffset = {
[1] = 100,
[2] = 100,
[3] = 100,
[4] = 100,
[5] = 100,},
eventDuration = 3600,
eventInterval = 7200,
enable = true,
sound = false,
voice_before = false,
voice_active = false,
anim = true,
questIDs = {70866},
findEventOnMap = {},
coor = {2022, 30.48, 78.20},
datablock = {},
},
[4] = { name = "Time rift",
texture = "interface/targetingframe/unitframeicons.blp", --ChromieTime-32x32
eventRegionOffset = {
[1] = 20,
[2] = 20,
[3] = 20,
[4] = 20,
[5] = 20,},
eventDuration = 900,
eventInterval = 3600,
enable = true,
sound = false,
voice_before = false,
voice_active = false,
anim = true,
questIDs = {77836},
findEventOnMap = {},
coor = {2025, 51, 57},
datablock = {},
},
[5] = { name = "Rares spawn",
texture = "VignetteKillElite",
eventRegionOffset = {
[1] = 0,
[2] = 0,
[3] = 14400,
[4] = 0,
[5] = 0,},
eventDuration = 60,
eventInterval = 1800,
enable = true,
sound = false,
voice_before = false,
voice_active = false,
anim = true,
questIDs = {},
findEventOnMap = {},
coor = {},
datablock = {
[0] = {name = "Amethyzar the Glittering", enable = true, coor = {2022, 63.6, 55.0},},
[1] = {name = "Eldoren the Reborn", enable = true, coor = {2025, 47.8, 51.2},},
[2] = {name = "Pheran", enable = true, coor = {2025, 60.6, 61.6},},
[3] = {name = "Skag the Thrower", enable = true, coor = {2024, 26.8, 49.6},},
[4] = {name = "Mikrin of the Raging Winds", enable = true, coor = {2023, 63.0, 80.0},},
[5] = {name = "Rokmur", enable = true, coor = {2025, 50.0, 51.6},},
[6] = {name = "Smogswog the Firebreather", enable = true, coor = {2022, 69.6, 64.6},},
[7] = {name = "Matriarch Remalla", enable = true, coor = {2025, 52.8, 59.0},},
[8] = {name = "O'nank Shorescour", enable = true, coor = {2022, 79.19, 52.92},},
[9] = {name = "Researcher Sneakwing", enable = true, coor = {2023, 37.0, 53.8},},
[10] = {name = "Treasure-Mad Trambladd", enable = true, coor = {2025, 35.0, 70.0},},
[11] = {name = "Harkyn Grymstone", enable = true, coor = {2022, 42.2, 39.6},},
[12] = {name = "Fulgurb", enable = true, coor = {2023, 75.2, 46.8},},
[13] = {name = "Sandana the Tempest", enable = true, coor = {2025, 37.6, 78.0},},
[14] = {name = "Gorjo the Crab Shackler", enable = true, coor = {2022, 78.6, 49.8},},
[15] = {name = "Steamgill", enable = true, coor = {2023, 53.6, 72.8},},
[16] = {name = "Tempestrian", enable = true, coor = {2025, 50.0, 79.0},},
[17] = {name = "Massive Magmashell", enable = true, coor = {2022, 21.8, 76.6},},
[18] = {name = "Grumbletrunk", enable = true, coor = {2024, 19.6, 43.2},},
[19] = {name = "Oshigol", enable = true, coor = {2023, 61.6, 30.0},},
[20] = {name = "Broodweaver Araznae", enable = true, coor = {2025, 61.51, 73.74},},
[21] = {name = "Azra's Prized Peony", enable = true, coor = {2022, 54.6, 71.6},},
[22] = {name = "Malsegan", enable = true, coor = {2023, 72.0, 46.6},},
[23] = {name = "Phleep", enable = true, coor = {2025, 58.6, 85.6},},
[24] = {name = "Magmaton", enable = true, coor = {2022, 40.0, 64.0},},
[25] = {name = "Gruffy", enable = true, coor = {2024, 32.6, 29.2},},
[26] = {name = "Ronsak the Decimator", enable = true, coor = {2023, 43.6, 55.4},},
[27] = {name = "Riverwalker Tamopo", enable = true, coor = {2025, 39.8, 70.0},},
},
},
[6] = { name = "Dreamsurge",
texture = "dreamsurge_hub-icon",
eventRegionOffset = {
[1] = 19,
[2] = 19,
[3] = 19,
[4] = 19,
[5] = 19,},
eventDuration = 1800,
eventInterval = 1800,
enable = true,
sound = false,
voice_before = false,
voice_active = false,
anim = true,
questIDs = {77251},
findEventOnMap = {2022, 2023, 2024, 2025},
coor = {},
datablock = {},
},
[7] = { name = "Storm's Fury",
texture = "ElementalStorm-Boss-Water",
eventRegionOffset = {
[1] = 1670338860 + 3600,
[2] = 1670698860,
[3] = 1674763260,
[4] = 1670698860,
[5] = 1670677260,},
eventDuration = 7200,
eventInterval = 18000,
enable = true,
sound = false,
voice_before = false,
voice_active = false,
anim = true,
questIDs = {74378}, --73162
findEventOnMap = {},
coor = {2025, 59.84, 82.29},
datablock = {},
},
[8] = { name = "Trial of Elements", -- ENCOUNTER_LOOT_RECEIVED: encounterID, itemID, itemLink, quantity, playerName, classFileName
texture = "VignetteLootElite", -- AREA_POIS_UPDATE
eventRegionOffset = {
[1] = 1670342460,
[2] = 1670698860,
[3] = 1674763260,
[4] = 1670698860,
[5] = 1670677260,},
eventDuration = 600,
eventInterval = 3600,
enable = true,
sound = false,
voice_before = false,
voice_active = false,
anim = true,
questIDs = {71995}, --71033 Flood
findEventOnMap = {},
coor = {},
datablock = {
[0] = {name = "Trial of the Elements", enable = false, coor = {2085, 27.91, 25.86},},
[1] = {name = "Trial of the Elements", enable = false, coor = {2085, 27.91, 25.86},},
[2] = {name = "Trial of the Elements", enable = true, coor = {2085, 27.91, 25.86},},
[3] = {name = "Trial of the Elements", enable = true, coor = {2085, 27.91, 25.86},},
[4] = {name = "Trial of the Elements", enable = true, coor = {2085, 27.91, 25.86},},
},
},
[9] = { name = "Elemental Storm",
texture = "ElementalStorm-Lesser-Earth",
eventRegionOffset = {
[1] = 60,
[2] = 60,
[3] = 60,
[4] = 60,
[5] = 60,},
eventDuration = 7200,
eventInterval = 10800,
enable = true,
sound = false,
voice_before = false,
voice_active = false,
anim = true,
questIDs = {70752, 70753, 70754, 70723, 72686}, -- Water 70752, Air 70753, Fire 70754, Earth 70723, Surge 72686
findEventOnMap = {2022, 2023, 2024, 2025},
coor = {},
datablock = {},
},
[10] = { name = "Superbloom",
texture = "MajorFactions_MapIcons_Dream64",
eventRegionOffset = {
[1] = 11,
[2] = 11,
[3] = 11,
[4] = 11,
[5] = 11,},
eventDuration = 1040,
eventInterval = 3600,
enable = true,
sound = false,
voice_before = false,
voice_active = false,
anim = true,
questIDs = {78319},
findEventOnMap = {},
coor = {2200, 51.39, 59.71},
datablock = {},
},
[11] = { name = "The Big Dig",
texture = "interface/archeology/arch-icon-marker.blp",
eventRegionOffset = {
[1] = 1836,
[2] = 1836,
[3] = 1836,
[4] = 1836,
[5] = 1836,},
eventDuration = 552,
eventInterval = 3600,
enable = true,
sound = false,
voice_before = false,
voice_active = false,
anim = true,
questIDs = {79226},
findEventOnMap = {},
coor = {2024, 26.96, 46.46},
datablock = {},
},
[12] = { name = "Hearthstone",
texture = "WarlockPortal-Yellow-32x32",
eventRegionOffset = {
[1] = 48,
[2] = 48,
[3] = 48,
[4] = 48,
[5] = 48,},
eventDuration = 300,
eventInterval = 3600,
enable = true,
sound = false,
voice_before = false,
voice_active = false,
anim = true,
questIDs = {},
findEventOnMap = {},
coor = {},
datablock = {
[0] = {name = "Hearthstone in Valdraken", enable = true, coor = {2112, 62.38, 67.40},},
[1] = {name = "Hearthstone in Stormwind", enable = true, coor = {84, 33.8, 19.6},}, --UnitFactionGroup("player") == 'Alliance' and {84, 33.8, 19.6} or {1, 52.8, 15.8},},
[2] = {name = "Hearthstone in Durotar", enable = true, coor = {1, 52.8, 15.8},},
},
},
},
}
---------------------------------------------
-- Setup functions
SetupEventsTrackerMixin = {};
function SetupEventsTrackerMixin:OnShow()
self.IconSizeSlider:SetEnabled(true);
self.IconSizeSlider:SetupSlider(L.cfg.iconSize);
self.IconSpaceSlider:SetEnabled(true);
self.IconSpaceSlider:SetupSlider(L.cfg.iconSpace);
self.IconsInRowSlider:SetEnabled(true);
self.IconsInRowSlider:SetupSlider(L.cfg.iconsInRow);
self.FontSizeSlider:SetEnabled(true);
self.FontSizeSlider:SetupSlider(L.cfg.fontSize);
self.SpeakVolumeSlider:SetEnabled(true);
self.SpeakVolumeSlider:SetupSlider(L.cfg.speakVolume);
self.TimeBeforeSlider:SetEnabled(true);
self.TimeBeforeSlider:SetupSlider(L.cfg.timeBefore);
self.ExtendedTooltipCheckButton:SetControlChecked(L.cfg.extendedTooltip);
local function onExtendedTooltipChecked(isChecked, isUserInput)
L.cfg.extendedTooltip = isChecked
end
self.ExtendedTooltipCheckButton:SetCallback(onExtendedTooltipChecked);
self.animIn:Play();
end
IconSizeSliderMixin = {};
function IconSizeSliderMixin:SetupSlider(value)
self.Slider:Init(value, 12, 40, 40 - 12, self.formatters);
end
function IconSizeSliderMixin:SetEnabled(enabled)
self.Slider:SetEnabled_(enabled);
end
function IconSizeSliderMixin:OnSliderValueChanged(value)
L.cfg.iconSize = value;
EventsTrackerMixin:ReloadAllEvents();
end
IconSpaceSliderMixin = {};
function IconSpaceSliderMixin:SetupSlider(value)
self.Slider:Init(value, 0, 16, 16, self.formatters);
end
function IconSpaceSliderMixin:SetEnabled(enabled)
self.Slider:SetEnabled_(enabled);
end
function IconSpaceSliderMixin:OnSliderValueChanged(value)
L.cfg.iconSpace = value;
EventsTrackerMixin:ReloadAllEvents();
end
IconsInRowSliderMixin = {};
function IconsInRowSliderMixin:SetupSlider(value)
self.Slider:Init(value, 1, 40, 40 - 1, self.formatters);
end
function IconsInRowSliderMixin:SetEnabled(enabled)
self.Slider:SetEnabled_(enabled);
end
function IconsInRowSliderMixin:OnSliderValueChanged(value)
L.cfg.iconsInRow = value;
EventsTrackerMixin:ReloadAllEvents();
end
FontSizeSliderMixin = {};
function FontSizeSliderMixin:SetupSlider(value)
self.Slider:Init(value, 7, 20, 20 - 7, self.formatters);
end
function FontSizeSliderMixin:SetEnabled(enabled)
self.Slider:SetEnabled_(enabled);
end
function FontSizeSliderMixin:OnSliderValueChanged(value)
L.cfg.fontSize = value;
EventsTrackerMixin:ReloadAllEvents();
end
SpeakVolumeSliderMixin = {};
function SpeakVolumeSliderMixin:SetupSlider(value)
self.Slider:Init(value, 1, 100, 99, self.formatters);
end
function SpeakVolumeSliderMixin:SetEnabled(enabled)
self.Slider:SetEnabled_(enabled);
end
function SpeakVolumeSliderMixin:OnSliderValueChanged(value)
L.cfg.speakVolume = value;
end
TimeBeforeSliderMixin = {};
function TimeBeforeSliderMixin:SetupSlider(value)
self.Slider:Init(value, 60, 600, 600-60, self.formatters);
end
function TimeBeforeSliderMixin:SetEnabled(enabled)
self.Slider:SetEnabled_(enabled);
end
function TimeBeforeSliderMixin:OnSliderValueChanged(value)
L.cfg.timeBefore = value;
end
---------------------------------------------
-- Pomocne funkcie
EventsTrackerMixin.FUNC_QUEUE_TABLE = {}
function EventsTrackerMixin:CallFunctionOutOfCombat(funcName, ...)
if type(funcName) == 'function' then
if InCombatLockdown() then
table_insert(self.FUNC_QUEUE_TABLE,{funcName,{...}})
else
funcName(...)
end
end
end
-- 2022 The Walking Shore, 2023 Ohn'Ahran plains, 2024 The Azure Span, 2025 Taldraszus, 2112 Valdrakken
--/dump EventsTrackerMixin:FindEventOnMaps("all", {84})
function EventsTrackerMixin:FindEventOnMaps(eventName, maps)
for _, mapID in next, maps do
local areaPoiIDs = C_AreaPoiInfo.GetAreaPOIForMap(mapID);
for _, ids in pairs(areaPoiIDs) do
--areaPoiID,position,name,description,textureIndex,widgetSetID,atlasName,uiTextureKit,shouldGlow,factionID,isPrimaryMapForPOI,isAlwaysOnFlightmap,addPaddingAboveWidgets,highlightWorldQuestsOnHover,highlightVignettesOnHover
local poiInfo = C_AreaPoiInfo.GetAreaPOIInfo(mapID, ids);
if eventName == "all" then
print("--------------------------------------");
print(C_Map.GetMapInfo(mapID).name .. "("..mapID..") - "..poiInfo.name)
print(poiInfo.atlasName, poiInfo.isPrimaryMapForPOI)
elseif ((poiInfo.atlasName == "dreamsurge_hub-icon" and eventName == "Dreamsurge") or poiInfo.name == eventName) and poiInfo.isPrimaryMapForPOI then
local elementType = poiInfo.atlasName and strmatch(poiInfo.atlasName, "ElementalStorm%-Lesser%-(.+)") or "";
local x, y = poiInfo.position:GetXY();
return mapID, x*100, y*100, poiInfo.areaPoiID, poiInfo.atlasName, elementType
end
end
end
end
local function SetTextureForEventFrame(frame, texture)
if tonumber(texture) then
frame.icon:SetTexture(texture);
frame.icon:SetTexCoord(.08, .92, 0.08, 0.92);
else
local info = C_Texture.GetAtlasInfo(texture);
if info then
frame.icon:SetAtlas(texture);
else
frame.icon:SetTexture(texture);
end
end
end
local function isQuestCompleted(questIDTable)
local completed = 0;
if questIDTable and (type(questIDTable) == "table") then
for _, questID in pairs(questIDTable) do
if (C_QuestLog.IsOnQuest(questID)) then
isCompleted = C_QuestLog.IsComplete(questID);
else
isCompleted = C_QuestLog.IsQuestFlaggedCompleted(questID);
end
if isCompleted then
completed = completed + 1;
end
end
end
return (completed > 0)
end
local function InstanceCheck()
if IsInInstance() then
if EventsTrackerHeader:IsShown() then
EventsTrackerMixin:ReloadAllEvents(true)
EventsTrackerHeader:Hide()
end
elseif not EventsTrackerHeader:IsShown() then
EventsTrackerMixin:ReloadAllEvents(false)
EventsTrackerHeader:Show()
end
end
local function SetupReset()
for key, value in pairs(DefaultConfig.events) do
L.cfg.events[key].enable = value.enable;
L.cfg.events[key].sound = value.sound;
L.cfg.events[key].voice_before = value.voice_before;
L.cfg.events[key].voice_active = value.voice_active;
L.cfg.events[key].anim = value.anim;
end
L.cfg.collapsed = DefaultConfig.collapsed;
L.cfg.iconSize = DefaultConfig.iconSize;
L.cfg.iconSpace = DefaultConfig.iconSpace;
L.cfg.iconsInRow = DefaultConfig.iconsInRow;
L.cfg.fontSize = DefaultConfig.fontSize;
L.cfg.speakVolume = DefaultConfig.speakVolume;
L.cfg.timeBefore = DefaultConfig.timeBefore;
L.cfg.savedposition = {"CENTER", nil, "CENTER", 0, 0};
EventsTrackerHeader:ClearAllPoints();
EventsTrackerHeader:SetPoint(unpack(L.cfg.savedposition));
EventsTrackerMixin:ReloadAllEvents();
end
function EventsTrackerMixin:GetLinkToEvent(index)
return L.cfg.events[index];
end
function EventsTrackerMixin:GetLinkToFullEvent(index)
return DefaultConfig.events[index];
end
function EventsTrackerMixin:GetTimeBefore()
return L.cfg.timeBefore;
end
function EventsTrackerMixin:GetCollapsed()
return L.cfg.collapsed;
end
function EventsTrackerMixin:SetCollapsed(value)
L.cfg.collapsed = value;
end
function EventsTrackerMixin:SavePosition(point, relativeTo, relativePoint, xOfs, yOfs)
L.cfg.savedposition = {point, relativeTo, relativePoint, xOfs, yOfs};
end
local function UpdateAllQuestCompleted()
for i, v in ipairs(L.cfg.events) do
if next(DefaultConfig.events[i].questIDs) then
local isComplete = isQuestCompleted(DefaultConfig.events[i].questIDs);
if v.enable and eventFrame[i] then
eventFrame[i].icon:SetDesaturated(isComplete);
end
L.cfg.events[i].isComplete = isComplete;
_G["EventsTrackerDB"][selfName].events[i].isComplete = isComplete;
end
end
end
function EventsTrackerMixin:GetToolTipComplete(index)
if not next(DefaultConfig.events[index].questIDs) then
return "", ""
end
local completeOnCurrentChar;
local completeOnAccout = "";
if _G["EventsTrackerDB"][selfName].events[index].isComplete then
completeOnCurrentChar = "|cFF00FF00Complete on this character|r"
else
completeOnCurrentChar = "|cFFFF0000Not complete on this character|r";
end
if L.cfg.extendedTooltip then
for name in pairs(_G["EventsTrackerDB"]) do
if name ~= selfName and _G["EventsTrackerDB"][name].enable then
if not _G["EventsTrackerDB"][name].events[index] or _G["EventsTrackerDB"][name].events[index].isComplete == nil or not _G["EventsTrackerDB"][name].events[index].isComplete then
local classColorStr = _G["EventsTrackerDB"][name].class and RAID_CLASS_COLORS[_G["EventsTrackerDB"][name].class].colorStr or "FFFFFFFF"
completeOnAccout = completeOnAccout .. "|c"..classColorStr .. name .. "|r\n"
end
end
end
end
return completeOnCurrentChar, completeOnAccout
end
function EventsTrackerMixin:WeeklyUpdate(reset)
local weeklyResetTime = C_DateAndTime.GetSecondsUntilWeeklyReset()
if reset or (_G["EventsTrackerSetup"].savedResetTime and _G["EventsTrackerSetup"].savedResetTime < weeklyResetTime) then
print("|cFFFF0000Events tracker weekly reset.|r")
for name in pairs(_G["EventsTrackerDB"]) do
for i in pairs(_G["EventsTrackerDB"][name].events) do
if i > #DefaultConfig.events then
_G["EventsTrackerDB"][name].events[i] = nil
elseif next(DefaultConfig.events[i].questIDs) then
_G["EventsTrackerDB"][name].events[i].isComplete = false;
end
end
end
end
_G["EventsTrackerSetup"].savedResetTime = weeklyResetTime;
end
local function FindNextEventInDataBlock(self, index)
for i = 0, #DefaultConfig.events[self.index].datablock do
if not DefaultConfig.events[self.index].datablock[index].enable then
self.timeTmp = (self.timeTmp or 0) + DefaultConfig.events[self.index].eventInterval;
else
return index
end
index = index == #DefaultConfig.events[self.index].datablock and 0 or (index + 1);
end
return index
end
local function CreateEventFrame(v, index)
local eFrame = CreateFrame("Button", nil, EventsTrackerHeader, "EventsTrackerButton");
local serverResetTime = GetServerTime() - (604800 - C_DateAndTime.GetSecondsUntilWeeklyReset());
local region = GetCurrentRegion();
-- ptr
if not region or region > 5 then
region = 1;
end
eFrame.index = index;
eFrame.initComplete = false;
eFrame.notification = false;
eFrame.isEventActive = nil;
eFrame.timeTmp = nil;
eFrame.enable = v.enable;
eFrame.sound = v.sound;
eFrame.voice_before = v.voice_before;
eFrame.voice_active = v.voice_active;
eFrame.anim = v.anim;
eFrame.tooltipTitle = DefaultConfig.events[index].name;
eFrame.coor = DefaultConfig.events[index].coor;
eFrame.eventNewRegionOffset = DefaultConfig.events[index].eventRegionOffset[region] > 1600000000 and DefaultConfig.events[index].eventRegionOffset[region] or (serverResetTime + DefaultConfig.events[index].eventRegionOffset[region]);
SetTextureForEventFrame(eFrame, DefaultConfig.events[index].texture);
eFrame.icon:SetDesaturated(v.isComplete);
eFrame:SetScript("OnUpdate", function(self, elapsed)
self.elapsed = (self.elapsed or 1) + elapsed;
if self.elapsed < 1 then return end
self.elapsed = 0;
if not self:IsShown() then return end
local timeFromFirstStart = GetServerTime() - self.eventNewRegionOffset;
local timeToNextEvent = (DefaultConfig.events[self.index].eventInterval - timeFromFirstStart % DefaultConfig.events[self.index].eventInterval) + (self.timeTmp and self.timeTmp or 0);
local timeActiveEvent = self.timeTmp and timeToNextEvent or DefaultConfig.events[self.index].eventDuration - (DefaultConfig.events[self.index].eventInterval - timeToNextEvent);
local isEventActive = (DefaultConfig.events[self.index].eventInterval + (self.timeTmp and self.timeTmp or 0)) - timeToNextEvent <= DefaultConfig.events[self.index].eventDuration;
local showedTime = isEventActive and timeActiveEvent or timeToNextEvent;
if not self.initComplete or (self.isEventActive and not isEventActive) then
if (self.isEventActive and not isEventActive) then self.isEventActive = false end
self.timer:SetTextColor(.9, .9, .9);
self.timeTmp = nil;
-- hladam dalsi event v databloku ak je neaky disabled preskocim ho a pripocitam cas
if next(DefaultConfig.events[self.index].datablock) then --not isEventActive and
local index = math.floor(((timeFromFirstStart + (not self.isEventActive and DefaultConfig.events[self.index].eventInterval or 0)) / DefaultConfig.events[self.index].eventInterval) % (#DefaultConfig.events[self.index].datablock + 1));
-- ak su nasledujuce eventy v databloku vypnute najdem prvy aktivny a upravim cas
index = FindNextEventInDataBlock(self, index)
local tmp = self.timeTmp
local nextIndex = index + 1
nextIndex = nextIndex > #DefaultConfig.events[self.index].datablock and 0 or nextIndex;
nextIndex = FindNextEventInDataBlock(self, nextIndex)
self.timeTmp = tmp
if DefaultConfig.events[self.index].datablock[index].name ~= DefaultConfig.events[self.index].datablock[nextIndex].name then
self.tooltipTitle = DefaultConfig.events[self.index].datablock[index].name .. "\n|cFF808080" .. DefaultConfig.events[self.index].datablock[nextIndex].name .."|r";
else
self.tooltipTitle = DefaultConfig.events[self.index].datablock[index].name
end
self.coor = DefaultConfig.events[self.index].datablock[index].coor;
elseif next(DefaultConfig.events[self.index].findEventOnMap) then
-- po ukonceni eventu (elemental storm) zmen na zakladnu iconu a popis
self.tooltipTitle = DefaultConfig.events[self.index].name;
SetTextureForEventFrame(self, DefaultConfig.events[self.index].texture);
self.icon:SetDesaturated(true);
wipe(self.coor);
end
end
if showedTime < 3600 then
self.timer:SetText(date("%M:%S", showedTime));
else
self.timer:SetText(date("%H", showedTime)-1 .. date("h%M", showedTime));
end
if not self.isEventActive and isEventActive then
if self.timeTmp and self.timeTmp > 0 then
self.timeTmp = self.timeTmp - DefaultConfig.events[self.index].eventInterval;
elseif DefaultConfig.events[self.index].eventDuration > 0 then
if next(DefaultConfig.events[self.index].findEventOnMap) then
local mapID, x, y, areaPoiID, atlasName, elementType = EventsTrackerMixin:FindEventOnMaps(DefaultConfig.events[self.index].name, DefaultConfig.events[self.index].findEventOnMap);
if mapID then
local mapName = C_Map.GetMapInfo(mapID).name;
self.tooltipTitle = DefaultConfig.events[self.index].name .. " in " ..mapName;
self.coor = {mapID, x, y};
if atlasName then
self.icon:SetAtlas(atlasName);
end
self.icon:SetDesaturated(false);
else
self.tooltipTitle = DefaultConfig.events[self.index].name;
SetTextureForEventFrame(self, DefaultConfig.events[self.index].texture);
self.icon:SetDesaturated(true);
wipe(self.coor);
return;
end
end
self.timer:SetTextColor(0, 1, 0);
if self.anim and not self.icon.Anim:IsPlaying() then
self.icon.Anim:Play();
end
if self.voice_active and self.initComplete then
C_VoiceChat.SpeakText(0, DefaultConfig.events[self.index].name.." is active.", 1, 0, L.cfg.speakVolume);
end
end
self.isEventActive = true;
elseif not isEventActive then
if showedTime < L.cfg.timeBefore and not self.timeTmp then
if not self.notification then
if self.sound and self.initComplete then
PlaySound(32585, "Master");
end
if self.voice_before and self.initComplete then
C_VoiceChat.SpeakText(0, DefaultConfig.events[self.index].name.." event will start in a moment.", 1, 0, L.cfg.speakVolume);
end
if self.anim and not self.icon.Anim:IsPlaying() then
self.icon.Anim:Play();
end
self.timer:SetTextColor(1, 1, 0);
self.notification = true;
end
elseif self.notification then
self.notification = false;
end
end
self.initComplete = true ;
end)
return eFrame;
end
function EventsTrackerMixin:ReloadAllEvents(hideAll)
local firstEventFrame, lastEventFrame;
local iconsInRow = 0;
for i, v in ipairs(L.cfg.events) do
if not hideAll and v.enable and not L.cfg.collapsed then
if not eventFrame[i] then
eventFrame[i] = CreateEventFrame(v, i);
end
eventFrame[i]:SetSize(L.cfg.iconSize, L.cfg.iconSize)
eventFrame[i].icon:SetSize(L.cfg.iconSize + 6, L.cfg.iconSize + 6)
eventFrame[i]:ClearAllPoints();
eventFrame[i].timer:SetFont("Fonts\\FRIZQT__.TTF", L.cfg.fontSize, "OUTLINE")
iconsInRow = (iconsInRow or 0) + 1;
if not lastEventFrame then
eventFrame[i]:SetPoint("TOPLEFT", EventsTrackerHeader, "TOPRIGHT", 4, -5);
firstEventFrame = eventFrame[i];
elseif iconsInRow > L.cfg.iconsInRow then
eventFrame[i]:SetPoint("TOP", firstEventFrame, "BOTTOM", 0, -12);
firstEventFrame = eventFrame[i];
iconsInRow = 1;
else
eventFrame[i]:SetPoint("LEFT", lastEventFrame, "RIGHT", L.cfg.iconSpace, 0);
end
eventFrame[i].enable = true;
eventFrame[i]:Show();
lastEventFrame = eventFrame[i];
elseif eventFrame[i] then
eventFrame[i]:Hide();
eventFrame[i]:SetScript("OnUpdate", nil);
eventFrame[i] = nil;
end
end
EventsTrackerHeader.CollapsedButton:SetButtonState(L.cfg.collapsed and "PUSHED" or "NORMAL", L.cfg.collapsed and true or false);
end
function EventsTrackerMixin:OnEvent(event, ...)
local arg1 = ...
if ( event == "ADDON_LOADED" ) then
if arg1 == _ then
selfName = UnitName("player") .. " - " .. GetRealmName();
if _G["EventsTrackerDB"] == nil then _G["EventsTrackerDB"] = {}; end
if _G["EventsTrackerDB"][selfName] == nil then
_G["EventsTrackerDB"][selfName] = {};
_G["EventsTrackerDB"][selfName].class = select(2, UnitClass("player"));
_G["EventsTrackerDB"][selfName].enable = true;
_G["EventsTrackerDB"][selfName].events = {};
end
-- prekopiruj nove eventy
for i, v in pairs(DefaultConfig.events) do
if _G["EventsTrackerDB"][selfName].events[i] == nil then
_G["EventsTrackerDB"][selfName].events[i] = {};
_G["EventsTrackerDB"][selfName].events[i].enable = v.enable;
_G["EventsTrackerDB"][selfName].events[i].sound = v.sound;
_G["EventsTrackerDB"][selfName].events[i].voice_before = v.voice_before;
_G["EventsTrackerDB"][selfName].events[i].voice_active = v.voice_active;
_G["EventsTrackerDB"][selfName].events[i].anim = v.anim;
end
end
-- zmaz zvysne eventy pod char save
if #DefaultConfig.events < #_G["EventsTrackerDB"][selfName].events then
for i = #DefaultConfig.events+1, #_G["EventsTrackerDB"][selfName].events do
_G["EventsTrackerDB"][selfName].events[i] = nil
end
end
-- pridaj nove hodnoty
for key, value in pairs(DefaultConfig) do
if _G["EventsTrackerDB"][selfName][key] == nil and type(value) ~= "table" then
_G["EventsTrackerDB"][selfName][key] = value;
end
end
L.cfg = _G["EventsTrackerDB"][selfName];
-- ak nebol nastaveny savedposition pre ETH nastav ho z predchadzajucej pozicie uzivatela
if not L.cfg.savedposition or (type(L.cfg.savedposition) ~= "table") then
local point, relativeTo, relativePoint, xOfs, yOfs = EventsTrackerHeader:GetPoint(1)
if point then
L.cfg.savedposition = {point, relativeTo, relativePoint, xOfs, yOfs};
else
L.cfg.savedposition = {"CENTER", nil, "CENTER", 0, 0}
end
end
if _G["EventsTrackerSetup"] == nil then _G["EventsTrackerSetup"] = {}; end
EventsTrackerHeader.SetupButton:SetScript("OnClick", function(self, button)
if button == "LeftButton" then
if SetupEventsTrackerFrame:IsShown() then
SetupEventsTrackerFrame:Hide()
EventsTrackerHeader.SetupButton:SetButtonState("NORMAL", false);
else
SetupEventsTrackerFrame:Show()
EventsTrackerHeader.SetupButton:SetButtonState("PUSHED", true);
end
elseif button == "RightButton"then
local menuFrame = CreateFrame("Frame", "EventsMenuFrame", UIParent, "UIDropDownMenuTemplate");
local menu = {};
local eventListMenu = {};
local copySetupMenu = {};
local charactersEnableMenu = {};
local selfName = UnitName("player") .. " - " .. GetRealmName();
-- vytvor Events list menu
for i, v in ipairs(L.cfg.events) do
tinsert(eventListMenu,
{ text = DefaultConfig.events[i].name,
checked = function() return v.enable; end,
keepShownOnClick = 1,
tooltipOnButton = 1,
tooltipTitle = v.name,
tooltipText = "Enable or diasable this event.",
func = function() v.enable = not v.enable; EventsTrackerMixin:ReloadAllEvents(); end
}
)
end
-- vytvor Reset menu
tinsert(copySetupMenu,
{ text = "Reset to default",
notCheckable = 1,
tooltipOnButton = 1,
tooltipTitle = "Reset",
tooltipText = "Reset setup for active character to default.",
colorCode = "|cFFFF0000",
func = function()
SetupReset()
CloseDropDownMenus();
if SetupEventsTrackerFrame:IsShown() then
SetupEventsTrackerFrame:Hide()
end
end
})
-- vytvor Copy to all
tinsert(copySetupMenu,
{ text = "Copy to all",
notCheckable = 1,
tooltipOnButton = 1,
tooltipTitle = "Copy",
tooltipText = "Copy this active setup to all your characters.",
colorCode = "|cFFFF0000",
func = function()
for name in pairs(_G["EventsTrackerDB"]) do
if name ~= selfName then
for key, value in pairs(L.cfg) do
if ( key == "events" ) then
for i, event in pairs(value) do
for x, y in pairs(event) do
if x ~= "isComplete" then
if _G["EventsTrackerDB"][name].events[i] == nil then
_G["EventsTrackerDB"][name].events[i] = {}
end
_G["EventsTrackerDB"][name].events[i][x] = y;
end
end
end
elseif key ~= "class" then
_G["EventsTrackerDB"][name][key] = value;
end
end
end
end
CloseDropDownMenus();
end
})
-- pridaj separator
tinsert(copySetupMenu,
{ text = "", hasArrow = false; dist = 0; isTitle = true; isUninteractable = true; notCheckable = true; iconOnly = true;
icon = "Interface\\Common\\UI-TooltipDivider-Transparent"; tCoordLeft = 0; tCoordRight = 1; tCoordTop = 0; tCoordBottom = 1; tSizeX = 0; tSizeY = 8; tFitDropDownSizeX = true;
iconInfo = { tCoordLeft = 0, tCoordRight = 1, tCoordTop = 0, tCoordBottom = 1, tSizeX = 0, tSizeY = 8, tFitDropDownSizeX = true},
})
-- vytvor copy form selected char
for name in pairs(_G["EventsTrackerDB"]) do
local classColorStr = _G["EventsTrackerDB"][name].class and RAID_CLASS_COLORS[_G["EventsTrackerDB"][name].class].colorStr or "FFFFFFFF"
if name ~= selfName then
tinsert(copySetupMenu,
{ text = name,
notCheckable = 1,
tooltipOnButton = 1,
tooltipTitle = name,
tooltipText = "Copy setup from this character",
colorCode = "|c" .. classColorStr,
func = function()
for key, value in pairs(_G["EventsTrackerDB"][name]) do
if ( key == "events" ) then
for i, event in pairs(value) do
for x, y in pairs(event) do
if x ~= "isComplete" then
_G["EventsTrackerDB"][selfName].events[i][x] = y;
L.cfg.events[i][x] = y;
end
end
end
elseif key ~= "class" then
_G["EventsTrackerDB"][selfName][key] = value;
L.cfg[key] = value;
end
end
if SetupEventsTrackerFrame:IsShown() then
SetupEventsTrackerFrame:Hide()
end
EventsTrackerMixin:ReloadAllEvents();
CloseDropDownMenus();
end
}
)
end
end
-- vytvor character enable
for name in pairs(_G["EventsTrackerDB"]) do
local classColorStr = _G["EventsTrackerDB"][name].class and RAID_CLASS_COLORS[_G["EventsTrackerDB"][name].class].colorStr or "FFFFFFFF"
tinsert(charactersEnableMenu,
{ text = name,
checked = function() return _G["EventsTrackerDB"][name].enable; end,
keepShownOnClick = 1,
tooltipOnButton = 1,
tooltipTitle = name,
tooltipText = "Enable this character for toolTip information.",
colorCode = "|c" .. classColorStr,
func = function() _G["EventsTrackerDB"][name].enable = not _G["EventsTrackerDB"][name].enable; end
}
)
end
tinsert(menu, { text = "Enable events", hasArrow = true, notCheckable = 1, menuList = eventListMenu});
tinsert(menu, { text = "Characters in toolTip", hasArrow = true, notCheckable = 1, menuList = charactersEnableMenu});
if copySetupMenu and #copySetupMenu > 0 then
tinsert(menu, { text = "Copy setup", hasArrow = true, notCheckable = 1, menuList = copySetupMenu});
end
EasyMenu(menu, menuFrame, "cursor", 0 , 0, "MENU");
end
end)
function EventsTrackerAlertFrame_SetUp(self, str, sound)
if str ~= nil then
self.Text:SetText(str);
end
--https://github.com/Gethe/wow-ui-source/blob/live/Interface/SharedXML/SoundKitConstants.lua
if sound then
PlaySound(sound);
end
end
EventsTrackerAlertSystem = AlertFrame:AddQueuedAlertFrameSubSystem("EventsTrackerWarningTemplate", EventsTrackerAlertFrame_SetUp, 6, math.huge);
SLASH_ETRACKER1 = "/etracker"
SlashCmdList["ETRACKER"] = function(msg)
if ( msg == "reset" ) then
SetupReset()
end
end
if IsAddOnLoaded(_) then
self:UnregisterEvent('ADDON_LOADED');
end
end
elseif ( event == "SCENARIO_UPDATE" ) then
if arg1 == false then
local bestMap = C_Map.GetBestMapForUnit("player");
if bestMap == 2085 then
EventsTrackerAlertSystem:AddAlert("You dont have active scenario, fly out and back to cave.", SOUNDKIT.UI_RAID_BOSS_WHISPER_WARNING);
end
elseif arg1 == nil then
UpdateAllQuestCompleted()
end
elseif ( event == "ZONE_CHANGED_NEW_AREA" ) then
EventsTrackerMixin:CallFunctionOutOfCombat(InstanceCheck())
elseif ( event == "PLAYER_ENTERING_WORLD" or ( event == "UNIT_QUEST_LOG_CHANGED" and arg1 == "player")) or event == "QUEST_TURNED_IN" or event == "ENCOUNTER_LOOT_RECEIVED" then
if event == "PLAYER_ENTERING_WORLD" then
self:CallFunctionOutOfCombat(InstanceCheck())
self:ReloadAllEvents();
EventsTrackerHeader:ClearAllPoints();
EventsTrackerHeader:SetPoint(unpack(L.cfg.savedposition));
end
UpdateAllQuestCompleted()
elseif ( event == "PLAYER_REGEN_ENABLED" ) then
for _, function_tbl in ipairs(self.FUNC_QUEUE_TABLE) do
if type(function_tbl[1]) == 'function' then
function_tbl[1](unpack(function_tbl[2]))
end
end
wipe(self.FUNC_QUEUE_TABLE)
elseif ( event == "COVENANT_CHOSEN" or event == "COVENANT_CALLINGS_UPDATED" ) then
self:WeeklyUpdate()
end
end
function EventsTrackerMixin:OnLoad()
for _, event in pairs({
"ADDON_LOADED",
"PLAYER_ENTERING_WORLD",
"ZONE_CHANGED_NEW_AREA",
"UNIT_QUEST_LOG_CHANGED", -- QUEST_WATCH_UPDATE. QUEST_LOG_UPDATE, UI_INFO_MESSAGE 303,"Objective complete"
"QUEST_TURNED_IN",
"SCENARIO_UPDATE",
"PLAYER_REGEN_ENABLED", -- pre spustenie funkcii outOfCombat
"COVENANT_CHOSEN", -- COVENANT_CALLINGS_UPDATED, GUILDBANK_UPDATE_WITHDRAWMONEY, TREASURE_PICKER_CACHE_FLUSH pre weekly update ak je player online pocas weekly resetu
"COVENANT_CALLINGS_UPDATED",
"ENCOUNTER_LOOT_RECEIVED", -- pre Trial of the element
}) do self:RegisterEvent(event) end
end