local GridStatus = Grid:GetModule("GridStatus"); local GridRoster = Grid:GetModule("GridRoster"); local GridFrame = Grid:GetModule("GridFrame"); -- local MapData = LibStub("LibMapData-1.0"); local APP = "GridStatusSmartHealing"; GridStatusSmartHealing = Grid:NewStatusModule(APP); GridStatusSmartHealing.menuName = "Smart Healing - by Tirds"; -- Timer used to measure time between updates local Timer = 0; -- Blank frame used to run OnUpdate local BlankFrame = CreateFrame("Frame"); local NumEnabled = 0; -- TODO make language files local function L(text) return text; end GridStatusSmartHealing.defaultDB = { debug = false, cycle = 0.2, } GridStatusSmartHealing.extraOptions = { ["frequency"] = { order = 101, type = "range", name = "Refresh time", desc = "Secounds between each refresh", width = "full", min = 0.01, max = 2, step = 0.01, get = function() return GridStatusSmartHealing.db.profile.cycle; end, set = function(info, v) GridStatusSmartHealing.db.profile.cycle = v; end }, --[[ ["test"] = { name = "test", order = 102, type = "toggle", width = "full", get = function() return false; end, set = function() print(GridStatusSmartHealing.statusModules); for key, value in pairs(GridStatusSmartHealing.statusModules) do print(key, " = ", value); end end } ]] } GridStatusSmartHealing.statusModules = {}; -- module stuff GridStatusSmartHealing.modulePrototype = GridStatus.modulePrototype; GridStatusSmartHealing:SetDefaultModulePrototype(GridStatusSmartHealing.modulePrototype); function GridStatusSmartHealing:RegisterStatus(module, status, desc, options, inMainMenu, order) GridStatus:RegisterStatus(status, desc, module.moduleName or true); options["enabled"] = { name = L("Enable"), desc = string.format(L("Enable %s"), desc), order = 10, width = "full", type = "toggle", get = function() return module.db.profile.enable; end, set = function(info, v) module.db.profile.enable = v; if (v) then if (module["OnStatusEnable"]) then module:OnStatusEnable(status); end else if (module["OnStatusDisable"]) then module:OnStatusDisable(status); end end end }; options["color"] = { name = L("Color"), desc = string.format(L("Color for %s"), desc), order = 20, type = "color", hasAlpha = true, get = function() local color = module.db.profile.color; return color.r, color.g, color.b, color.a; end, set = function(_, r, g, b, a) local color = module.db.profile.color; color.r = r; color.g = g; color.b = b; color.a = a or 1; end, }; options["priority"] = { name = L("Priority"), desc = string.format(L("Priority for %s"), desc), order = 30, type = "range", max = 99, min = 0, step = 1, get = function() return module.db.profile.priority end, set = function(_, v) module.db.profile.priority = v end, }; GridStatusSmartHealing.options.args[desc] = { type = "group", name = desc, desc = string.format(L("Options for %s"), desc), args = options, }; end function GridStatusSmartHealing:PostInitialize() -- Do now so modulePrototype can register Options for modules self:InitializeOptions(); end function GridStatusSmartHealing:PostEnable() for name, statusModule in pairs(self.statusModules) do if (self:Enabled(statusModule)) then statusModule:OnStatusEnable(nil);---------------- NumEnabled = NumEnabled + 1; end end if (NumEnabled > 0) then self:DoEnable(true); end end function GridStatusSmartHealing:IsEnabled() return NumEnabled > 0; end function GridStatusSmartHealing:DoEnable(force) if (NumEnabled > 0 and not force) then NumEnabled = NumEnabled + 1; return; end self:Debug("Enabling", self.moduleName); --[[ self:UpdateRoster(); self:RegisterEvent("PLAYER_MEMBERS_CHANGED", "UpdateRoster"); self:RegisterEvent("RAID_ROSTER_UPDATE", "UpdateRoster"); ]] --GridRoster:RegisterMessage("Grid_RosterUpdated"); BlankFrame:SetScript("OnUpdate", function(_, timer) return self:OnUpdate(timer); end); -- todo loop modules and check enabled if (not force) then NumEnabled = 1; end -- self.state = { x = 0, y = 0, mapWidth = 0, mapHeight = 0, data = {}, }; end function GridStatusSmartHealing:DoDisable() if (NumEnabled == 0) then return; end NumEnabled = NumEnabled - 1; if (NumEnabled == 0) then self:Debug("Disabling", self.moduleName); BlankFrame:SetScript("OnUpdate", nil); end end function GridStatusSmartHealing:ClearAll() for name, statusModule in pairs(self.statusModules) do if (self:Enabled(statusModule) and statusModule['ClearAll']) then statusModule:ClearAll(statusModule); end end end function GridStatusSmartHealing:UpdateAll() for name, statusModule in pairs(self.statusModules) do if (self:Enabled(statusModule) and statusModule['Update']) then statusModule:Update(); end end end function GridStatusSmartHealing:OnUpdate(elapsed) Timer = Timer + elapsed; if (NumEnabled == 0) then self:Debug("Nothing is Enabled to Update"); return; end if (Timer >= self.db.profile.cycle) then Timer = 0; --self:UpdateRoster(); if (self:UpdateMap()) then self:UpdateData(); self:UpdateAll(); else SetMapToCurrentZone(); self:Debug("Update Map Failed"); self:ClearAll(); end end end function GridStatusSmartHealing:GetUnitInfo(guid) return self.state.data[guid]; end function GridStatusSmartHealing:UpdateData() self.state.data = {}; self.state.x = self.state.x * self.state.mapWidth; self.state.y = self.state.y * self.state.mapHeight; for _guid, _unitId in GridRoster:IterateRoster() do local unitX, unitY = GetPlayerMapPosition(_unitId); if (unitX ~= 0 or unitY ~= 0 and self:IsValidHealTarget(_unitId)) then local health = UnitHealth(_unitId); local maxHealth = UnitHealthMax(_unitId); self.state.data[_guid] = { unitId = _unitId, guid = _guid, x = unitX * self.state.mapWidth, y = unitY * self.state.mapHeight, health = health, maxHealth = maxHealth, missingHealth = maxHealth - health, percent = maxHealth / health, }; end end end function GridStatusSmartHealing:UpdateMap() self.state.x, self.state.y = GetPlayerMapPosition('player'); if (self.state.x <= 0 or self.state.y <= 0) then return false; end local fileName = GetMapInfo(); local currentLevel = GetCurrentMapDungeonLevel(); self.state.mapWidth, self.state.mapHeight = MapData:MapArea(fileName, currentLevel); if (self.state.mapWidth ~= 0 and self.state.mapHeight ~= 0) then return true; end return false; end --[[ -- Now using GridRoster function GridStatusSmartHealing:Grid_RosterUpdated() self.roster = { [1] = {}, [2] = {}, [3] = {}, [4] = {}, [5] = {}, [6] = {}, [7] = {}, [8] = {} }; local RaidMemberNum = GetNumGroupMembers(); if (IsInRaid() == false) then tinsert(self.roster[1], "player"); player_group = 1; for i = 1, 4 do local unitid = "party" .. i; if UnitExists(unitid) then tinsert(self.roster[1], unitid); end end else for i = 1, RaidMemberNum do local name, _, group = GetRaidRosterInfo(i); local unitid = "raid" .. i; if (name and UnitExists(unitid)) then tinsert(self.roster[group], unitid) if (UnitIsUnit("player", unitid)) then player_group = group; end end end end end ]] function GridStatusSmartHealing:Enabled(statusModule) return statusModule.db.profile.enable; end function GridStatusSmartHealing:Distance(p1, p2) local x = p2.x - p1.x; local y = p2.y - p1.y; return x*x + y*y; end function GridStatusSmartHealing:HasGlyph(glyph_id) for i = 1, 9 do local _, _, _, id = GetGlyphSocketInfo(i); if (id and glyph_id == id) then return true; end end return false; end function GridStatusSmartHealing:IsValidHealTarget(unitId) return not UnitIsDeadOrGhost(unitId) and UnitIsConnected(unitId) and UnitIsVisible(unitId) and not (UnitIsCharmed(unitId) and UnitIsEnemy("player", unitId)); end function GridStatusSmartHealing:NewModule(name) local statusModule = Grid:NewStatusModule(name); GridStatusSmartHealing.statusModules[statusModule.name] = statusModule; return statusModule; end