first Details commit

This commit is contained in:
Tercio
2013-08-09 13:46:47 -03:00
commit aa5db1ee19
304 changed files with 51003 additions and 0 deletions
+91
View File
@@ -0,0 +1,91 @@
## Interface: 50300
## Title: Details
## Notes: Computes detailed infos about combats.
## SavedVariables: _detalhes_global
## SavedVariablesPerCharacter: _detalhes_database
## OptionalDeps: Ace3, LibSharedMedia-3.0, LibBossIDs-1.0, LibGraph-2.0, !ClassColors
#@no-lib-strip@
embeds.xml
#@end-no-lib-strip@
locales\Details-ptBR.lua
locales\Details-enUS.lua
boot.lua
core\util.lua
functions\boss.lua
functions\spells.lua
functions\events.lua
functions\classes.lua
functions\buff.lua
functions\link.lua
functions\spellcache.lua
functions\attributes.lua
functions\savedata.lua
functions\slash.lua
functions\playerclass.lua
functions\timedata.lua
functions\report.lua
core\timemachine.lua
framework\framework.lua
framework\colors.lua
framework\label.lua
framework\slider.lua
framework\picture.lua
framework\cooltip.xml
framework\textentry.xml
framework\panel.xml
framework\normal_bar.xml
framework\split_bar.xml
framework\button.xml
framework\dropdown.xml
framework\pictureedit.lua
gumps\anime.lua
gumps\anime.xml
gumps\janela_copy.lua
gumps\janela_options.lua
gumps\janela_info.lua
gumps\janela_report.lua
gumps\janela_principal.lua
gumps\janela_custom.lua
gumps\fw_mods.lua
gumps\switch.lua
gumps\toolbar_button.xml
classes\classe_error.lua
classes\classe_combate.lua
classes\classe_damage.lua
classes\classe_damage_habilidade.lua
classes\classe_heal.lua
classes\classe_heal_habilidade.lua
classes\classe_energy.lua
classes\classe_energy_habilidade.lua
classes\classe_others.lua
classes\classe_others_habilidade.lua
classes\classe_instancia.lua
classes\classe_target.lua
classes\classe_custom.lua
core\control.lua
classes\container_combatentes.lua
classes\container_habilidades.lua
classes\container_historico.lua
classes\container_pets.lua
core\plugins.lua
core\plugins_toolbar.lua
core\plugins_statusbar.lua
core\plugins_raid.lua
core\plugins_solo.lua
core\gears.lua
core\windows.lua
core\meta.lua
core\parser.lua
startup.lua
+17
View File
@@ -0,0 +1,17 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\..\FrameXML\UI.xsd">
<Frame name="_detalhes_listener">
<Scripts>
<OnLoad>
self:RegisterEvent ("ADDON_LOADED");
self:RegisterEvent ("PLAYER_LOGOUT");
</OnLoad>
<OnEvent>
_detalhes.OnEvent (self, event, ...);
</OnEvent>
</Scripts>
</Frame>
</Ui>
+659
View File
@@ -0,0 +1,659 @@
--- **AceAddon-3.0** provides a template for creating addon objects.
-- It'll provide you with a set of callback functions that allow you to simplify the loading
-- process of your addon.\\
-- Callbacks provided are:\\
-- * **OnInitialize**, which is called directly after the addon is fully loaded.
-- * **OnEnable** which gets called during the PLAYER_LOGIN event, when most of the data provided by the game is already present.
-- * **OnDisable**, which is only called when your addon is manually being disabled.
-- @usage
-- -- A small (but complete) addon, that doesn't do anything,
-- -- but shows usage of the callbacks.
-- local MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon")
--
-- function MyAddon:OnInitialize()
-- -- do init tasks here, like loading the Saved Variables,
-- -- or setting up slash commands.
-- end
--
-- function MyAddon:OnEnable()
-- -- Do more initialization here, that really enables the use of your addon.
-- -- Register Events, Hook functions, Create Frames, Get information from
-- -- the game that wasn't available in OnInitialize
-- end
--
-- function MyAddon:OnDisable()
-- -- Unhook, Unregister Events, Hide frames that you created.
-- -- You would probably only use an OnDisable if you want to
-- -- build a "standby" mode, or be able to toggle modules on/off.
-- end
-- @class file
-- @name AceAddon-3.0.lua
-- @release $Id: AceAddon-3.0.lua 1036 2011-08-16 22:45:05Z nevcairiel $
local MAJOR, MINOR = "AceAddon-3.0", 11
local AceAddon, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
if not AceAddon then return end -- No Upgrade needed.
AceAddon.frame = AceAddon.frame or CreateFrame("Frame", "AceAddon30Frame") -- Our very own frame
AceAddon.addons = AceAddon.addons or {} -- addons in general
AceAddon.statuses = AceAddon.statuses or {} -- statuses of addon.
AceAddon.initializequeue = AceAddon.initializequeue or {} -- addons that are new and not initialized
AceAddon.enablequeue = AceAddon.enablequeue or {} -- addons that are initialized and waiting to be enabled
AceAddon.embeds = AceAddon.embeds or setmetatable({}, {__index = function(tbl, key) tbl[key] = {} return tbl[key] end }) -- contains a list of libraries embedded in an addon
-- Lua APIs
local tinsert, tconcat, tremove = table.insert, table.concat, table.remove
local fmt, tostring = string.format, tostring
local select, pairs, next, type, unpack = select, pairs, next, type, unpack
local loadstring, assert, error = loadstring, assert, error
local setmetatable, getmetatable, rawset, rawget = setmetatable, getmetatable, rawset, rawget
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
-- List them here for Mikk's FindGlobals script
-- GLOBALS: LibStub, IsLoggedIn, geterrorhandler
--[[
xpcall safecall implementation
]]
local xpcall = xpcall
local function errorhandler(err)
return geterrorhandler()(err)
end
local function CreateDispatcher(argCount)
local code = [[
local xpcall, eh = ...
local method, ARGS
local function call() return method(ARGS) end
local function dispatch(func, ...)
method = func
if not method then return end
ARGS = ...
return xpcall(call, eh)
end
return dispatch
]]
local ARGS = {}
for i = 1, argCount do ARGS[i] = "arg"..i end
code = code:gsub("ARGS", tconcat(ARGS, ", "))
return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(xpcall, errorhandler)
end
local Dispatchers = setmetatable({}, {__index=function(self, argCount)
local dispatcher = CreateDispatcher(argCount)
rawset(self, argCount, dispatcher)
return dispatcher
end})
Dispatchers[0] = function(func)
return xpcall(func, errorhandler)
end
local function safecall(func, ...)
-- we check to see if the func is passed is actually a function here and don't error when it isn't
-- this safecall is used for optional functions like OnInitialize OnEnable etc. When they are not
-- present execution should continue without hinderance
if type(func) == "function" then
return Dispatchers[select('#', ...)](func, ...)
end
end
-- local functions that will be implemented further down
local Enable, Disable, EnableModule, DisableModule, Embed, NewModule, GetModule, GetName, SetDefaultModuleState, SetDefaultModuleLibraries, SetEnabledState, SetDefaultModulePrototype
-- used in the addon metatable
local function addontostring( self ) return self.name end
--- Create a new AceAddon-3.0 addon.
-- Any libraries you specified will be embeded, and the addon will be scheduled for
-- its OnInitialize and OnEnable callbacks.
-- The final addon object, with all libraries embeded, will be returned.
-- @paramsig [object ,]name[, lib, ...]
-- @param object Table to use as a base for the addon (optional)
-- @param name Name of the addon object to create
-- @param lib List of libraries to embed into the addon
-- @usage
-- -- Create a simple addon object
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon", "AceEvent-3.0")
--
-- -- Create a Addon object based on the table of a frame
-- local MyFrame = CreateFrame("Frame")
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon(MyFrame, "MyAddon", "AceEvent-3.0")
function AceAddon:NewAddon(objectorname, ...)
local object,name
local i=1
if type(objectorname)=="table" then
object=objectorname
name=...
i=2
else
name=objectorname
end
if type(name)~="string" then
error(("Usage: NewAddon([object,] name, [lib, lib, lib, ...]): 'name' - string expected got '%s'."):format(type(name)), 2)
end
if self.addons[name] then
error(("Usage: NewAddon([object,] name, [lib, lib, lib, ...]): 'name' - Addon '%s' already exists."):format(name), 2)
end
object = object or {}
object.name = name
local addonmeta = {}
local oldmeta = getmetatable(object)
if oldmeta then
for k, v in pairs(oldmeta) do addonmeta[k] = v end
end
addonmeta.__tostring = addontostring
setmetatable( object, addonmeta )
self.addons[name] = object
object.modules = {}
object.orderedModules = {}
object.defaultModuleLibraries = {}
Embed( object ) -- embed NewModule, GetModule methods
self:EmbedLibraries(object, select(i,...))
-- add to queue of addons to be initialized upon ADDON_LOADED
tinsert(self.initializequeue, object)
return object
end
--- Get the addon object by its name from the internal AceAddon registry.
-- Throws an error if the addon object cannot be found (except if silent is set).
-- @param name unique name of the addon object
-- @param silent if true, the addon is optional, silently return nil if its not found
-- @usage
-- -- Get the Addon
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
function AceAddon:GetAddon(name, silent)
if not silent and not self.addons[name] then
error(("Usage: GetAddon(name): 'name' - Cannot find an AceAddon '%s'."):format(tostring(name)), 2)
end
return self.addons[name]
end
-- - Embed a list of libraries into the specified addon.
-- This function will try to embed all of the listed libraries into the addon
-- and error if a single one fails.
--
-- **Note:** This function is for internal use by :NewAddon/:NewModule
-- @paramsig addon, [lib, ...]
-- @param addon addon object to embed the libs in
-- @param lib List of libraries to embed into the addon
function AceAddon:EmbedLibraries(addon, ...)
for i=1,select("#", ... ) do
local libname = select(i, ...)
self:EmbedLibrary(addon, libname, false, 4)
end
end
-- - Embed a library into the addon object.
-- This function will check if the specified library is registered with LibStub
-- and if it has a :Embed function to call. It'll error if any of those conditions
-- fails.
--
-- **Note:** This function is for internal use by :EmbedLibraries
-- @paramsig addon, libname[, silent[, offset]]
-- @param addon addon object to embed the library in
-- @param libname name of the library to embed
-- @param silent marks an embed to fail silently if the library doesn't exist (optional)
-- @param offset will push the error messages back to said offset, defaults to 2 (optional)
function AceAddon:EmbedLibrary(addon, libname, silent, offset)
local lib = LibStub:GetLibrary(libname, true)
if not lib and not silent then
error(("Usage: EmbedLibrary(addon, libname, silent, offset): 'libname' - Cannot find a library instance of %q."):format(tostring(libname)), offset or 2)
elseif lib and type(lib.Embed) == "function" then
lib:Embed(addon)
tinsert(self.embeds[addon], libname)
return true
elseif lib then
error(("Usage: EmbedLibrary(addon, libname, silent, offset): 'libname' - Library '%s' is not Embed capable"):format(libname), offset or 2)
end
end
--- Return the specified module from an addon object.
-- Throws an error if the addon object cannot be found (except if silent is set)
-- @name //addon//:GetModule
-- @paramsig name[, silent]
-- @param name unique name of the module
-- @param silent if true, the module is optional, silently return nil if its not found (optional)
-- @usage
-- -- Get the Addon
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
-- -- Get the Module
-- MyModule = MyAddon:GetModule("MyModule")
function GetModule(self, name, silent)
if not self.modules[name] and not silent then
error(("Usage: GetModule(name, silent): 'name' - Cannot find module '%s'."):format(tostring(name)), 2)
end
return self.modules[name]
end
local function IsModuleTrue(self) return true end
--- Create a new module for the addon.
-- The new module can have its own embeded libraries and/or use a module prototype to be mixed into the module.\\
-- A module has the same functionality as a real addon, it can have modules of its own, and has the same API as
-- an addon object.
-- @name //addon//:NewModule
-- @paramsig name[, prototype|lib[, lib, ...]]
-- @param name unique name of the module
-- @param prototype object to derive this module from, methods and values from this table will be mixed into the module (optional)
-- @param lib List of libraries to embed into the addon
-- @usage
-- -- Create a module with some embeded libraries
-- MyModule = MyAddon:NewModule("MyModule", "AceEvent-3.0", "AceHook-3.0")
--
-- -- Create a module with a prototype
-- local prototype = { OnEnable = function(self) print("OnEnable called!") end }
-- MyModule = MyAddon:NewModule("MyModule", prototype, "AceEvent-3.0", "AceHook-3.0")
function NewModule(self, name, prototype, ...)
if type(name) ~= "string" then error(("Usage: NewModule(name, [prototype, [lib, lib, lib, ...]): 'name' - string expected got '%s'."):format(type(name)), 2) end
if type(prototype) ~= "string" and type(prototype) ~= "table" and type(prototype) ~= "nil" then error(("Usage: NewModule(name, [prototype, [lib, lib, lib, ...]): 'prototype' - table (prototype), string (lib) or nil expected got '%s'."):format(type(prototype)), 2) end
if self.modules[name] then error(("Usage: NewModule(name, [prototype, [lib, lib, lib, ...]): 'name' - Module '%s' already exists."):format(name), 2) end
-- modules are basically addons. We treat them as such. They will be added to the initializequeue properly as well.
-- NewModule can only be called after the parent addon is present thus the modules will be initialized after their parent is.
local module = AceAddon:NewAddon(fmt("%s_%s", self.name or tostring(self), name))
module.IsModule = IsModuleTrue
module:SetEnabledState(self.defaultModuleState)
module.moduleName = name
if type(prototype) == "string" then
AceAddon:EmbedLibraries(module, prototype, ...)
else
AceAddon:EmbedLibraries(module, ...)
end
AceAddon:EmbedLibraries(module, unpack(self.defaultModuleLibraries))
if not prototype or type(prototype) == "string" then
prototype = self.defaultModulePrototype or nil
end
if type(prototype) == "table" then
local mt = getmetatable(module)
mt.__index = prototype
setmetatable(module, mt) -- More of a Base class type feel.
end
safecall(self.OnModuleCreated, self, module) -- Was in Ace2 and I think it could be a cool thing to have handy.
self.modules[name] = module
tinsert(self.orderedModules, module)
return module
end
--- Returns the real name of the addon or module, without any prefix.
-- @name //addon//:GetName
-- @paramsig
-- @usage
-- print(MyAddon:GetName())
-- -- prints "MyAddon"
function GetName(self)
return self.moduleName or self.name
end
--- Enables the Addon, if possible, return true or false depending on success.
-- This internally calls AceAddon:EnableAddon(), thus dispatching a OnEnable callback
-- and enabling all modules of the addon (unless explicitly disabled).\\
-- :Enable() also sets the internal `enableState` variable to true
-- @name //addon//:Enable
-- @paramsig
-- @usage
-- -- Enable MyModule
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
-- MyModule = MyAddon:GetModule("MyModule")
-- MyModule:Enable()
function Enable(self)
self:SetEnabledState(true)
return AceAddon:EnableAddon(self)
end
--- Disables the Addon, if possible, return true or false depending on success.
-- This internally calls AceAddon:DisableAddon(), thus dispatching a OnDisable callback
-- and disabling all modules of the addon.\\
-- :Disable() also sets the internal `enableState` variable to false
-- @name //addon//:Disable
-- @paramsig
-- @usage
-- -- Disable MyAddon
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
-- MyAddon:Disable()
function Disable(self)
self:SetEnabledState(false)
return AceAddon:DisableAddon(self)
end
--- Enables the Module, if possible, return true or false depending on success.
-- Short-hand function that retrieves the module via `:GetModule` and calls `:Enable` on the module object.
-- @name //addon//:EnableModule
-- @paramsig name
-- @usage
-- -- Enable MyModule using :GetModule
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
-- MyModule = MyAddon:GetModule("MyModule")
-- MyModule:Enable()
--
-- -- Enable MyModule using the short-hand
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
-- MyAddon:EnableModule("MyModule")
function EnableModule(self, name)
local module = self:GetModule( name )
return module:Enable()
end
--- Disables the Module, if possible, return true or false depending on success.
-- Short-hand function that retrieves the module via `:GetModule` and calls `:Disable` on the module object.
-- @name //addon//:DisableModule
-- @paramsig name
-- @usage
-- -- Disable MyModule using :GetModule
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
-- MyModule = MyAddon:GetModule("MyModule")
-- MyModule:Disable()
--
-- -- Disable MyModule using the short-hand
-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
-- MyAddon:DisableModule("MyModule")
function DisableModule(self, name)
local module = self:GetModule( name )
return module:Disable()
end
--- Set the default libraries to be mixed into all modules created by this object.
-- Note that you can only change the default module libraries before any module is created.
-- @name //addon//:SetDefaultModuleLibraries
-- @paramsig lib[, lib, ...]
-- @param lib List of libraries to embed into the addon
-- @usage
-- -- Create the addon object
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon")
-- -- Configure default libraries for modules (all modules need AceEvent-3.0)
-- MyAddon:SetDefaultModuleLibraries("AceEvent-3.0")
-- -- Create a module
-- MyModule = MyAddon:NewModule("MyModule")
function SetDefaultModuleLibraries(self, ...)
if next(self.modules) then
error("Usage: SetDefaultModuleLibraries(...): cannot change the module defaults after a module has been registered.", 2)
end
self.defaultModuleLibraries = {...}
end
--- Set the default state in which new modules are being created.
-- Note that you can only change the default state before any module is created.
-- @name //addon//:SetDefaultModuleState
-- @paramsig state
-- @param state Default state for new modules, true for enabled, false for disabled
-- @usage
-- -- Create the addon object
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon")
-- -- Set the default state to "disabled"
-- MyAddon:SetDefaultModuleState(false)
-- -- Create a module and explicilty enable it
-- MyModule = MyAddon:NewModule("MyModule")
-- MyModule:Enable()
function SetDefaultModuleState(self, state)
if next(self.modules) then
error("Usage: SetDefaultModuleState(state): cannot change the module defaults after a module has been registered.", 2)
end
self.defaultModuleState = state
end
--- Set the default prototype to use for new modules on creation.
-- Note that you can only change the default prototype before any module is created.
-- @name //addon//:SetDefaultModulePrototype
-- @paramsig prototype
-- @param prototype Default prototype for the new modules (table)
-- @usage
-- -- Define a prototype
-- local prototype = { OnEnable = function(self) print("OnEnable called!") end }
-- -- Set the default prototype
-- MyAddon:SetDefaultModulePrototype(prototype)
-- -- Create a module and explicitly Enable it
-- MyModule = MyAddon:NewModule("MyModule")
-- MyModule:Enable()
-- -- should print "OnEnable called!" now
-- @see NewModule
function SetDefaultModulePrototype(self, prototype)
if next(self.modules) then
error("Usage: SetDefaultModulePrototype(prototype): cannot change the module defaults after a module has been registered.", 2)
end
if type(prototype) ~= "table" then
error(("Usage: SetDefaultModulePrototype(prototype): 'prototype' - table expected got '%s'."):format(type(prototype)), 2)
end
self.defaultModulePrototype = prototype
end
--- Set the state of an addon or module
-- This should only be called before any enabling actually happend, e.g. in/before OnInitialize.
-- @name //addon//:SetEnabledState
-- @paramsig state
-- @param state the state of an addon or module (enabled=true, disabled=false)
function SetEnabledState(self, state)
self.enabledState = state
end
--- Return an iterator of all modules associated to the addon.
-- @name //addon//:IterateModules
-- @paramsig
-- @usage
-- -- Enable all modules
-- for name, module in MyAddon:IterateModules() do
-- module:Enable()
-- end
local function IterateModules(self) return pairs(self.modules) end
-- Returns an iterator of all embeds in the addon
-- @name //addon//:IterateEmbeds
-- @paramsig
local function IterateEmbeds(self) return pairs(AceAddon.embeds[self]) end
--- Query the enabledState of an addon.
-- @name //addon//:IsEnabled
-- @paramsig
-- @usage
-- if MyAddon:IsEnabled() then
-- MyAddon:Disable()
-- end
local function IsEnabled(self) return self.enabledState end
local mixins = {
NewModule = NewModule,
GetModule = GetModule,
Enable = Enable,
Disable = Disable,
EnableModule = EnableModule,
DisableModule = DisableModule,
IsEnabled = IsEnabled,
SetDefaultModuleLibraries = SetDefaultModuleLibraries,
SetDefaultModuleState = SetDefaultModuleState,
SetDefaultModulePrototype = SetDefaultModulePrototype,
SetEnabledState = SetEnabledState,
IterateModules = IterateModules,
IterateEmbeds = IterateEmbeds,
GetName = GetName,
}
local function IsModule(self) return false end
local pmixins = {
defaultModuleState = true,
enabledState = true,
IsModule = IsModule,
}
-- Embed( target )
-- target (object) - target object to embed aceaddon in
--
-- this is a local function specifically since it's meant to be only called internally
function Embed(target, skipPMixins)
for k, v in pairs(mixins) do
target[k] = v
end
if not skipPMixins then
for k, v in pairs(pmixins) do
target[k] = target[k] or v
end
end
end
-- - Initialize the addon after creation.
-- This function is only used internally during the ADDON_LOADED event
-- It will call the **OnInitialize** function on the addon object (if present),
-- and the **OnEmbedInitialize** function on all embeded libraries.
--
-- **Note:** Do not call this function manually, unless you're absolutely sure that you know what you are doing.
-- @param addon addon object to intialize
function AceAddon:InitializeAddon(addon)
safecall(addon.OnInitialize, addon)
local embeds = self.embeds[addon]
for i = 1, #embeds do
local lib = LibStub:GetLibrary(embeds[i], true)
if lib then safecall(lib.OnEmbedInitialize, lib, addon) end
end
-- we don't call InitializeAddon on modules specifically, this is handled
-- from the event handler and only done _once_
end
-- - Enable the addon after creation.
-- Note: This function is only used internally during the PLAYER_LOGIN event, or during ADDON_LOADED,
-- if IsLoggedIn() already returns true at that point, e.g. for LoD Addons.
-- It will call the **OnEnable** function on the addon object (if present),
-- and the **OnEmbedEnable** function on all embeded libraries.\\
-- This function does not toggle the enable state of the addon itself, and will return early if the addon is disabled.
--
-- **Note:** Do not call this function manually, unless you're absolutely sure that you know what you are doing.
-- Use :Enable on the addon itself instead.
-- @param addon addon object to enable
function AceAddon:EnableAddon(addon)
if type(addon) == "string" then addon = AceAddon:GetAddon(addon) end
if self.statuses[addon.name] or not addon.enabledState then return false end
-- set the statuses first, before calling the OnEnable. this allows for Disabling of the addon in OnEnable.
self.statuses[addon.name] = true
safecall(addon.OnEnable, addon)
-- make sure we're still enabled before continueing
if self.statuses[addon.name] then
local embeds = self.embeds[addon]
for i = 1, #embeds do
local lib = LibStub:GetLibrary(embeds[i], true)
if lib then safecall(lib.OnEmbedEnable, lib, addon) end
end
-- enable possible modules.
local modules = addon.orderedModules
for i = 1, #modules do
self:EnableAddon(modules[i])
end
end
return self.statuses[addon.name] -- return true if we're disabled
end
-- - Disable the addon
-- Note: This function is only used internally.
-- It will call the **OnDisable** function on the addon object (if present),
-- and the **OnEmbedDisable** function on all embeded libraries.\\
-- This function does not toggle the enable state of the addon itself, and will return early if the addon is still enabled.
--
-- **Note:** Do not call this function manually, unless you're absolutely sure that you know what you are doing.
-- Use :Disable on the addon itself instead.
-- @param addon addon object to enable
function AceAddon:DisableAddon(addon)
if type(addon) == "string" then addon = AceAddon:GetAddon(addon) end
if not self.statuses[addon.name] then return false end
-- set statuses first before calling OnDisable, this allows for aborting the disable in OnDisable.
self.statuses[addon.name] = false
safecall( addon.OnDisable, addon )
-- make sure we're still disabling...
if not self.statuses[addon.name] then
local embeds = self.embeds[addon]
for i = 1, #embeds do
local lib = LibStub:GetLibrary(embeds[i], true)
if lib then safecall(lib.OnEmbedDisable, lib, addon) end
end
-- disable possible modules.
local modules = addon.orderedModules
for i = 1, #modules do
self:DisableAddon(modules[i])
end
end
return not self.statuses[addon.name] -- return true if we're disabled
end
--- Get an iterator over all registered addons.
-- @usage
-- -- Print a list of all installed AceAddon's
-- for name, addon in AceAddon:IterateAddons() do
-- print("Addon: " .. name)
-- end
function AceAddon:IterateAddons() return pairs(self.addons) end
--- Get an iterator over the internal status registry.
-- @usage
-- -- Print a list of all enabled addons
-- for name, status in AceAddon:IterateAddonStatus() do
-- if status then
-- print("EnabledAddon: " .. name)
-- end
-- end
function AceAddon:IterateAddonStatus() return pairs(self.statuses) end
-- Following Iterators are deprecated, and their addon specific versions should be used
-- e.g. addon:IterateEmbeds() instead of :IterateEmbedsOnAddon(addon)
function AceAddon:IterateEmbedsOnAddon(addon) return pairs(self.embeds[addon]) end
function AceAddon:IterateModulesOfAddon(addon) return pairs(addon.modules) end
-- Event Handling
local function onEvent(this, event, arg1)
-- 2011-08-17 nevcairiel - ignore the load event of Blizzard_DebugTools, so a potential startup error isn't swallowed up
if (event == "ADDON_LOADED" and arg1 ~= "Blizzard_DebugTools") or event == "PLAYER_LOGIN" then
-- if a addon loads another addon, recursion could happen here, so we need to validate the table on every iteration
while(#AceAddon.initializequeue > 0) do
local addon = tremove(AceAddon.initializequeue, 1)
-- this might be an issue with recursion - TODO: validate
if event == "ADDON_LOADED" then addon.baseName = arg1 end
AceAddon:InitializeAddon(addon)
tinsert(AceAddon.enablequeue, addon)
end
if IsLoggedIn() then
while(#AceAddon.enablequeue > 0) do
local addon = tremove(AceAddon.enablequeue, 1)
AceAddon:EnableAddon(addon)
end
end
end
end
AceAddon.frame:RegisterEvent("ADDON_LOADED")
AceAddon.frame:RegisterEvent("PLAYER_LOGIN")
AceAddon.frame:SetScript("OnEvent", onEvent)
-- upgrade embeded
for name, addon in pairs(AceAddon.addons) do
Embed(addon, true)
end
-- 2010-10-27 nevcairiel - add new "orderedModules" table
if oldminor and oldminor < 10 then
for name, addon in pairs(AceAddon.addons) do
addon.orderedModules = {}
for module_name, module in pairs(addon.modules) do
tinsert(addon.orderedModules, module)
end
end
end
@@ -0,0 +1,4 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="AceAddon-3.0.lua"/>
</Ui>
+382
View File
@@ -0,0 +1,382 @@
--- **AceComm-3.0** allows you to send messages of unlimited length over the addon comm channels.
-- It'll automatically split the messages into multiple parts and rebuild them on the receiving end.\\
-- **ChatThrottleLib** is of course being used to avoid being disconnected by the server.
--
-- **AceComm-3.0** can be embeded into your addon, either explicitly by calling AceComm:Embed(MyAddon) or by
-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
-- and can be accessed directly, without having to explicitly call AceComm itself.\\
-- It is recommended to embed AceComm, otherwise you'll have to specify a custom `self` on all calls you
-- make into AceComm.
-- @class file
-- @name AceComm-3.0
-- @release $Id: AceComm-3.0.lua 1019 2011-03-27 12:08:33Z mikk $
--[[ AceComm-3.0
TODO: Time out old data rotting around from dead senders? Not a HUGE deal since the number of possible sender names is somewhat limited.
]]
local MAJOR, MINOR = "AceComm-3.0", 7
local AceComm,oldminor = LibStub:NewLibrary(MAJOR, MINOR)
if not AceComm then return end
local CallbackHandler = LibStub:GetLibrary("CallbackHandler-1.0")
local CTL = assert(ChatThrottleLib, "AceComm-3.0 requires ChatThrottleLib")
-- Lua APIs
local type, next, pairs, tostring = type, next, pairs, tostring
local strsub, strfind = string.sub, string.find
local match = string.match
local tinsert, tconcat = table.insert, table.concat
local error, assert = error, assert
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
-- List them here for Mikk's FindGlobals script
-- GLOBALS: LibStub, DEFAULT_CHAT_FRAME, geterrorhandler, RegisterAddonMessagePrefix
AceComm.embeds = AceComm.embeds or {}
-- for my sanity and yours, let's give the message type bytes some names
local MSG_MULTI_FIRST = "\001"
local MSG_MULTI_NEXT = "\002"
local MSG_MULTI_LAST = "\003"
local MSG_ESCAPE = "\004"
if not RegisterAddonMessagePrefix then
AceComm.multipart_origprefixes = AceComm.multipart_origprefixes or {} -- e.g. "Prefix\001"="Prefix", "Prefix\002"="Prefix"
AceComm.multipart_reassemblers = AceComm.multipart_reassemblers or {} -- e.g. "Prefix\001"="OnReceiveMultipartFirst"
else
AceComm.multipart_origprefixes = nil
AceComm.multipart_reassemblers = nil
end
-- the multipart message spool: indexed by a combination of sender+distribution+
AceComm.multipart_spool = AceComm.multipart_spool or {}
--- Register for Addon Traffic on a specified prefix
-- @param prefix A printable character (\032-\255) classification of the message (typically AddonName or AddonNameEvent), max 16 characters
-- @param method Callback to call on message reception: Function reference, or method name (string) to call on self. Defaults to "OnCommReceived"
function AceComm:RegisterComm(prefix, method)
if method == nil then
method = "OnCommReceived"
end
if RegisterAddonMessagePrefix then
if #prefix>16 then -- TODO: 15?
error("AceComm:RegisterComm(prefix,method): prefix length is limited to 16 characters")
end
RegisterAddonMessagePrefix(prefix)
end
return AceComm._RegisterComm(self, prefix, method) -- created by CallbackHandler
end
local warnedPrefix=false
--- Send a message over the Addon Channel
-- @param prefix A printable character (\032-\255) classification of the message (typically AddonName or AddonNameEvent)
-- @param text Data to send, nils (\000) not allowed. Any length.
-- @param distribution Addon channel, e.g. "RAID", "GUILD", etc; see SendAddonMessage API
-- @param target Destination for some distributions; see SendAddonMessage API
-- @param prio OPTIONAL: ChatThrottleLib priority, "BULK", "NORMAL" or "ALERT". Defaults to "NORMAL".
-- @param callbackFn OPTIONAL: callback function to be called as each chunk is sent. receives 3 args: the user supplied arg (see next), the number of bytes sent so far, and the number of bytes total to send.
-- @param callbackArg: OPTIONAL: first arg to the callback function. nil will be passed if not specified.
function AceComm:SendCommMessage(prefix, text, distribution, target, prio, callbackFn, callbackArg)
prio = prio or "NORMAL" -- pasta's reference implementation had different prio for singlepart and multipart, but that's a very bad idea since that can easily lead to out-of-sequence delivery!
if not( type(prefix)=="string" and
type(text)=="string" and
type(distribution)=="string" and
(target==nil or type(target)=="string") and
(prio=="BULK" or prio=="NORMAL" or prio=="ALERT")
) then
error('Usage: SendCommMessage(addon, "prefix", "text", "distribution"[, "target"[, "prio"[, callbackFn, callbackarg]]])', 2)
end
if not RegisterAddonMessagePrefix then
if strfind(prefix, "[\001-\009]") then
if strfind(prefix, "[\001-\003]") then
error("SendCommMessage: Characters \\001--\\003 in prefix are reserved for AceComm metadata", 2)
elseif not warnedPrefix then
-- I have some ideas about future extensions that require more control characters /mikk, 20090808
geterrorhandler()("SendCommMessage: Heads-up developers: Characters \\004--\\009 in prefix are reserved for AceComm future extension")
warnedPrefix = true
end
end
end
local textlen = #text
local maxtextlen;
if not RegisterAddonMessagePrefix then
maxtextlen = 254 - #prefix -- 254 is the max length of prefix + text that can be sent in one message (there's an internal separator char)
else
maxtextlen = 255 -- Yes, the max is 255 even if the dev post said 256. I tested. Char 256+ get silently truncated. /Mikk, 20110327
end
local queueName = prefix..distribution..(target or "")
local ctlCallback = nil
if callbackFn then
ctlCallback = function(sent)
return callbackFn(callbackArg, sent, textlen)
end
end
local forceMultipart
if RegisterAddonMessagePrefix and match(text, "^[\001-\009]") then -- 4.1+: see if the first character is a control character
-- we need to escape the first character with a \004
if textlen+1 > maxtextlen then -- would we go over the size limit?
forceMultipart = true -- just make it multipart, no escape problems then
else
text = "\004" .. text
end
end
if not forceMultipart and textlen <= maxtextlen then
-- fits all in one message
CTL:SendAddonMessage(prio, prefix, text, distribution, target, queueName, ctlCallback, textlen)
else
maxtextlen = maxtextlen - 1 -- 1 extra byte for part indicator in prefix(4.0)/start of message(4.1)
-- first part
local chunk = strsub(text, 1, maxtextlen)
if not RegisterAddonMessagePrefix then
CTL:SendAddonMessage(prio, prefix..MSG_MULTI_FIRST, chunk, distribution, target, queueName, ctlCallback, maxtextlen)
else
CTL:SendAddonMessage(prio, prefix, MSG_MULTI_FIRST..chunk, distribution, target, queueName, ctlCallback, maxtextlen)
end
-- continuation
local pos = 1+maxtextlen
while pos+maxtextlen <= textlen do
chunk = strsub(text, pos, pos+maxtextlen-1)
if not RegisterAddonMessagePrefix then
CTL:SendAddonMessage(prio, prefix..MSG_MULTI_NEXT, chunk, distribution, target, queueName, ctlCallback, pos+maxtextlen-1)
else
CTL:SendAddonMessage(prio, prefix, MSG_MULTI_NEXT..chunk, distribution, target, queueName, ctlCallback, pos+maxtextlen-1)
end
pos = pos + maxtextlen
end
-- final part
chunk = strsub(text, pos)
if not RegisterAddonMessagePrefix then
CTL:SendAddonMessage(prio, prefix..MSG_MULTI_LAST, chunk, distribution, target, queueName, ctlCallback, textlen)
else
CTL:SendAddonMessage(prio, prefix, MSG_MULTI_LAST..chunk, distribution, target, queueName, ctlCallback, textlen)
end
end
end
----------------------------------------
-- Message receiving
----------------------------------------
do
local compost = setmetatable({}, {__mode = "k"})
local function new()
local t = next(compost)
if t then
compost[t]=nil
for i=#t,3,-1 do -- faster than pairs loop. don't even nil out 1/2 since they'll be overwritten
t[i]=nil
end
return t
end
return {}
end
local function lostdatawarning(prefix,sender,where)
DEFAULT_CHAT_FRAME:AddMessage(MAJOR..": Warning: lost network data regarding '"..tostring(prefix).."' from '"..tostring(sender).."' (in "..where..")")
end
function AceComm:OnReceiveMultipartFirst(prefix, message, distribution, sender)
local key = prefix.."\t"..distribution.."\t"..sender -- a unique stream is defined by the prefix + distribution + sender
local spool = AceComm.multipart_spool
--[[
if spool[key] then
lostdatawarning(prefix,sender,"First")
-- continue and overwrite
end
--]]
spool[key] = message -- plain string for now
end
function AceComm:OnReceiveMultipartNext(prefix, message, distribution, sender)
local key = prefix.."\t"..distribution.."\t"..sender -- a unique stream is defined by the prefix + distribution + sender
local spool = AceComm.multipart_spool
local olddata = spool[key]
if not olddata then
--lostdatawarning(prefix,sender,"Next")
return
end
if type(olddata)~="table" then
-- ... but what we have is not a table. So make it one. (Pull a composted one if available)
local t = new()
t[1] = olddata -- add old data as first string
t[2] = message -- and new message as second string
spool[key] = t -- and put the table in the spool instead of the old string
else
tinsert(olddata, message)
end
end
function AceComm:OnReceiveMultipartLast(prefix, message, distribution, sender)
local key = prefix.."\t"..distribution.."\t"..sender -- a unique stream is defined by the prefix + distribution + sender
local spool = AceComm.multipart_spool
local olddata = spool[key]
if not olddata then
--lostdatawarning(prefix,sender,"End")
return
end
spool[key] = nil
if type(olddata) == "table" then
-- if we've received a "next", the spooled data will be a table for rapid & garbage-free tconcat
tinsert(olddata, message)
AceComm.callbacks:Fire(prefix, tconcat(olddata, ""), distribution, sender)
compost[olddata] = true
else
-- if we've only received a "first", the spooled data will still only be a string
AceComm.callbacks:Fire(prefix, olddata..message, distribution, sender)
end
end
end
----------------------------------------
-- Embed CallbackHandler
----------------------------------------
if not AceComm.callbacks then
AceComm.callbacks = CallbackHandler:New(AceComm,
"_RegisterComm",
"UnregisterComm",
"UnregisterAllComm")
end
local OnEvent
if not RegisterAddonMessagePrefix then -- 4.0: per-prefix callbacks per part type
function AceComm.callbacks:OnUsed(target, prefix)
AceComm.multipart_origprefixes[prefix..MSG_MULTI_FIRST] = prefix
AceComm.multipart_reassemblers[prefix..MSG_MULTI_FIRST] = "OnReceiveMultipartFirst"
AceComm.multipart_origprefixes[prefix..MSG_MULTI_NEXT] = prefix
AceComm.multipart_reassemblers[prefix..MSG_MULTI_NEXT] = "OnReceiveMultipartNext"
AceComm.multipart_origprefixes[prefix..MSG_MULTI_LAST] = prefix
AceComm.multipart_reassemblers[prefix..MSG_MULTI_LAST] = "OnReceiveMultipartLast"
end
function AceComm.callbacks:OnUnused(target, prefix)
AceComm.multipart_origprefixes[prefix..MSG_MULTI_FIRST] = nil
AceComm.multipart_reassemblers[prefix..MSG_MULTI_FIRST] = nil
AceComm.multipart_origprefixes[prefix..MSG_MULTI_NEXT] = nil
AceComm.multipart_reassemblers[prefix..MSG_MULTI_NEXT] = nil
AceComm.multipart_origprefixes[prefix..MSG_MULTI_LAST] = nil
AceComm.multipart_reassemblers[prefix..MSG_MULTI_LAST] = nil
end
function OnEvent(this, event, ...)
if event == "CHAT_MSG_ADDON" then
local prefix,message,distribution,sender = ...
local reassemblername = AceComm.multipart_reassemblers[prefix]
if reassemblername then
-- multipart: reassemble
local aceCommReassemblerFunc = AceComm[reassemblername]
local origprefix = AceComm.multipart_origprefixes[prefix]
aceCommReassemblerFunc(AceComm, origprefix, message, distribution, sender)
else
-- single part: fire it off immediately and let CallbackHandler decide if it's registered or not
AceComm.callbacks:Fire(prefix, message, distribution, sender)
end
else
assert(false, "Received "..tostring(event).." event?!")
end
end
else -- 4.1+: only one prefix for all
AceComm.callbacks.OnUsed = nil
AceComm.callbacks.OnUnused = nil
function OnEvent(this, event, ...)
if event == "CHAT_MSG_ADDON" then
local prefix,message,distribution,sender = ...
local control, rest = match(message, "^([\001-\009])(.*)")
if control then
if control==MSG_MULTI_FIRST then
AceComm:OnReceiveMultipartFirst(prefix, rest, distribution, sender)
elseif control==MSG_MULTI_NEXT then
AceComm:OnReceiveMultipartNext(prefix, rest, distribution, sender)
elseif control==MSG_MULTI_LAST then
AceComm:OnReceiveMultipartLast(prefix, rest, distribution, sender)
elseif control==MSG_ESCAPE then
AceComm.callbacks:Fire(prefix, rest, distribution, sender)
else
-- unknown control character, ignore SILENTLY (dont warn unnecessarily about future extensions!)
end
else
-- single part: fire it off immediately and let CallbackHandler decide if it's registered or not
AceComm.callbacks:Fire(prefix, message, distribution, sender)
end
else
assert(false, "Received "..tostring(event).." event?!")
end
end
end
AceComm.frame = AceComm.frame or CreateFrame("Frame", "AceComm30Frame")
AceComm.frame:SetScript("OnEvent", OnEvent)
AceComm.frame:UnregisterAllEvents()
AceComm.frame:RegisterEvent("CHAT_MSG_ADDON")
----------------------------------------
-- Base library stuff
----------------------------------------
local mixins = {
"RegisterComm",
"UnregisterComm",
"UnregisterAllComm",
"SendCommMessage",
}
-- Embeds AceComm-3.0 into the target object making the functions from the mixins list available on target:..
-- @param target target object to embed AceComm-3.0 in
function AceComm:Embed(target)
for k, v in pairs(mixins) do
target[v] = self[v]
end
self.embeds[target] = true
return target
end
function AceComm:OnEmbedDisable(target)
target:UnregisterAllComm()
end
-- Update embeds
for target, v in pairs(AceComm.embeds) do
AceComm:Embed(target)
end
+5
View File
@@ -0,0 +1,5 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="ChatThrottleLib.lua"/>
<Script file="AceComm-3.0.lua"/>
</Ui>
@@ -0,0 +1,510 @@
--
-- ChatThrottleLib by Mikk
--
-- Manages AddOn chat output to keep player from getting kicked off.
--
-- ChatThrottleLib:SendChatMessage/:SendAddonMessage functions that accept
-- a Priority ("BULK", "NORMAL", "ALERT") as well as prefix for SendChatMessage.
--
-- Priorities get an equal share of available bandwidth when fully loaded.
-- Communication channels are separated on extension+chattype+destination and
-- get round-robinned. (Destination only matters for whispers and channels,
-- obviously)
--
-- Will install hooks for SendChatMessage and SendAddonMessage to measure
-- bandwidth bypassing the library and use less bandwidth itself.
--
--
-- Fully embeddable library. Just copy this file into your addon directory,
-- add it to the .toc, and it's done.
--
-- Can run as a standalone addon also, but, really, just embed it! :-)
--
local CTL_VERSION = 22
local _G = _G
if _G.ChatThrottleLib then
if _G.ChatThrottleLib.version >= CTL_VERSION then
-- There's already a newer (or same) version loaded. Buh-bye.
return
elseif not _G.ChatThrottleLib.securelyHooked then
print("ChatThrottleLib: Warning: There's an ANCIENT ChatThrottleLib.lua (pre-wow 2.0, <v16) in an addon somewhere. Get the addon updated or copy in a newer ChatThrottleLib.lua (>=v16) in it!")
-- ATTEMPT to unhook; this'll behave badly if someone else has hooked...
-- ... and if someone has securehooked, they can kiss that goodbye too... >.<
_G.SendChatMessage = _G.ChatThrottleLib.ORIG_SendChatMessage
if _G.ChatThrottleLib.ORIG_SendAddonMessage then
_G.SendAddonMessage = _G.ChatThrottleLib.ORIG_SendAddonMessage
end
end
_G.ChatThrottleLib.ORIG_SendChatMessage = nil
_G.ChatThrottleLib.ORIG_SendAddonMessage = nil
end
if not _G.ChatThrottleLib then
_G.ChatThrottleLib = {}
end
ChatThrottleLib = _G.ChatThrottleLib -- in case some addon does "local ChatThrottleLib" above us and we're copypasted (AceComm-2, sigh)
local ChatThrottleLib = _G.ChatThrottleLib
ChatThrottleLib.version = CTL_VERSION
------------------ TWEAKABLES -----------------
ChatThrottleLib.MAX_CPS = 800 -- 2000 seems to be safe if NOTHING ELSE is happening. let's call it 800.
ChatThrottleLib.MSG_OVERHEAD = 40 -- Guesstimate overhead for sending a message; source+dest+chattype+protocolstuff
ChatThrottleLib.BURST = 4000 -- WoW's server buffer seems to be about 32KB. 8KB should be safe, but seen disconnects on _some_ servers. Using 4KB now.
ChatThrottleLib.MIN_FPS = 20 -- Reduce output CPS to half (and don't burst) if FPS drops below this value
local setmetatable = setmetatable
local table_remove = table.remove
local tostring = tostring
local GetTime = GetTime
local math_min = math.min
local math_max = math.max
local next = next
local strlen = string.len
local GetFrameRate = GetFrameRate
-----------------------------------------------------------------------
-- Double-linked ring implementation
local Ring = {}
local RingMeta = { __index = Ring }
function Ring:New()
local ret = {}
setmetatable(ret, RingMeta)
return ret
end
function Ring:Add(obj) -- Append at the "far end" of the ring (aka just before the current position)
if self.pos then
obj.prev = self.pos.prev
obj.prev.next = obj
obj.next = self.pos
obj.next.prev = obj
else
obj.next = obj
obj.prev = obj
self.pos = obj
end
end
function Ring:Remove(obj)
obj.next.prev = obj.prev
obj.prev.next = obj.next
if self.pos == obj then
self.pos = obj.next
if self.pos == obj then
self.pos = nil
end
end
end
-----------------------------------------------------------------------
-- Recycling bin for pipes
-- A pipe is a plain integer-indexed queue, which also happens to be a ring member
ChatThrottleLib.PipeBin = nil -- pre-v19, drastically different
local PipeBin = setmetatable({}, {__mode="k"})
local function DelPipe(pipe)
for i = #pipe, 1, -1 do
pipe[i] = nil
end
pipe.prev = nil
pipe.next = nil
PipeBin[pipe] = true
end
local function NewPipe()
local pipe = next(PipeBin)
if pipe then
PipeBin[pipe] = nil
return pipe
end
return {}
end
-----------------------------------------------------------------------
-- Recycling bin for messages
ChatThrottleLib.MsgBin = nil -- pre-v19, drastically different
local MsgBin = setmetatable({}, {__mode="k"})
local function DelMsg(msg)
msg[1] = nil
-- there's more parameters, but they're very repetetive so the string pool doesn't suffer really, and it's faster to just not delete them.
MsgBin[msg] = true
end
local function NewMsg()
local msg = next(MsgBin)
if msg then
MsgBin[msg] = nil
return msg
end
return {}
end
-----------------------------------------------------------------------
-- ChatThrottleLib:Init
-- Initialize queues, set up frame for OnUpdate, etc
function ChatThrottleLib:Init()
-- Set up queues
if not self.Prio then
self.Prio = {}
self.Prio["ALERT"] = { ByName = {}, Ring = Ring:New(), avail = 0 }
self.Prio["NORMAL"] = { ByName = {}, Ring = Ring:New(), avail = 0 }
self.Prio["BULK"] = { ByName = {}, Ring = Ring:New(), avail = 0 }
end
-- v4: total send counters per priority
for _, Prio in pairs(self.Prio) do
Prio.nTotalSent = Prio.nTotalSent or 0
end
if not self.avail then
self.avail = 0 -- v5
end
if not self.nTotalSent then
self.nTotalSent = 0 -- v5
end
-- Set up a frame to get OnUpdate events
if not self.Frame then
self.Frame = CreateFrame("Frame")
self.Frame:Hide()
end
self.Frame:SetScript("OnUpdate", self.OnUpdate)
self.Frame:SetScript("OnEvent", self.OnEvent) -- v11: Monitor P_E_W so we can throttle hard for a few seconds
self.Frame:RegisterEvent("PLAYER_ENTERING_WORLD")
self.OnUpdateDelay = 0
self.LastAvailUpdate = GetTime()
self.HardThrottlingBeginTime = GetTime() -- v11: Throttle hard for a few seconds after startup
-- Hook SendChatMessage and SendAddonMessage so we can measure unpiped traffic and avoid overloads (v7)
if not self.securelyHooked then
-- Use secure hooks as of v16. Old regular hook support yanked out in v21.
self.securelyHooked = true
--SendChatMessage
hooksecurefunc("SendChatMessage", function(...)
return ChatThrottleLib.Hook_SendChatMessage(...)
end)
--SendAddonMessage
hooksecurefunc("SendAddonMessage", function(...)
return ChatThrottleLib.Hook_SendAddonMessage(...)
end)
end
self.nBypass = 0
end
-----------------------------------------------------------------------
-- ChatThrottleLib.Hook_SendChatMessage / .Hook_SendAddonMessage
local bMyTraffic = false
function ChatThrottleLib.Hook_SendChatMessage(text, chattype, language, destination, ...)
if bMyTraffic then
return
end
local self = ChatThrottleLib
local size = strlen(tostring(text or "")) + strlen(tostring(destination or "")) + self.MSG_OVERHEAD
self.avail = self.avail - size
self.nBypass = self.nBypass + size -- just a statistic
end
function ChatThrottleLib.Hook_SendAddonMessage(prefix, text, chattype, destination, ...)
if bMyTraffic then
return
end
local self = ChatThrottleLib
local size = tostring(text or ""):len() + tostring(prefix or ""):len();
size = size + tostring(destination or ""):len() + self.MSG_OVERHEAD
self.avail = self.avail - size
self.nBypass = self.nBypass + size -- just a statistic
end
-----------------------------------------------------------------------
-- ChatThrottleLib:UpdateAvail
-- Update self.avail with how much bandwidth is currently available
function ChatThrottleLib:UpdateAvail()
local now = GetTime()
local MAX_CPS = self.MAX_CPS;
local newavail = MAX_CPS * (now - self.LastAvailUpdate)
local avail = self.avail
if now - self.HardThrottlingBeginTime < 5 then
-- First 5 seconds after startup/zoning: VERY hard clamping to avoid irritating the server rate limiter, it seems very cranky then
avail = math_min(avail + (newavail*0.1), MAX_CPS*0.5)
self.bChoking = true
elseif GetFramerate() < self.MIN_FPS then -- GetFrameRate call takes ~0.002 secs
avail = math_min(MAX_CPS, avail + newavail*0.5)
self.bChoking = true -- just a statistic
else
avail = math_min(self.BURST, avail + newavail)
self.bChoking = false
end
avail = math_max(avail, 0-(MAX_CPS*2)) -- Can go negative when someone is eating bandwidth past the lib. but we refuse to stay silent for more than 2 seconds; if they can do it, we can.
self.avail = avail
self.LastAvailUpdate = now
return avail
end
-----------------------------------------------------------------------
-- Despooling logic
function ChatThrottleLib:Despool(Prio)
local ring = Prio.Ring
while ring.pos and Prio.avail > ring.pos[1].nSize do
local msg = table_remove(Prio.Ring.pos, 1)
if not Prio.Ring.pos[1] then
local pipe = Prio.Ring.pos
Prio.Ring:Remove(pipe)
Prio.ByName[pipe.name] = nil
DelPipe(pipe)
else
Prio.Ring.pos = Prio.Ring.pos.next
end
Prio.avail = Prio.avail - msg.nSize
bMyTraffic = true
msg.f(unpack(msg, 1, msg.n))
bMyTraffic = false
Prio.nTotalSent = Prio.nTotalSent + msg.nSize
DelMsg(msg)
if msg.callbackFn then
msg.callbackFn (msg.callbackArg)
end
end
end
function ChatThrottleLib.OnEvent(this,event)
-- v11: We know that the rate limiter is touchy after login. Assume that it's touchy after zoning, too.
local self = ChatThrottleLib
if event == "PLAYER_ENTERING_WORLD" then
self.HardThrottlingBeginTime = GetTime() -- Throttle hard for a few seconds after zoning
self.avail = 0
end
end
function ChatThrottleLib.OnUpdate(this,delay)
local self = ChatThrottleLib
self.OnUpdateDelay = self.OnUpdateDelay + delay
if self.OnUpdateDelay < 0.08 then
return
end
self.OnUpdateDelay = 0
self:UpdateAvail()
if self.avail < 0 then
return -- argh. some bastard is spewing stuff past the lib. just bail early to save cpu.
end
-- See how many of our priorities have queued messages (we only have 3, don't worry about the loop)
local n = 0
for prioname,Prio in pairs(self.Prio) do
if Prio.Ring.pos or Prio.avail < 0 then
n = n + 1
end
end
-- Anything queued still?
if n<1 then
-- Nope. Move spillover bandwidth to global availability gauge and clear self.bQueueing
for prioname, Prio in pairs(self.Prio) do
self.avail = self.avail + Prio.avail
Prio.avail = 0
end
self.bQueueing = false
self.Frame:Hide()
return
end
-- There's stuff queued. Hand out available bandwidth to priorities as needed and despool their queues
local avail = self.avail/n
self.avail = 0
for prioname, Prio in pairs(self.Prio) do
if Prio.Ring.pos or Prio.avail < 0 then
Prio.avail = Prio.avail + avail
if Prio.Ring.pos and Prio.avail > Prio.Ring.pos[1].nSize then
self:Despool(Prio)
-- Note: We might not get here if the user-supplied callback function errors out! Take care!
end
end
end
end
-----------------------------------------------------------------------
-- Spooling logic
function ChatThrottleLib:Enqueue(prioname, pipename, msg)
local Prio = self.Prio[prioname]
local pipe = Prio.ByName[pipename]
if not pipe then
self.Frame:Show()
pipe = NewPipe()
pipe.name = pipename
Prio.ByName[pipename] = pipe
Prio.Ring:Add(pipe)
end
pipe[#pipe + 1] = msg
self.bQueueing = true
end
function ChatThrottleLib:SendChatMessage(prio, prefix, text, chattype, language, destination, queueName, callbackFn, callbackArg)
if not self or not prio or not prefix or not text or not self.Prio[prio] then
error('Usage: ChatThrottleLib:SendChatMessage("{BULK||NORMAL||ALERT}", "prefix", "text"[, "chattype"[, "language"[, "destination"]]]', 2)
end
if callbackFn and type(callbackFn)~="function" then
error('ChatThrottleLib:ChatMessage(): callbackFn: expected function, got '..type(callbackFn), 2)
end
local nSize = text:len()
if nSize>255 then
error("ChatThrottleLib:SendChatMessage(): message length cannot exceed 255 bytes", 2)
end
nSize = nSize + self.MSG_OVERHEAD
-- Check if there's room in the global available bandwidth gauge to send directly
if not self.bQueueing and nSize < self:UpdateAvail() then
self.avail = self.avail - nSize
bMyTraffic = true
_G.SendChatMessage(text, chattype, language, destination)
bMyTraffic = false
self.Prio[prio].nTotalSent = self.Prio[prio].nTotalSent + nSize
if callbackFn then
callbackFn (callbackArg)
end
return
end
-- Message needs to be queued
local msg = NewMsg()
msg.f = _G.SendChatMessage
msg[1] = text
msg[2] = chattype or "SAY"
msg[3] = language
msg[4] = destination
msg.n = 4
msg.nSize = nSize
msg.callbackFn = callbackFn
msg.callbackArg = callbackArg
self:Enqueue(prio, queueName or (prefix..(chattype or "SAY")..(destination or "")), msg)
end
function ChatThrottleLib:SendAddonMessage(prio, prefix, text, chattype, target, queueName, callbackFn, callbackArg)
if not self or not prio or not prefix or not text or not chattype or not self.Prio[prio] then
error('Usage: ChatThrottleLib:SendAddonMessage("{BULK||NORMAL||ALERT}", "prefix", "text", "chattype"[, "target"])', 2)
end
if callbackFn and type(callbackFn)~="function" then
error('ChatThrottleLib:SendAddonMessage(): callbackFn: expected function, got '..type(callbackFn), 2)
end
local nSize = text:len();
if RegisterAddonMessagePrefix then
if nSize>255 then
error("ChatThrottleLib:SendAddonMessage(): message length cannot exceed 255 bytes", 2)
end
else
nSize = nSize + prefix:len() + 1
if nSize>255 then
error("ChatThrottleLib:SendAddonMessage(): prefix + message length cannot exceed 254 bytes", 2)
end
end
nSize = nSize + self.MSG_OVERHEAD;
-- Check if there's room in the global available bandwidth gauge to send directly
if not self.bQueueing and nSize < self:UpdateAvail() then
self.avail = self.avail - nSize
bMyTraffic = true
_G.SendAddonMessage(prefix, text, chattype, target)
bMyTraffic = false
self.Prio[prio].nTotalSent = self.Prio[prio].nTotalSent + nSize
if callbackFn then
callbackFn (callbackArg)
end
return
end
-- Message needs to be queued
local msg = NewMsg()
msg.f = _G.SendAddonMessage
msg[1] = prefix
msg[2] = text
msg[3] = chattype
msg[4] = target
msg.n = (target~=nil) and 4 or 3;
msg.nSize = nSize
msg.callbackFn = callbackFn
msg.callbackArg = callbackArg
self:Enqueue(prio, queueName or (prefix..chattype..(target or "")), msg)
end
-----------------------------------------------------------------------
-- Get the ball rolling!
ChatThrottleLib:Init()
--[[ WoWBench debugging snippet
if(WOWB_VER) then
local function SayTimer()
print("SAY: "..GetTime().." "..arg1)
end
ChatThrottleLib.Frame:SetScript("OnEvent", SayTimer)
ChatThrottleLib.Frame:RegisterEvent("CHAT_MSG_SAY")
end
]]
@@ -0,0 +1,137 @@
--- **AceLocale-3.0** manages localization in addons, allowing for multiple locale to be registered with fallback to the base locale for untranslated strings.
-- @class file
-- @name AceLocale-3.0
-- @release $Id: AceLocale-3.0.lua 1035 2011-07-09 03:20:13Z kaelten $
local MAJOR,MINOR = "AceLocale-3.0", 6
local AceLocale, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
if not AceLocale then return end -- no upgrade needed
-- Lua APIs
local assert, tostring, error = assert, tostring, error
local getmetatable, setmetatable, rawset, rawget = getmetatable, setmetatable, rawset, rawget
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
-- List them here for Mikk's FindGlobals script
-- GLOBALS: GAME_LOCALE, geterrorhandler
local gameLocale = GetLocale()
if gameLocale == "enGB" then
gameLocale = "enUS"
end
AceLocale.apps = AceLocale.apps or {} -- array of ["AppName"]=localetableref
AceLocale.appnames = AceLocale.appnames or {} -- array of [localetableref]="AppName"
-- This metatable is used on all tables returned from GetLocale
local readmeta = {
__index = function(self, key) -- requesting totally unknown entries: fire off a nonbreaking error and return key
rawset(self, key, key) -- only need to see the warning once, really
geterrorhandler()(MAJOR..": "..tostring(AceLocale.appnames[self])..": Missing entry for '"..tostring(key).."'")
return key
end
}
-- This metatable is used on all tables returned from GetLocale if the silent flag is true, it does not issue a warning on unknown keys
local readmetasilent = {
__index = function(self, key) -- requesting totally unknown entries: return key
rawset(self, key, key) -- only need to invoke this function once
return key
end
}
-- Remember the locale table being registered right now (it gets set by :NewLocale())
-- NOTE: Do never try to register 2 locale tables at once and mix their definition.
local registering
-- local assert false function
local assertfalse = function() assert(false) end
-- This metatable proxy is used when registering nondefault locales
local writeproxy = setmetatable({}, {
__newindex = function(self, key, value)
rawset(registering, key, value == true and key or value) -- assigning values: replace 'true' with key string
end,
__index = assertfalse
})
-- This metatable proxy is used when registering the default locale.
-- It refuses to overwrite existing values
-- Reason 1: Allows loading locales in any order
-- Reason 2: If 2 modules have the same string, but only the first one to be
-- loaded has a translation for the current locale, the translation
-- doesn't get overwritten.
--
local writedefaultproxy = setmetatable({}, {
__newindex = function(self, key, value)
if not rawget(registering, key) then
rawset(registering, key, value == true and key or value)
end
end,
__index = assertfalse
})
--- Register a new locale (or extend an existing one) for the specified application.
-- :NewLocale will return a table you can fill your locale into, or nil if the locale isn't needed for the players
-- game locale.
-- @paramsig application, locale[, isDefault[, silent]]
-- @param application Unique name of addon / module
-- @param locale Name of the locale to register, e.g. "enUS", "deDE", etc.
-- @param isDefault If this is the default locale being registered (your addon is written in this language, generally enUS)
-- @param silent If true, the locale will not issue warnings for missing keys. Must be set on the first locale registered. If set to "raw", nils will be returned for unknown keys (no metatable used).
-- @usage
-- -- enUS.lua
-- local L = LibStub("AceLocale-3.0"):NewLocale("TestLocale", "enUS", true)
-- L["string1"] = true
--
-- -- deDE.lua
-- local L = LibStub("AceLocale-3.0"):NewLocale("TestLocale", "deDE")
-- if not L then return end
-- L["string1"] = "Zeichenkette1"
-- @return Locale Table to add localizations to, or nil if the current locale is not required.
function AceLocale:NewLocale(application, locale, isDefault, silent)
-- GAME_LOCALE allows translators to test translations of addons without having that wow client installed
local gameLocale = GAME_LOCALE or gameLocale
local app = AceLocale.apps[application]
if silent and app and getmetatable(app) ~= readmetasilent then
geterrorhandler()("Usage: NewLocale(application, locale[, isDefault[, silent]]): 'silent' must be specified for the first locale registered")
end
if not app then
if silent=="raw" then
app = {}
else
app = setmetatable({}, silent and readmetasilent or readmeta)
end
AceLocale.apps[application] = app
AceLocale.appnames[app] = application
end
if locale ~= gameLocale and not isDefault then
return -- nop, we don't need these translations
end
registering = app -- remember globally for writeproxy and writedefaultproxy
if isDefault then
return writedefaultproxy
end
return writeproxy
end
--- Returns localizations for the current locale (or default locale if translations are missing).
-- Errors if nothing is registered (spank developer, not just a missing translation)
-- @param application Unique name of addon / module
-- @param silent If true, the locale is optional, silently return nil if it's not found (defaults to false, optional)
-- @return The locale table for the current language.
function AceLocale:GetLocale(application, silent)
if not silent and not AceLocale.apps[application] then
error("Usage: GetLocale(application[, silent]): 'application' - No locales registered for '"..tostring(application).."'", 2)
end
return AceLocale.apps[application]
end
@@ -0,0 +1,4 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="AceLocale-3.0.lua"/>
</Ui>
@@ -0,0 +1,283 @@
--- **AceSerializer-3.0** can serialize any variable (except functions or userdata) into a string format,
-- that can be send over the addon comm channel. AceSerializer was designed to keep all data intact, especially
-- very large numbers or floating point numbers, and table structures. The only caveat currently is, that multiple
-- references to the same table will be send individually.
--
-- **AceSerializer-3.0** can be embeded into your addon, either explicitly by calling AceSerializer:Embed(MyAddon) or by
-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
-- and can be accessed directly, without having to explicitly call AceSerializer itself.\\
-- It is recommended to embed AceSerializer, otherwise you'll have to specify a custom `self` on all calls you
-- make into AceSerializer.
-- @class file
-- @name AceSerializer-3.0
-- @release $Id: AceSerializer-3.0.lua 1038 2011-10-03 01:39:58Z mikk $
local MAJOR,MINOR = "AceSerializer-3.0", 4
local AceSerializer, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
if not AceSerializer then return end
-- Lua APIs
local strbyte, strchar, gsub, gmatch, format = string.byte, string.char, string.gsub, string.gmatch, string.format
local assert, error, pcall = assert, error, pcall
local type, tostring, tonumber = type, tostring, tonumber
local pairs, select, frexp = pairs, select, math.frexp
local tconcat = table.concat
-- quick copies of string representations of wonky numbers
local inf = math.huge
local serNaN -- can't do this in 4.3, see ace3 ticket 268
local serInf = tostring(inf)
local serNegInf = tostring(-inf)
-- Serialization functions
local function SerializeStringHelper(ch) -- Used by SerializeValue for strings
-- We use \126 ("~") as an escape character for all nonprints plus a few more
local n = strbyte(ch)
if n==30 then -- v3 / ticket 115: catch a nonprint that ends up being "~^" when encoded... DOH
return "\126\122"
elseif n<=32 then -- nonprint + space
return "\126"..strchar(n+64)
elseif n==94 then -- value separator
return "\126\125"
elseif n==126 then -- our own escape character
return "\126\124"
elseif n==127 then -- nonprint (DEL)
return "\126\123"
else
assert(false) -- can't be reached if caller uses a sane regex
end
end
local function SerializeValue(v, res, nres)
-- We use "^" as a value separator, followed by one byte for type indicator
local t=type(v)
if t=="string" then -- ^S = string (escaped to remove nonprints, "^"s, etc)
res[nres+1] = "^S"
res[nres+2] = gsub(v,"[%c \94\126\127]", SerializeStringHelper)
nres=nres+2
elseif t=="number" then -- ^N = number (just tostring()ed) or ^F (float components)
local str = tostring(v)
if tonumber(str)==v --[[not in 4.3 or str==serNaN]] or str==serInf or str==serNegInf then
-- translates just fine, transmit as-is
res[nres+1] = "^N"
res[nres+2] = str
nres=nres+2
else
local m,e = frexp(v)
res[nres+1] = "^F"
res[nres+2] = format("%.0f",m*2^53) -- force mantissa to become integer (it's originally 0.5--0.9999)
res[nres+3] = "^f"
res[nres+4] = tostring(e-53) -- adjust exponent to counteract mantissa manipulation
nres=nres+4
end
elseif t=="table" then -- ^T...^t = table (list of key,value pairs)
nres=nres+1
res[nres] = "^T"
for k,v in pairs(v) do
nres = SerializeValue(k, res, nres)
nres = SerializeValue(v, res, nres)
end
nres=nres+1
res[nres] = "^t"
elseif t=="boolean" then -- ^B = true, ^b = false
nres=nres+1
if v then
res[nres] = "^B" -- true
else
res[nres] = "^b" -- false
end
elseif t=="nil" then -- ^Z = nil (zero, "N" was taken :P)
nres=nres+1
res[nres] = "^Z"
else
error(MAJOR..": Cannot serialize a value of type '"..t.."'") -- can't produce error on right level, this is wildly recursive
end
return nres
end
local serializeTbl = { "^1" } -- "^1" = Hi, I'm data serialized by AceSerializer protocol rev 1
--- Serialize the data passed into the function.
-- Takes a list of values (strings, numbers, booleans, nils, tables)
-- and returns it in serialized form (a string).\\
-- May throw errors on invalid data types.
-- @param ... List of values to serialize
-- @return The data in its serialized form (string)
function AceSerializer:Serialize(...)
local nres = 1
for i=1,select("#", ...) do
local v = select(i, ...)
nres = SerializeValue(v, serializeTbl, nres)
end
serializeTbl[nres+1] = "^^" -- "^^" = End of serialized data
return tconcat(serializeTbl, "", 1, nres+1)
end
-- Deserialization functions
local function DeserializeStringHelper(escape)
if escape<"~\122" then
return strchar(strbyte(escape,2,2)-64)
elseif escape=="~\122" then -- v3 / ticket 115: special case encode since 30+64=94 ("^") - OOPS.
return "\030"
elseif escape=="~\123" then
return "\127"
elseif escape=="~\124" then
return "\126"
elseif escape=="~\125" then
return "\94"
end
error("DeserializeStringHelper got called for '"..escape.."'?!?") -- can't be reached unless regex is screwed up
end
local function DeserializeNumberHelper(number)
--[[ not in 4.3 if number == serNaN then
return 0/0
else]]if number == serNegInf then
return -inf
elseif number == serInf then
return inf
else
return tonumber(number)
end
end
-- DeserializeValue: worker function for :Deserialize()
-- It works in two modes:
-- Main (top-level) mode: Deserialize a list of values and return them all
-- Recursive (table) mode: Deserialize only a single value (_may_ of course be another table with lots of subvalues in it)
--
-- The function _always_ works recursively due to having to build a list of values to return
--
-- Callers are expected to pcall(DeserializeValue) to trap errors
local function DeserializeValue(iter,single,ctl,data)
if not single then
ctl,data = iter()
end
if not ctl then
error("Supplied data misses AceSerializer terminator ('^^')")
end
if ctl=="^^" then
-- ignore extraneous data
return
end
local res
if ctl=="^S" then
res = gsub(data, "~.", DeserializeStringHelper)
elseif ctl=="^N" then
res = DeserializeNumberHelper(data)
if not res then
error("Invalid serialized number: '"..tostring(data).."'")
end
elseif ctl=="^F" then -- ^F<mantissa>^f<exponent>
local ctl2,e = iter()
if ctl2~="^f" then
error("Invalid serialized floating-point number, expected '^f', not '"..tostring(ctl2).."'")
end
local m=tonumber(data)
e=tonumber(e)
if not (m and e) then
error("Invalid serialized floating-point number, expected mantissa and exponent, got '"..tostring(m).."' and '"..tostring(e).."'")
end
res = m*(2^e)
elseif ctl=="^B" then -- yeah yeah ignore data portion
res = true
elseif ctl=="^b" then -- yeah yeah ignore data portion
res = false
elseif ctl=="^Z" then -- yeah yeah ignore data portion
res = nil
elseif ctl=="^T" then
-- ignore ^T's data, future extensibility?
res = {}
local k,v
while true do
ctl,data = iter()
if ctl=="^t" then break end -- ignore ^t's data
k = DeserializeValue(iter,true,ctl,data)
if k==nil then
error("Invalid AceSerializer table format (no table end marker)")
end
ctl,data = iter()
v = DeserializeValue(iter,true,ctl,data)
if v==nil then
error("Invalid AceSerializer table format (no table end marker)")
end
res[k]=v
end
else
error("Invalid AceSerializer control code '"..ctl.."'")
end
if not single then
return res,DeserializeValue(iter)
else
return res
end
end
--- Deserializes the data into its original values.
-- Accepts serialized data, ignoring all control characters and whitespace.
-- @param str The serialized data (from :Serialize)
-- @return true followed by a list of values, OR false followed by an error message
function AceSerializer:Deserialize(str)
str = gsub(str, "[%c ]", "") -- ignore all control characters; nice for embedding in email and stuff
local iter = gmatch(str, "(^.)([^^]*)") -- Any ^x followed by string of non-^
local ctl,data = iter()
if not ctl or ctl~="^1" then
-- we purposefully ignore the data portion of the start code, it can be used as an extension mechanism
return false, "Supplied data is not AceSerializer data (rev 1)"
end
return pcall(DeserializeValue, iter)
end
----------------------------------------
-- Base library stuff
----------------------------------------
AceSerializer.internals = { -- for test scripts
SerializeValue = SerializeValue,
SerializeStringHelper = SerializeStringHelper,
}
local mixins = {
"Serialize",
"Deserialize",
}
AceSerializer.embeds = AceSerializer.embeds or {}
function AceSerializer:Embed(target)
for k, v in pairs(mixins) do
target[v] = self[v]
end
self.embeds[target] = true
return target
end
-- Update embeds
for target, v in pairs(AceSerializer.embeds) do
AceSerializer:Embed(target)
end
@@ -0,0 +1,4 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="AceSerializer-3.0.lua"/>
</Ui>
+475
View File
@@ -0,0 +1,475 @@
--- **AceTimer-3.0** provides a central facility for registering timers.
-- AceTimer supports one-shot timers and repeating timers. All timers are stored in an efficient
-- data structure that allows easy dispatching and fast rescheduling. Timers can be registered, rescheduled
-- or canceled at any time, even from within a running timer, without conflict or large overhead.\\
-- AceTimer is currently limited to firing timers at a frequency of 0.1s. This constant may change
-- in the future, but for now it seemed like a good compromise in efficiency and accuracy.
--
-- All `:Schedule` functions will return a handle to the current timer, which you will need to store if you
-- need to cancel or reschedule the timer you just registered.
--
-- **AceTimer-3.0** can be embeded into your addon, either explicitly by calling AceTimer:Embed(MyAddon) or by
-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
-- and can be accessed directly, without having to explicitly call AceTimer itself.\\
-- It is recommended to embed AceTimer, otherwise you'll have to specify a custom `self` on all calls you
-- make into AceTimer.
-- @class file
-- @name AceTimer-3.0
-- @release $Id: AceTimer-3.0.lua 1037 2011-09-02 16:24:08Z mikk $
--[[
Basic assumptions:
* In a typical system, we do more re-scheduling per second than there are timer pulses per second
* Regardless of timer implementation, we cannot guarantee timely delivery due to FPS restriction (may be as low as 10)
This implementation:
CON: The smallest timer interval is constrained by HZ (currently 1/10s).
PRO: It will still correctly fire any timer slower than HZ over a length of time, e.g. 0.11s interval -> 90 times over 10 seconds
PRO: In lag bursts, the system simly skips missed timer intervals to decrease load
CON: Algorithms depending on a timer firing "N times per minute" will fail
PRO: (Re-)scheduling is O(1) with a VERY small constant. It's a simple linked list insertion in a hash bucket.
CAUTION: The BUCKETS constant constrains how many timers can be efficiently handled. With too many hash collisions, performance will decrease.
Major assumptions upheld:
- ALLOWS scheduling multiple timers with the same funcref/method
- ALLOWS scheduling more timers during OnUpdate processing
- ALLOWS unscheduling ANY timer (including the current running one) at any time, including during OnUpdate processing
]]
local MAJOR, MINOR = "AceTimer-3.0", 6
local AceTimer, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
if not AceTimer then return end -- No upgrade needed
AceTimer.hash = AceTimer.hash or {} -- Array of [0..BUCKET-1] = linked list of timers (using .next member)
-- Linked list gets around ACE-88 and ACE-90.
AceTimer.selfs = AceTimer.selfs or {} -- Array of [self]={[handle]=timerobj, [handle2]=timerobj2, ...}
AceTimer.frame = AceTimer.frame or CreateFrame("Frame", "AceTimer30Frame")
-- Lua APIs
local assert, error, loadstring = assert, error, loadstring
local setmetatable, rawset, rawget = setmetatable, rawset, rawget
local select, pairs, type, next, tostring = select, pairs, type, next, tostring
local floor, max, min = math.floor, math.max, math.min
local tconcat = table.concat
-- WoW APIs
local GetTime = GetTime
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
-- List them here for Mikk's FindGlobals script
-- GLOBALS: DEFAULT_CHAT_FRAME, geterrorhandler
-- Simple ONE-SHOT timer cache. Much more efficient than a full compost for our purposes.
local timerCache = nil
--[[
Timers will not be fired more often than HZ-1 times per second.
Keep at intended speed PLUS ONE or we get bitten by floating point rounding errors (n.5 + 0.1 can be n.599999)
If this is ever LOWERED, all existing timers need to be enforced to have a delay >= 1/HZ on lib upgrade.
If this number is ever changed, all entries need to be rehashed on lib upgrade.
]]
local HZ = 11
--[[
Prime for good distribution
If this number is ever changed, all entries need to be rehashed on lib upgrade.
]]
local BUCKETS = 131
local hash = AceTimer.hash
for i=1,BUCKETS do
hash[i] = hash[i] or false -- make it an integer-indexed array; it's faster than hashes
end
--[[
xpcall safecall implementation
]]
local xpcall = xpcall
local function errorhandler(err)
return geterrorhandler()(err)
end
local function CreateDispatcher(argCount)
local code = [[
local xpcall, eh = ... -- our arguments are received as unnamed values in "..." since we don't have a proper function declaration
local method, ARGS
local function call() return method(ARGS) end
local function dispatch(func, ...)
method = func
if not method then return end
ARGS = ...
return xpcall(call, eh)
end
return dispatch
]]
local ARGS = {}
for i = 1, argCount do ARGS[i] = "arg"..i end
code = code:gsub("ARGS", tconcat(ARGS, ", "))
return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(xpcall, errorhandler)
end
local Dispatchers = setmetatable({}, {
__index=function(self, argCount)
local dispatcher = CreateDispatcher(argCount)
rawset(self, argCount, dispatcher)
return dispatcher
end
})
Dispatchers[0] = function(func)
return xpcall(func, errorhandler)
end
local function safecall(func, ...)
return Dispatchers[select('#', ...)](func, ...)
end
local lastint = floor(GetTime() * HZ)
-- --------------------------------------------------------------------
-- OnUpdate handler
--
-- traverse buckets, always chasing "now", and fire timers that have expired
local function OnUpdate()
local now = GetTime()
local nowint = floor(now * HZ)
-- Have we passed into a new hash bucket?
if nowint == lastint then return end
local soon = now + 1 -- +1 is safe as long as 1 < HZ < BUCKETS/2
-- Pass through each bucket at most once
-- Happens on e.g. instance loads, but COULD happen on high local load situations also
for curint = (max(lastint, nowint - BUCKETS) + 1), nowint do -- loop until we catch up with "now", usually only 1 iteration
local curbucket = (curint % BUCKETS)+1
-- Yank the list of timers out of the bucket and empty it. This allows reinsertion in the currently-processed bucket from callbacks.
local nexttimer = hash[curbucket]
hash[curbucket] = false -- false rather than nil to prevent the array from becoming a hash
while nexttimer do
local timer = nexttimer
nexttimer = timer.next
local when = timer.when
if when < soon then
-- Call the timer func, either as a method on given object, or a straight function ref
local callback = timer.callback
if type(callback) == "string" then
safecall(timer.object[callback], timer.object, timer.arg)
elseif callback then
safecall(callback, timer.arg)
else
-- probably nilled out by CancelTimer
timer.delay = nil -- don't reschedule it
end
local delay = timer.delay -- NOW make a local copy, can't do it earlier in case the timer cancelled itself in the callback
if not delay then
-- single-shot timer (or cancelled)
AceTimer.selfs[timer.object][tostring(timer)] = nil
timerCache = timer
else
-- repeating timer
local newtime = when + delay
if newtime < now then -- Keep lag from making us firing a timer unnecessarily. (Note that this still won't catch too-short-delay timers though.)
newtime = now + delay
end
timer.when = newtime
-- add next timer execution to the correct bucket
local bucket = (floor(newtime * HZ) % BUCKETS) + 1
timer.next = hash[bucket]
hash[bucket] = timer
end
else -- if when>=soon
-- reinsert (yeah, somewhat expensive, but shouldn't be happening too often either due to hash distribution)
timer.next = hash[curbucket]
hash[curbucket] = timer
end -- if when<soon ... else
end -- while nexttimer do
end -- for curint=lastint,nowint
lastint = nowint
end
-- ---------------------------------------------------------------------
-- Reg( callback, delay, arg, repeating )
--
-- callback( function or string ) - direct function ref or method name in our object for the callback
-- delay(int) - delay for the timer
-- arg(variant) - any argument to be passed to the callback function
-- repeating(boolean) - repeating timer, or oneshot
--
-- returns the handle of the timer for later processing (canceling etc)
local function Reg(self, callback, delay, arg, repeating)
if type(callback) ~= "string" and type(callback) ~= "function" then
local error_origin = repeating and "ScheduleRepeatingTimer" or "ScheduleTimer"
error(MAJOR..": " .. error_origin .. "(callback, delay, arg): 'callback' - function or method name expected.", 3)
end
if type(callback) == "string" then
if type(self)~="table" then
local error_origin = repeating and "ScheduleRepeatingTimer" or "ScheduleTimer"
error(MAJOR..": " .. error_origin .. "(\"methodName\", delay, arg): 'self' - must be a table.", 3)
end
if type(self[callback]) ~= "function" then
local error_origin = repeating and "ScheduleRepeatingTimer" or "ScheduleTimer"
error(MAJOR..": " .. error_origin .. "(\"methodName\", delay, arg): 'methodName' - method not found on target object.", 3)
end
end
if delay < (1 / (HZ - 1)) then
delay = 1 / (HZ - 1)
end
-- Create and stuff timer in the correct hash bucket
local now = GetTime()
local timer = timerCache or {} -- Get new timer object (from cache if available)
timerCache = nil
timer.object = self
timer.callback = callback
timer.delay = (repeating and delay)
timer.arg = arg
timer.when = now + delay
local bucket = (floor((now+delay)*HZ) % BUCKETS) + 1
timer.next = hash[bucket]
hash[bucket] = timer
-- Insert timer in our self->handle->timer registry
local handle = tostring(timer)
local selftimers = AceTimer.selfs[self]
if not selftimers then
selftimers = {}
AceTimer.selfs[self] = selftimers
end
selftimers[handle] = timer
selftimers.__ops = (selftimers.__ops or 0) + 1
return handle
end
--- Schedule a new one-shot timer.
-- The timer will fire once in `delay` seconds, unless canceled before.
-- @param callback Callback function for the timer pulse (funcref or method name).
-- @param delay Delay for the timer, in seconds.
-- @param arg An optional argument to be passed to the callback function.
-- @usage
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("TimerTest", "AceTimer-3.0")
--
-- function MyAddon:OnEnable()
-- self:ScheduleTimer("TimerFeedback", 5)
-- end
--
-- function MyAddon:TimerFeedback()
-- print("5 seconds passed")
-- end
function AceTimer:ScheduleTimer(callback, delay, arg)
return Reg(self, callback, delay, arg)
end
--- Schedule a repeating timer.
-- The timer will fire every `delay` seconds, until canceled.
-- @param callback Callback function for the timer pulse (funcref or method name).
-- @param delay Delay for the timer, in seconds.
-- @param arg An optional argument to be passed to the callback function.
-- @usage
-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("TimerTest", "AceTimer-3.0")
--
-- function MyAddon:OnEnable()
-- self.timerCount = 0
-- self.testTimer = self:ScheduleRepeatingTimer("TimerFeedback", 5)
-- end
--
-- function MyAddon:TimerFeedback()
-- self.timerCount = self.timerCount + 1
-- print(("%d seconds passed"):format(5 * self.timerCount))
-- -- run 30 seconds in total
-- if self.timerCount == 6 then
-- self:CancelTimer(self.testTimer)
-- end
-- end
function AceTimer:ScheduleRepeatingTimer(callback, delay, arg)
return Reg(self, callback, delay, arg, true)
end
--- Cancels a timer with the given handle, registered by the same addon object as used for `:ScheduleTimer`
-- Both one-shot and repeating timers can be canceled with this function, as long as the `handle` is valid
-- and the timer has not fired yet or was canceled before.
-- @param handle The handle of the timer, as returned by `:ScheduleTimer` or `:ScheduleRepeatingTimer`
-- @param silent If true, no error is raised if the timer handle is invalid (expired or already canceled)
-- @return True if the timer was successfully cancelled.
function AceTimer:CancelTimer(handle, silent)
if not handle then return end -- nil handle -> bail out without erroring
if type(handle) ~= "string" then
error(MAJOR..": CancelTimer(handle): 'handle' - expected a string", 2) -- for now, anyway
end
local selftimers = AceTimer.selfs[self]
local timer = selftimers and selftimers[handle]
if silent then
if timer then
timer.callback = nil -- don't run it again
timer.delay = nil -- if this is the currently-executing one: don't even reschedule
-- The timer object is removed in the OnUpdate loop
end
return not not timer -- might return "true" even if we double-cancel. we'll live.
else
if not timer then
geterrorhandler()(MAJOR..": CancelTimer(handle[, silent]): '"..tostring(handle).."' - no such timer registered")
return false
end
if not timer.callback then
geterrorhandler()(MAJOR..": CancelTimer(handle[, silent]): '"..tostring(handle).."' - timer already cancelled or expired")
return false
end
timer.callback = nil -- don't run it again
timer.delay = nil -- if this is the currently-executing one: don't even reschedule
return true
end
end
--- Cancels all timers registered to the current addon object ('self')
function AceTimer:CancelAllTimers()
if not(type(self) == "string" or type(self) == "table") then
error(MAJOR..": CancelAllTimers(): 'self' - must be a string or a table",2)
end
if self == AceTimer then
error(MAJOR..": CancelAllTimers(): supply a meaningful 'self'", 2)
end
local selftimers = AceTimer.selfs[self]
if selftimers then
for handle,v in pairs(selftimers) do
if type(v) == "table" then -- avoid __ops, etc
AceTimer.CancelTimer(self, handle, true)
end
end
end
end
--- Returns the time left for a timer with the given handle, registered by the current addon object ('self').
-- This function will raise a warning when the handle is invalid, but not stop execution.
-- @param handle The handle of the timer, as returned by `:ScheduleTimer` or `:ScheduleRepeatingTimer`
-- @return The time left on the timer, or false if the handle is invalid.
function AceTimer:TimeLeft(handle)
if not handle then return end
if type(handle) ~= "string" then
error(MAJOR..": TimeLeft(handle): 'handle' - expected a string", 2) -- for now, anyway
end
local selftimers = AceTimer.selfs[self]
local timer = selftimers and selftimers[handle]
if not timer then
geterrorhandler()(MAJOR..": TimeLeft(handle): '"..tostring(handle).."' - no such timer registered")
return false
end
return timer.when - GetTime()
end
-- ---------------------------------------------------------------------
-- PLAYER_REGEN_ENABLED: Run through our .selfs[] array step by step
-- and clean it out - otherwise the table indices can grow indefinitely
-- if an addon starts and stops a lot of timers. AceBucket does this!
--
-- See ACE-94 and tests/AceTimer-3.0-ACE-94.lua
local lastCleaned = nil
local function OnEvent(this, event)
if event~="PLAYER_REGEN_ENABLED" then
return
end
-- Get the next 'self' to process
local selfs = AceTimer.selfs
local self = next(selfs, lastCleaned)
if not self then
self = next(selfs)
end
lastCleaned = self
if not self then -- should only happen if .selfs[] is empty
return
end
-- Time to clean it out?
local list = selfs[self]
if (list.__ops or 0) < 250 then -- 250 slosh indices = ~10KB wasted (worst case!). For one 'self'.
return
end
-- Create a new table and copy all members over
local newlist = {}
local n=0
for k,v in pairs(list) do
newlist[k] = v
if type(v)=="table" and v.callback then -- if the timer is actually live: count it
n=n+1
end
end
newlist.__ops = 0 -- Reset operation count
-- And since we now have a count of the number of live timers, check that it's reasonable. Emit a warning if not.
if n>BUCKETS then
DEFAULT_CHAT_FRAME:AddMessage(MAJOR..": Warning: The addon/module '"..tostring(self).."' has "..n.." live timers. Surely that's not intended?")
end
selfs[self] = newlist
end
-- ---------------------------------------------------------------------
-- Embed handling
AceTimer.embeds = AceTimer.embeds or {}
local mixins = {
"ScheduleTimer", "ScheduleRepeatingTimer",
"CancelTimer", "CancelAllTimers",
"TimeLeft"
}
function AceTimer:Embed(target)
AceTimer.embeds[target] = true
for _,v in pairs(mixins) do
target[v] = AceTimer[v]
end
return target
end
-- AceTimer:OnEmbedDisable( target )
-- target (object) - target object that AceTimer is embedded in.
--
-- cancel all timers registered for the object
function AceTimer:OnEmbedDisable( target )
target:CancelAllTimers()
end
for addon in pairs(AceTimer.embeds) do
AceTimer:Embed(addon)
end
-- ---------------------------------------------------------------------
-- Debug tools (expose copies of internals to test suites)
AceTimer.debug = AceTimer.debug or {}
AceTimer.debug.HZ = HZ
AceTimer.debug.BUCKETS = BUCKETS
-- ---------------------------------------------------------------------
-- Finishing touchups
AceTimer.frame:SetScript("OnUpdate", OnUpdate)
AceTimer.frame:SetScript("OnEvent", OnEvent)
AceTimer.frame:RegisterEvent("PLAYER_REGEN_ENABLED")
-- In theory, we could hide&show the frame based on there being timers or not.
-- However, this job is fairly expensive, and the chance that there will
-- actually be zero timers running is diminuitive to say the least.
@@ -0,0 +1,4 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="AceTimer-3.0.lua"/>
</Ui>
@@ -0,0 +1,240 @@
--[[ $Id: CallbackHandler-1.0.lua 14 2010-08-09 00:43:38Z mikk $ ]]
local MAJOR, MINOR = "CallbackHandler-1.0", 6
local CallbackHandler = LibStub:NewLibrary(MAJOR, MINOR)
if not CallbackHandler then return end -- No upgrade needed
local meta = {__index = function(tbl, key) tbl[key] = {} return tbl[key] end}
-- Lua APIs
local tconcat = table.concat
local assert, error, loadstring = assert, error, loadstring
local setmetatable, rawset, rawget = setmetatable, rawset, rawget
local next, select, pairs, type, tostring = next, select, pairs, type, tostring
-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
-- List them here for Mikk's FindGlobals script
-- GLOBALS: geterrorhandler
local xpcall = xpcall
local function errorhandler(err)
return geterrorhandler()(err)
end
local function CreateDispatcher(argCount)
local code = [[
local next, xpcall, eh = ...
local method, ARGS
local function call() method(ARGS) end
local function dispatch(handlers, ...)
local index
index, method = next(handlers)
if not method then return end
local OLD_ARGS = ARGS
ARGS = ...
repeat
xpcall(call, eh)
index, method = next(handlers, index)
until not method
ARGS = OLD_ARGS
end
return dispatch
]]
local ARGS, OLD_ARGS = {}, {}
for i = 1, argCount do ARGS[i], OLD_ARGS[i] = "arg"..i, "old_arg"..i end
code = code:gsub("OLD_ARGS", tconcat(OLD_ARGS, ", ")):gsub("ARGS", tconcat(ARGS, ", "))
return assert(loadstring(code, "safecall Dispatcher["..argCount.."]"))(next, xpcall, errorhandler)
end
local Dispatchers = setmetatable({}, {__index=function(self, argCount)
local dispatcher = CreateDispatcher(argCount)
rawset(self, argCount, dispatcher)
return dispatcher
end})
--------------------------------------------------------------------------
-- CallbackHandler:New
--
-- target - target object to embed public APIs in
-- RegisterName - name of the callback registration API, default "RegisterCallback"
-- UnregisterName - name of the callback unregistration API, default "UnregisterCallback"
-- UnregisterAllName - name of the API to unregister all callbacks, default "UnregisterAllCallbacks". false == don't publish this API.
function CallbackHandler:New(target, RegisterName, UnregisterName, UnregisterAllName, OnUsed, OnUnused)
-- TODO: Remove this after beta has gone out
assert(not OnUsed and not OnUnused, "ACE-80: OnUsed/OnUnused are deprecated. Callbacks are now done to registry.OnUsed and registry.OnUnused")
RegisterName = RegisterName or "RegisterCallback"
UnregisterName = UnregisterName or "UnregisterCallback"
if UnregisterAllName==nil then -- false is used to indicate "don't want this method"
UnregisterAllName = "UnregisterAllCallbacks"
end
-- we declare all objects and exported APIs inside this closure to quickly gain access
-- to e.g. function names, the "target" parameter, etc
-- Create the registry object
local events = setmetatable({}, meta)
local registry = { recurse=0, events=events }
-- registry:Fire() - fires the given event/message into the registry
function registry:Fire(eventname, ...)
if not rawget(events, eventname) or not next(events[eventname]) then return end
local oldrecurse = registry.recurse
registry.recurse = oldrecurse + 1
Dispatchers[select('#', ...) + 1](events[eventname], eventname, ...)
registry.recurse = oldrecurse
if registry.insertQueue and oldrecurse==0 then
-- Something in one of our callbacks wanted to register more callbacks; they got queued
for eventname,callbacks in pairs(registry.insertQueue) do
local first = not rawget(events, eventname) or not next(events[eventname]) -- test for empty before. not test for one member after. that one member may have been overwritten.
for self,func in pairs(callbacks) do
events[eventname][self] = func
-- fire OnUsed callback?
if first and registry.OnUsed then
registry.OnUsed(registry, target, eventname)
first = nil
end
end
end
registry.insertQueue = nil
end
end
-- Registration of a callback, handles:
-- self["method"], leads to self["method"](self, ...)
-- self with function ref, leads to functionref(...)
-- "addonId" (instead of self) with function ref, leads to functionref(...)
-- all with an optional arg, which, if present, gets passed as first argument (after self if present)
target[RegisterName] = function(self, eventname, method, ... --[[actually just a single arg]])
if type(eventname) ~= "string" then
error("Usage: "..RegisterName.."(eventname, method[, arg]): 'eventname' - string expected.", 2)
end
method = method or eventname
local first = not rawget(events, eventname) or not next(events[eventname]) -- test for empty before. not test for one member after. that one member may have been overwritten.
if type(method) ~= "string" and type(method) ~= "function" then
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - string or function expected.", 2)
end
local regfunc
if type(method) == "string" then
-- self["method"] calling style
if type(self) ~= "table" then
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): self was not a table?", 2)
elseif self==target then
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): do not use Library:"..RegisterName.."(), use your own 'self'", 2)
elseif type(self[method]) ~= "function" then
error("Usage: "..RegisterName.."(\"eventname\", \"methodname\"): 'methodname' - method '"..tostring(method).."' not found on self.", 2)
end
if select("#",...)>=1 then -- this is not the same as testing for arg==nil!
local arg=select(1,...)
regfunc = function(...) self[method](self,arg,...) end
else
regfunc = function(...) self[method](self,...) end
end
else
-- function ref with self=object or self="addonId" or self=thread
if type(self)~="table" and type(self)~="string" and type(self)~="thread" then
error("Usage: "..RegisterName.."(self or \"addonId\", eventname, method): 'self or addonId': table or string or thread expected.", 2)
end
if select("#",...)>=1 then -- this is not the same as testing for arg==nil!
local arg=select(1,...)
regfunc = function(...) method(arg,...) end
else
regfunc = method
end
end
if events[eventname][self] or registry.recurse<1 then
-- if registry.recurse<1 then
-- we're overwriting an existing entry, or not currently recursing. just set it.
events[eventname][self] = regfunc
-- fire OnUsed callback?
if registry.OnUsed and first then
registry.OnUsed(registry, target, eventname)
end
else
-- we're currently processing a callback in this registry, so delay the registration of this new entry!
-- yes, we're a bit wasteful on garbage, but this is a fringe case, so we're picking low implementation overhead over garbage efficiency
registry.insertQueue = registry.insertQueue or setmetatable({},meta)
registry.insertQueue[eventname][self] = regfunc
end
end
-- Unregister a callback
target[UnregisterName] = function(self, eventname)
if not self or self==target then
error("Usage: "..UnregisterName.."(eventname): bad 'self'", 2)
end
if type(eventname) ~= "string" then
error("Usage: "..UnregisterName.."(eventname): 'eventname' - string expected.", 2)
end
if rawget(events, eventname) and events[eventname][self] then
events[eventname][self] = nil
-- Fire OnUnused callback?
if registry.OnUnused and not next(events[eventname]) then
registry.OnUnused(registry, target, eventname)
end
end
if registry.insertQueue and rawget(registry.insertQueue, eventname) and registry.insertQueue[eventname][self] then
registry.insertQueue[eventname][self] = nil
end
end
-- OPTIONAL: Unregister all callbacks for given selfs/addonIds
if UnregisterAllName then
target[UnregisterAllName] = function(...)
if select("#",...)<1 then
error("Usage: "..UnregisterAllName.."([whatFor]): missing 'self' or \"addonId\" to unregister events for.", 2)
end
if select("#",...)==1 and ...==target then
error("Usage: "..UnregisterAllName.."([whatFor]): supply a meaningful 'self' or \"addonId\"", 2)
end
for i=1,select("#",...) do
local self = select(i,...)
if registry.insertQueue then
for eventname, callbacks in pairs(registry.insertQueue) do
if callbacks[self] then
callbacks[self] = nil
end
end
end
for eventname, callbacks in pairs(events) do
if callbacks[self] then
callbacks[self] = nil
-- Fire OnUnused callback?
if registry.OnUnused and not next(callbacks) then
registry.OnUnused(registry, target, eventname)
end
end
end
end
end
end
return registry
end
-- CallbackHandler purposefully does NOT do explicit embedding. Nor does it
-- try to upgrade old implicit embeds since the system is selfcontained and
-- relies on closures to work.
@@ -0,0 +1,4 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="CallbackHandler-1.0.lua"/>
</Ui>
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,237 @@
--[[
Name: LibSharedMedia-3.0
Revision: $Revision: 69 $
Author: Elkano (elkano@gmx.de)
Inspired By: SurfaceLib by Haste/Otravi (troeks@gmail.com)
Website: http://www.wowace.com/projects/libsharedmedia-3-0/
Description: Shared handling of media data (fonts, sounds, textures, ...) between addons.
Dependencies: LibStub, CallbackHandler-1.0
License: LGPL v2.1
]]
local MAJOR, MINOR = "LibSharedMedia-3.0", 4030402 -- increase manualy on changes
local lib = LibStub:NewLibrary(MAJOR, MINOR)
if not lib then return end
local _G = getfenv(0)
local pairs = _G.pairs
local type = _G.type
local band = _G.bit.band
local table_insert = _G.table.insert
local table_sort = _G.table.sort
local locale = GetLocale()
local locale_is_western
local LOCALE_MASK = 0
lib.LOCALE_BIT_koKR = 1
lib.LOCALE_BIT_ruRU = 2
lib.LOCALE_BIT_zhCN = 4
lib.LOCALE_BIT_zhTW = 8
lib.LOCALE_BIT_western = 128
local CallbackHandler = LibStub:GetLibrary("CallbackHandler-1.0")
lib.callbacks = lib.callbacks or CallbackHandler:New(lib)
lib.DefaultMedia = lib.DefaultMedia or {}
lib.MediaList = lib.MediaList or {}
lib.MediaTable = lib.MediaTable or {}
lib.MediaType = lib.MediaType or {}
lib.OverrideMedia = lib.OverrideMedia or {}
local defaultMedia = lib.DefaultMedia
local mediaList = lib.MediaList
local mediaTable = lib.MediaTable
local overrideMedia = lib.OverrideMedia
-- create mediatype constants
lib.MediaType.BACKGROUND = "background" -- background textures
lib.MediaType.BORDER = "border" -- border textures
lib.MediaType.FONT = "font" -- fonts
lib.MediaType.STATUSBAR = "statusbar" -- statusbar textures
lib.MediaType.SOUND = "sound" -- sound files
-- populate lib with default Blizzard data
-- BACKGROUND
if not lib.MediaTable.background then lib.MediaTable.background = {} end
lib.MediaTable.background["None"] = [[]]
lib.MediaTable.background["Blizzard Dialog Background"] = [[Interface\DialogFrame\UI-DialogBox-Background]]
lib.MediaTable.background["Blizzard Dialog Background Dark"] = [[Interface\DialogFrame\UI-DialogBox-Background-Dark]]
lib.MediaTable.background["Blizzard Dialog Background Gold"] = [[Interface\DialogFrame\UI-DialogBox-Gold-Background]]
lib.MediaTable.background["Blizzard Low Health"] = [[Interface\FullScreenTextures\LowHealth]]
lib.MediaTable.background["Blizzard Marble"] = [[Interface\FrameGeneral\UI-Background-Marble]]
lib.MediaTable.background["Blizzard Out of Control"] = [[Interface\FullScreenTextures\OutOfControl]]
lib.MediaTable.background["Blizzard Parchment"] = [[Interface\AchievementFrame\UI-Achievement-Parchment-Horizontal]]
lib.MediaTable.background["Blizzard Parchment 2"] = [[Interface\AchievementFrame\UI-GuildAchievement-Parchment-Horizontal]]
lib.MediaTable.background["Blizzard Rock"] = [[Interface\FrameGeneral\UI-Background-Rock]]
lib.MediaTable.background["Blizzard Tabard Background"] = [[Interface\TabardFrame\TabardFrameBackground]]
lib.MediaTable.background["Blizzard Tooltip"] = [[Interface\Tooltips\UI-Tooltip-Background]]
lib.MediaTable.background["Solid"] = [[Interface\Buttons\WHITE8X8]]
lib.DefaultMedia.background = "None"
-- BORDER
if not lib.MediaTable.border then lib.MediaTable.border = {} end
lib.MediaTable.border["None"] = [[]]
lib.MediaTable.border["Blizzard Achievement Wood"] = [[Interface\AchievementFrame\UI-Achievement-WoodBorder]]
lib.MediaTable.border["Blizzard Chat Bubble"] = [[Interface\Tooltips\ChatBubble-Backdrop]]
lib.MediaTable.border["Blizzard Dialog"] = [[Interface\DialogFrame\UI-DialogBox-Border]]
lib.MediaTable.border["Blizzard Dialog Gold"] = [[Interface\DialogFrame\UI-DialogBox-Gold-Border]]
lib.MediaTable.border["Blizzard Party"] = [[Interface\CHARACTERFRAME\UI-Party-Border]]
lib.MediaTable.border["Blizzard Tooltip"] = [[Interface\Tooltips\UI-Tooltip-Border]]
lib.DefaultMedia.border = "None"
-- FONT
if not lib.MediaTable.font then lib.MediaTable.font = {} end
local SML_MT_font = lib.MediaTable.font
if locale == "koKR" then
LOCALE_MASK = lib.LOCALE_BIT_koKR
--
SML_MT_font["굵은 글꼴"] = [[Fonts\2002B.TTF]]
SML_MT_font["기본 글꼴"] = [[Fonts\2002.TTF]]
SML_MT_font["데미지 글꼴"] = [[Fonts\K_Damage.TTF]]
SML_MT_font["퀘스트 글꼴"] = [[Fonts\K_Pagetext.TTF]]
--
lib.DefaultMedia["font"] = "기본 글꼴" -- someone from koKR please adjust if needed
--
elseif locale == "zhCN" then
LOCALE_MASK = lib.LOCALE_BIT_zhCN
--
SML_MT_font["伤害数字"] = [[Fonts\ARKai_C.ttf]]
SML_MT_font["默认"] = [[Fonts\ARKai_T.ttf]]
SML_MT_font["聊天"] = [[Fonts\ARHei.ttf]]
--
lib.DefaultMedia["font"] = "默认" -- someone from zhCN please adjust if needed
--
elseif locale == "zhTW" then
LOCALE_MASK = lib.LOCALE_BIT_zhTW
--
SML_MT_font["提示訊息"] = [[Fonts\bHEI00M.ttf]]
SML_MT_font["聊天"] = [[Fonts\bHEI01B.ttf]]
SML_MT_font["傷害數字"] = [[Fonts\bKAI00M.ttf]]
SML_MT_font["預設"] = [[Fonts\bLEI00D.ttf]]
--
lib.DefaultMedia["font"] = "預設" -- someone from zhTW please adjust if needed
elseif locale == "ruRU" then
LOCALE_MASK = lib.LOCALE_BIT_ruRU
--
SML_MT_font["Arial Narrow"] = [[Fonts\ARIALN.TTF]]
SML_MT_font["Friz Quadrata TT"] = [[Fonts\FRIZQT__.TTF]]
SML_MT_font["Morpheus"] = [[Fonts\MORPHEUS.TTF]]
SML_MT_font["Nimrod MT"] = [[Fonts\NIM_____.ttf]]
SML_MT_font["Skurri"] = [[Fonts\SKURRI.TTF]]
--
lib.DefaultMedia.font = "Friz Quadrata TT"
--
else
LOCALE_MASK = lib.LOCALE_BIT_western
locale_is_western = true
--
SML_MT_font["Arial Narrow"] = [[Fonts\ARIALN.TTF]]
SML_MT_font["Friz Quadrata TT"] = [[Fonts\FRIZQT__.TTF]]
SML_MT_font["Morpheus"] = [[Fonts\MORPHEUS.TTF]]
SML_MT_font["Skurri"] = [[Fonts\SKURRI.TTF]]
--
lib.DefaultMedia.font = "Friz Quadrata TT"
--
end
-- STATUSBAR
if not lib.MediaTable.statusbar then lib.MediaTable.statusbar = {} end
lib.MediaTable.statusbar["Blizzard"] = [[Interface\TargetingFrame\UI-StatusBar]]
lib.MediaTable.statusbar["Blizzard Character Skills Bar"] = [[Interface\PaperDollInfoFrame\UI-Character-Skills-Bar]]
lib.DefaultMedia.statusbar = "Blizzard"
-- SOUND
if not lib.MediaTable.sound then lib.MediaTable.sound = {} end
lib.MediaTable.sound["None"] = [[Interface\Quiet.ogg]] -- Relies on the fact that PlaySound[File] doesn't error on non-existing input.
lib.DefaultMedia.sound = "None"
local function rebuildMediaList(mediatype)
local mtable = mediaTable[mediatype]
if not mtable then return end
if not mediaList[mediatype] then mediaList[mediatype] = {} end
local mlist = mediaList[mediatype]
-- list can only get larger, so simply overwrite it
local i = 0
for k in pairs(mtable) do
i = i + 1
mlist[i] = k
end
table_sort(mlist)
end
function lib:Register(mediatype, key, data, langmask)
if type(mediatype) ~= "string" then
error(MAJOR..":Register(mediatype, key, data, langmask) - mediatype must be string, got "..type(mediatype))
end
if type(key) ~= "string" then
error(MAJOR..":Register(mediatype, key, data, langmask) - key must be string, got "..type(key))
end
mediatype = mediatype:lower()
if mediatype == lib.MediaType.FONT and ((langmask and band(langmask, LOCALE_MASK) == 0) or not (langmask or locale_is_western)) then return false end
if not mediaTable[mediatype] then mediaTable[mediatype] = {} end
local mtable = mediaTable[mediatype]
if mtable[key] then return false end
mtable[key] = data
rebuildMediaList(mediatype)
self.callbacks:Fire("LibSharedMedia_Registered", mediatype, key)
return true
end
function lib:Fetch(mediatype, key, noDefault)
local mtt = mediaTable[mediatype]
local overridekey = overrideMedia[mediatype]
local result = mtt and ((overridekey and mtt[overridekey] or mtt[key]) or (not noDefault and defaultMedia[mediatype] and mtt[defaultMedia[mediatype]])) or nil
return result ~= "" and result or nil
end
function lib:IsValid(mediatype, key)
return mediaTable[mediatype] and (not key or mediaTable[mediatype][key]) and true or false
end
function lib:HashTable(mediatype)
return mediaTable[mediatype]
end
function lib:List(mediatype)
if not mediaTable[mediatype] then
return nil
end
if not mediaList[mediatype] then
rebuildMediaList(mediatype)
end
return mediaList[mediatype]
end
function lib:GetGlobal(mediatype)
return overrideMedia[mediatype]
end
function lib:SetGlobal(mediatype, key)
if not mediaTable[mediatype] then
return false
end
overrideMedia[mediatype] = (key and mediaTable[mediatype][key]) and key or nil
self.callbacks:Fire("LibSharedMedia_SetGlobal", mediatype, overrideMedia[mediatype])
return true
end
function lib:GetDefault(mediatype)
return defaultMedia[mediatype]
end
function lib:SetDefault(mediatype, key)
if mediaTable[mediatype] and mediaTable[mediatype][key] and not defaultMedia[mediatype] then
defaultMedia[mediatype] = key
return true
else
return false
end
end
+4
View File
@@ -0,0 +1,4 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/
..\FrameXML\UI.xsd">
<Script file="LibSharedMedia-3.0.lua" />
</Ui>
+51
View File
@@ -0,0 +1,51 @@
-- $Id: LibStub.lua 76 2007-09-03 01:50:17Z mikk $
-- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/wiki/LibStub for more info
-- LibStub is hereby placed in the Public Domain
-- Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke
local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS!
local LibStub = _G[LIBSTUB_MAJOR]
-- Check to see is this version of the stub is obsolete
if not LibStub or LibStub.minor < LIBSTUB_MINOR then
LibStub = LibStub or {libs = {}, minors = {} }
_G[LIBSTUB_MAJOR] = LibStub
LibStub.minor = LIBSTUB_MINOR
-- LibStub:NewLibrary(major, minor)
-- major (string) - the major version of the library
-- minor (string or number ) - the minor version of the library
--
-- returns nil if a newer or same version of the lib is already present
-- returns empty library object or old library object if upgrade is needed
function LibStub:NewLibrary(major, minor)
assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)")
minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.")
local oldminor = self.minors[major]
if oldminor and oldminor >= minor then return nil end
self.minors[major], self.libs[major] = minor, self.libs[major] or {}
return self.libs[major], oldminor
end
-- LibStub:GetLibrary(major, [silent])
-- major (string) - the major version of the library
-- silent (boolean) - if true, library is optional, silently return nil if its not found
--
-- throws an error if the library can not be found (except silent is set)
-- returns the library object if found
function LibStub:GetLibrary(major, silent)
if not self.libs[major] and not silent then
error(("Cannot find a library instance of %q."):format(tostring(major)), 2)
end
return self.libs[major], self.minors[major]
end
-- LibStub:IterateLibraries()
--
-- Returns an iterator for the currently registered libraries
function LibStub:IterateLibraries()
return pairs(self.libs)
end
setmetatable(LibStub, { __call = LibStub.GetLibrary })
end
+13
View File
@@ -0,0 +1,13 @@
## Interface: 40200
## Title: Lib: LibStub
## Notes: Universal Library Stub
## Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel
## X-Website: http://www.wowace.com/addons/libstub/
## X-Category: Library
## X-License: Public Domain
## X-Curse-Packaged-Version: r95
## X-Curse-Project-Name: LibStub
## X-Curse-Project-ID: libstub
## X-Curse-Repository-ID: wow/libstub/mainline
LibStub.lua
+41
View File
@@ -0,0 +1,41 @@
debugstack = debug.traceback
strmatch = string.match
loadfile("../LibStub.lua")()
local lib, oldMinor = LibStub:NewLibrary("Pants", 1) -- make a new thingy
assert(lib) -- should return the library table
assert(not oldMinor) -- should not return the old minor, since it didn't exist
-- the following is to create data and then be able to check if the same data exists after the fact
function lib:MyMethod()
end
local MyMethod = lib.MyMethod
lib.MyTable = {}
local MyTable = lib.MyTable
local newLib, newOldMinor = LibStub:NewLibrary("Pants", 1) -- try to register a library with the same version, should silently fail
assert(not newLib) -- should not return since out of date
local newLib, newOldMinor = LibStub:NewLibrary("Pants", 0) -- try to register a library with a previous, should silently fail
assert(not newLib) -- should not return since out of date
local newLib, newOldMinor = LibStub:NewLibrary("Pants", 2) -- register a new version
assert(newLib) -- library table
assert(rawequal(newLib, lib)) -- should be the same reference as the previous
assert(newOldMinor == 1) -- should return the minor version of the previous version
assert(rawequal(lib.MyMethod, MyMethod)) -- verify that values were saved
assert(rawequal(lib.MyTable, MyTable)) -- verify that values were saved
local newLib, newOldMinor = LibStub:NewLibrary("Pants", "Blah 3 Blah") -- register a new version with a string minor version (instead of a number)
assert(newLib) -- library table
assert(newOldMinor == 2) -- previous version was 2
local newLib, newOldMinor = LibStub:NewLibrary("Pants", "Blah 4 and please ignore 15 Blah") -- register a new version with a string minor version (instead of a number)
assert(newLib)
assert(newOldMinor == 3) -- previous version was 3 (even though it gave a string)
local newLib, newOldMinor = LibStub:NewLibrary("Pants", 5) -- register a new library, using a normal number instead of a string
assert(newLib)
assert(newOldMinor == 4) -- previous version was 4 (even though it gave a string)
+27
View File
@@ -0,0 +1,27 @@
debugstack = debug.traceback
strmatch = string.match
loadfile("../LibStub.lua")()
for major, library in LibStub:IterateLibraries() do
-- check that MyLib doesn't exist yet, by iterating through all the libraries
assert(major ~= "MyLib")
end
assert(not LibStub:GetLibrary("MyLib", true)) -- check that MyLib doesn't exist yet by direct checking
assert(not pcall(LibStub.GetLibrary, LibStub, "MyLib")) -- don't silently fail, thus it should raise an error.
local lib = LibStub:NewLibrary("MyLib", 1) -- create the lib
assert(lib) -- check it exists
assert(rawequal(LibStub:GetLibrary("MyLib"), lib)) -- verify that :GetLibrary("MyLib") properly equals the lib reference
assert(LibStub:NewLibrary("MyLib", 2)) -- create a new version
local count=0
for major, library in LibStub:IterateLibraries() do
-- check that MyLib exists somewhere in the libraries, by iterating through all the libraries
if major == "MyLib" then -- we found it!
count = count +1
assert(rawequal(library, lib)) -- verify that the references are equal
end
end
assert(count == 1) -- verify that we actually found it, and only once
+14
View File
@@ -0,0 +1,14 @@
debugstack = debug.traceback
strmatch = string.match
loadfile("../LibStub.lua")()
local proxy = newproxy() -- non-string
assert(not pcall(LibStub.NewLibrary, LibStub, proxy, 1)) -- should error, proxy is not a string, it's userdata
local success, ret = pcall(LibStub.GetLibrary, proxy, true)
assert(not success or not ret) -- either error because proxy is not a string or because it's not actually registered.
assert(not pcall(LibStub.NewLibrary, LibStub, "Something", "No number in here")) -- should error, minor has no string in it.
assert(not LibStub:GetLibrary("Something", true)) -- shouldn't've created it from the above statement
+41
View File
@@ -0,0 +1,41 @@
debugstack = debug.traceback
strmatch = string.match
loadfile("../LibStub.lua")()
-- Pretend like loaded libstub is old and doesn't have :IterateLibraries
assert(LibStub.minor)
LibStub.minor = LibStub.minor - 0.0001
LibStub.IterateLibraries = nil
loadfile("../LibStub.lua")()
assert(type(LibStub.IterateLibraries)=="function")
-- Now pretend that we're the same version -- :IterateLibraries should NOT be re-created
LibStub.IterateLibraries = 123
loadfile("../LibStub.lua")()
assert(LibStub.IterateLibraries == 123)
-- Now pretend that a newer version is loaded -- :IterateLibraries should NOT be re-created
LibStub.minor = LibStub.minor + 0.0001
loadfile("../LibStub.lua")()
assert(LibStub.IterateLibraries == 123)
-- Again with a huge number
LibStub.minor = LibStub.minor + 1234567890
loadfile("../LibStub.lua")()
assert(LibStub.IterateLibraries == 123)
print("OK")
+208
View File
@@ -0,0 +1,208 @@
--File Revision: 1
--Last Modification: 27/07/2013
-- Change Log:
-- 27/07/2013: Finished alpha version.
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> global name declaration
_detalhes = LibStub("AceAddon-3.0"):NewAddon("_detalhes", "AceTimer-3.0", "AceComm-3.0")
_detalhes.version = "Alpha 001"
_detalhes.realversion = 1
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> initialization stuff
do
local _detalhes = _G._detalhes
--> startup
_detalhes.initializing = true
_detalhes.enabled = true
_detalhes.__index = _detalhes
_detalhes._tempo = time()
_detalhes.debug = false
--> containers
--> armazenas as funções do parser - All parse functions
_detalhes.parser = {}
--> armazena os escudos - Shields information for absorbs
_detalhes.escudos = {}
--> armazena os overwirtes de spells pelo usuario
_detalhes.SpellOverwriteUser = {}
--> armazena as funções dos frames - Frames functions
_detalhes.gump = {}
--> armazena as funções para inicialização dos dados - Metatable functions
_detalhes.refresh = {}
--> armazena as funções para limpar e guardas os dados - Metatable functions
_detalhes.clear = {}
--> armazena as fontstring usadas no addon - Store labels (fontstrings)
_detalhes.font_pool = {}
--> armazena a config do painel de fast switch
_detalhes.switch = {}
--> armazena os estilos salvos
_detalhes.savedStyles = {}
--> armazena quais atributos possue janela de atributos - contain attributes and sub attributos wich have a detailed window (left click on a row)
_detalhes.row_singleclick_overwrite = {}
--> report
_detalhes.ReportOptions = {}
--> armazena os buffs registrados - store buffs ids and functions
_detalhes.Buffs = {} --> initialize buff table
--> Plugins
--> raid -------------------------------------------------------------------
--> general function for raid mode plugins
_detalhes.RaidTables = {}
--> menu for raid modes
_detalhes.RaidTables.Menu = {}
--> plugin objects for raid mode
_detalhes.RaidTables.Plugins = {}
--> name to plugin object
_detalhes.RaidTables.NameTable = {}
--> solo -------------------------------------------------------------------
--> general functions for solo mode plugins
_detalhes.SoloTables = {}
--> maintain plugin menu
_detalhes.SoloTables.Menu = {}
--> plugins objects for solo mode
_detalhes.SoloTables.Plugins = {}
--> name to plugin object
_detalhes.SoloTables.NameTable = {}
--> toolbar -------------------------------------------------------------------
--> plugins container
_detalhes.ToolBar = {}
--> current showing icons
_detalhes.ToolBar.Shown = {}
--> plugin objects
_detalhes.ToolBar.Plugins = {}
--> name to plugin object
_detalhes.ToolBar.NameTable = {}
--> statusbar -------------------------------------------------------------------
--> plugins container
_detalhes.StatusBar = {}
--> maintain plugin menu
_detalhes.StatusBar.Menu = {}
--> plugins object
_detalhes.StatusBar.Plugins = {}
--> name to plugin object
_detalhes.StatusBar.NameTable = {}
--> constants
_detalhes._detalhes_props = {
DATA_TYPE_START = 1, --> Something on start
DATA_TYPE_END = 2, --> Something on end
MODO_ALONE = 1, --> Solo
MODO_GROUP = 2, --> Group
MODO_ALL = 3, --> Everything
MODO_RAID = 4, --> Raid
}
_detalhes.modos = {
alone = 1, --> Solo
group = 2, --> Group
all = 3, --> Everything
raid = 4 --> Raid
}
_detalhes.flags = {
--> Player and Pet
player = 0x00000001,--> player character
pet = 0x00000002, --> pet mobile
--> Group
in_group = 0x00000100,--> in group
player_in_group = 0x00000101, --> player in group
--> Friendship
friend = 0x00000010,--> friend (same faction)
friend_in_group = 0x00000110, --> friend in group
--> Enemies
neutral = 0x00000020,--> neutral
enemy = 0x00000040--> enemy
}
_detalhes.divisores = {
abre = "(", --> open
fecha = ")", --> close
colocacao = ". " --> dot
}
local Loc = LibStub ("AceLocale-3.0"):GetLocale ("Details")
_detalhes.segmentos = {
label = Loc ["STRING_SEGMENT"]..": ",
overall = Loc ["STRING_TOTAL"],
overall_standard = Loc ["STRING_OVERALL"],
current = Loc ["STRING_CURRENT"],
current_standard = Loc ["STRING_CURRENTFIGHT"],
past = Loc ["STRING_FIGHTNUMBER"]
}
_detalhes._detalhes_props["modo_nome"] = {
[_detalhes._detalhes_props["MODO_ALONE"]] = Loc ["STRING_MODE_SELF"],
[_detalhes._detalhes_props["MODO_GROUP"]] = Loc ["STRING_MODE_GROUP"],
[_detalhes._detalhes_props["MODO_ALL"]] = Loc ["STRING_MODE_ALL"],
[_detalhes._detalhes_props["MODO_RAID"]] = Loc ["STRING_MODE_RAID"]
}
_detalhes.icones = {
--> report window
report = {
up = "Interface\\FriendsFrame\\UI-Toast-FriendOnlineIcon",
down = "Interface\\ItemAnimations\\MINIMAP\\TRACKING\\Profession",
disabled = "Interface\\ItemAnimations\\MINIMAP\\TRACKING\\Profession",
highlight = nil
}
}
_detalhes.missTypes = {"ABSORB", "BLOCK", "DEFLECT", "DODGE", "EVADE", "IMMUNE", "MISS", "PARRY", "REFLECT", "RESIST"} --> do not localize-me
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> frames
local _CreateFrame = CreateFrame --api locals
local _UIParent = UIParent --api locals
--> Info Window
_detalhes.janela_info = _CreateFrame ("Frame", "Details_JanelaInfo", _UIParent)
--> Event Frame
_detalhes.listener = _CreateFrame ("Frame", nil, _UIParent)
_detalhes.listener:RegisterEvent ("ADDON_LOADED")
_detalhes.listener:RegisterEvent ("PLAYER_LOGOUT")
_detalhes.listener:SetFrameStrata ("LOW")
_detalhes.listener:SetFrameLevel (9)
_detalhes.listener.FrameTime = 0
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> functions
--> register textures and fonts for shared media
local SharedMedia = LibStub:GetLibrary ("LibSharedMedia-3.0")
SharedMedia:Register ("statusbar", "Details D'ictum", [[Interface\AddOns\Details\images\bar4]])
--> global 'vardump' for dump table contents over chat panel
function vardump (t)
if (type (t) ~= "table") then
return
end
for a,b in pairs (t) do
print (a,b)
end
end
--> delay messages
function _detalhes:DelayMsg (msg)
_detalhes.delaymsgs = _detalhes.delaymsgs or {}
_detalhes.delaymsgs [#_detalhes.delaymsgs+1] = msg
end
function _detalhes:ShowDelayMsg()
if (_detalhes.delaymsgs and #_detalhes.delaymsgs > 0) then
for _, msg in ipairs (_detalhes.delaymsgs) do
print (msg)
end
end
_detalhes.delaymsgs = {}
end
end
+456
View File
@@ -0,0 +1,456 @@
--[[
-------Details! Addon
-------Class Combat
-------This file control combat class. A combat is a object wich hold combat attributes.
-------The numeric part of table is compost by 4 indexes: [1] damage, [2] heal, [3] energies and [4] misc
]]
local _detalhes = _G._detalhes
--shortcuts
local combate = _detalhes.combate
local container_combatentes = _detalhes.container_combatentes
--flags
local REACTION_HOSTILE = 0x00000040
local CONTROL_PLAYER = 0x00000100
--locals
local _setmetatable = setmetatable --> lua api
local _ipairs = ipairs --> lua api
local _pairs = pairs --> lua api
local _bit_band = bit.band --> lua api
local _date = date --> lua api
local _UnitName = UnitName --> wow api
--time hold
local _tempo = time()
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--[[ __call function, get an actor from current combat.
combatTable ( index, actorName )
index: container number [1] damage, [2] heal, [3] energies and [4] misc
actorName: name of an actor (player, npc, pet, etc) --]]
_detalhes.call_combate = function (self, class_type, name)
local container = self[class_type]
local index_mapa = container._NameIndexTable [name]
local actor = container._ActorTable [index_mapa]
return actor
end
combate.__call = _detalhes.call_combate
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--[[ Class Constructor ]]
function combate:NovaTabela (iniciada, _tabela_overall, combatId, ...)
local esta_tabela = {}
esta_tabela [1] = container_combatentes:NovoContainer (_detalhes.container_type.CONTAINER_DAMAGE_CLASS, esta_tabela, combatId) --> Damage
esta_tabela [2] = container_combatentes:NovoContainer (_detalhes.container_type.CONTAINER_HEAL_CLASS, esta_tabela, combatId) --> Healing
esta_tabela [3] = container_combatentes:NovoContainer (_detalhes.container_type.CONTAINER_ENERGY_CLASS, esta_tabela, combatId) --> Energies
esta_tabela [4] = container_combatentes:NovoContainer (_detalhes.container_type.CONTAINER_MISC_CLASS, esta_tabela, combatId) --> Misc
esta_tabela [5] = container_combatentes:NovoContainer (_detalhes.container_type.CONTAINER_DAMAGE_CLASS, esta_tabela, combatId) --> place holder for customs
_setmetatable (esta_tabela, combate)
--> debug
esta_tabela.meu_tipo = "classe_combate"
--> try discover if is a pvp combat
local who_serial, who_name, who_flags, alvo_serial, alvo_name, alvo_flags = ...
if (who_serial) then --> aqui irá identificar o boss ou o oponente
if (alvo_name and _bit_band (alvo_flags, REACTION_HOSTILE) ~= 0) then --> tentando pegar o inimigo pelo alvo
esta_tabela.contra = alvo_name
if (_bit_band (alvo_flags, CONTROL_PLAYER) ~= 0) then
esta_tabela.pvp = true --> o alvo é da facção oposta ou foi dado mind control
end
elseif (who_name and _bit_band (who_flags, REACTION_HOSTILE) ~= 0) then --> tentando pegar o inimigo pelo who caso o mob é quem deu o primeiro hit
esta_tabela.contra = who_name
if (_bit_band (who_flags, CONTROL_PLAYER) ~= 0) then
esta_tabela.pvp = true --> o who é da facção oposta ou foi dado mind control
end
else
esta_tabela.pvp = true --> se ambos são friendly, seria isso um PVP entre jogadores da mesma facções?
end
end
--> start/end time (duration)
esta_tabela.data_fim = 0
esta_tabela.data_inicio = 0
--esta_tabela.last_event = 0
--> record last event before dead
esta_tabela.last_events_tables = {}
--> record damage data
--esta_tabela.DpsGraphic = {max = 0}
--> time data container
esta_tabela.TimeData = _detalhes.timeContainer:CreateTimeTable()
--> Skill cache (not used)
esta_tabela.CombatSkillCache = {}
-- a tabela sem o tempo de inicio é a tabela descartavel do inicio do addon
if (iniciada) then
esta_tabela.start_time = _tempo
esta_tabela.end_time = nil
else
esta_tabela.start_time = 0
esta_tabela.end_time = nil
end
-- o container irá armazenar as classes de dano -- cria um novo container de indexes de seriais de jogadores --parâmetro 1 classe armazenada no container, parâmetro 2 = flag da classe
esta_tabela[1].need_refresh = true
esta_tabela[2].need_refresh = true
esta_tabela[3].need_refresh = true
esta_tabela[4].need_refresh = true
esta_tabela[5].need_refresh = true
if (_tabela_overall) then --> link é a tabela de combate do overall
esta_tabela[1].shadow = _tabela_overall[1] --> diz ao objeto qual a shadow dele na tabela overall
esta_tabela[2].shadow = _tabela_overall[2] --> diz ao objeto qual a shadow dele na tabela overall
esta_tabela[3].shadow = _tabela_overall[3] --> diz ao objeto qual a shadow dele na tabela overall
esta_tabela[4].shadow = _tabela_overall[4] --> diz ao objeto qual a shadow dele na tabela overall
end
-- abriga a tabela contendo o total de cada atributo
-- esta_tabela.barra_total = barra_total:NovaBarra()
--> barra total movido para um simples membro do combate:
esta_tabela.totals = {
0, --> dano
0, --> cura
{--> e_energy
mana = 0, --> mana
e_rage = 0, --> rage
e_energy = 0, --> energy (rogues cat)
runepower = 0 --> runepower (dk)
},
{--> misc
cc_break = 0, --> armazena quantas quebras de CC
ress = 0, --> armazena quantos pessoas ele reviveu
interrupt = 0, --> armazena quantos interrupt a pessoa deu
dispell = 0, --> armazena quantos dispell esta pessoa recebeu
dead = 0 --> armazena quantas vezes essa oessia morreu
}
}
esta_tabela.totals_grupo = {
0, --> dano
0, --> cura
{--> e_energy
mana = 0, --> mana
e_rage = 0, --> rage
e_energy = 0, --> energy (rogues cat)
runepower = 0 --> runepower (dk)
},
{--> misc
cc_break = 0, --> armazena quantas quebras de CC
ress = 0, --> armazena quantos pessoas ele reviveu
interrupt = 0, --> armazena quantos interrupt a pessoa deu
dispell = 0, --> armazena quantos dispell esta pessoa recebeu
dead = 0 --> armazena quantas vezes essa oessia morreu
}
}
return esta_tabela
end
function combate:GetTimeData (dataType)
--if (not dataType) then
return self.TimeData
--end
end
function combate:TravarTempos()
--é necessário travar o tempo em todos os atributos do combate.
for index, container in _ipairs (self) do -- aqui ele lista os tipos de atributo listado na lista acima
if (index ~= 3 and index ~= 4) then --> 3 é e_energy, não possui tempo // 4 é misc tbm não possui tempo
for _, jogador in _ipairs (container._ActorTable) do
if (jogador:Iniciar()) then -- retorna se ele esta com o dps ativo
jogador:TerminarTempo()
jogador:Iniciar (false) --trava o dps do jogador
jogador.last_events_table = {} --> elimina a tabela dos danos --não é mais usado desta forma
end
end
end
end
end
function combate:UltimaAcao (tempo)
if (tempo) then
self.last_event = tempo
else
return self.last_event
end
end
function combate:seta_data (tipo)
if (tipo == _detalhes._detalhes_props.DATA_TYPE_START) then
self.data_inicio = _date ("%H:%M:%S")
elseif (tipo == _detalhes._detalhes_props.DATA_TYPE_END) then
self.data_fim = _date ("%H:%M:%S")
end
end
function combate:GetActorList (container)
return self [container]._ActorTable
end
function combate:GetCombatTime()
if (self.end_time) then
return self.end_time - self.start_time
elseif (self.start_time and _detalhes.in_combat) then
return _tempo - self.start_time
else
return 0
end
end
function combate:GetTotal (attribute, subAttribute, onlyGroup)
if (attribute == 1 or attribute == 2) then
if (onlyGroup) then
return self.totals_grupo [attribute]
else
return self.totals [attribute]
end
elseif (attribute == 3 or attribute == 4) then
local subName = _detalhes:GetInternalSubAttributeName (attribute, subAttribute)
if (onlyGroup) then
return self.totals_grupo [attribute] [subName]
else
return self.totals [attribute] [subName]
end
end
return 0
end
function combate:seta_tempo_decorrido()
self.end_time = _tempo
end
function _detalhes.refresh:r_combate (tabela_combate, shadow)
_setmetatable (tabela_combate, _detalhes.combate)
tabela_combate.__index = _detalhes.combate
tabela_combate.shadow = shadow
end
function _detalhes.clear:c_combate (tabela_combate)
tabela_combate.__index = {}
tabela_combate.__call = {}
tabela_combate._combat_table = nil
tabela_combate.shadow = nil
end
combate.__sub = function (overall, combate)
--> foreach no dano
for index, classe_damage in _ipairs (combate[1]._ActorTable) do
local nome = classe_damage.nome
local no_overall = overall[1]._ActorTable [overall[1]._NameIndexTable [nome]]
no_overall = no_overall - classe_damage
local alvos = classe_damage.targets
for index, alvo in _ipairs (alvos._ActorTable) do
local alvo_overall = no_overall.targets._ActorTable [no_overall.targets._NameIndexTable [alvo.nome]]
alvo_overall = alvo_overall - alvo
end
local habilidades = classe_damage.spell_tables
for _spellid, habilidade in _pairs (habilidades._ActorTable) do
local habilidade_overall = no_overall.spell_tables._ActorTable [_spellid]
habilidade_overall = habilidade_overall - habilidade
local alvos = habilidade.targets
for index, alvo in _ipairs (alvos._ActorTable) do
local alvo_overall = habilidade_overall.targets._ActorTable [habilidade_overall.targets._NameIndexTable [alvo.nome]]
alvo_overall = alvo_overall - alvo
end
end
end
--> foreach na cura
for index, classe_heal in _ipairs (combate[2]._ActorTable) do
local nome = classe_heal.nome
local no_overall = overall[2]._ActorTable [overall[2]._NameIndexTable [nome]]
no_overall = no_overall - classe_heal
local alvos = classe_heal.targets
for index, alvo in _ipairs (alvos._ActorTable) do
local alvo_overall = no_overall.targets._ActorTable [no_overall.targets._NameIndexTable [alvo.nome]]
alvo_overall = alvo_overall - alvo
end
local habilidades = classe_heal.spell_tables
for _spellid, habilidade in _pairs (habilidades._ActorTable) do
local habilidade_overall = no_overall.spell_tables._ActorTable [_spellid]
habilidade_overall = habilidade_overall - habilidade
local alvos = habilidade.targets
for index, alvo in _ipairs (alvos._ActorTable) do
local alvo_overall = habilidade_overall.targets._ActorTable [habilidade_overall.targets._NameIndexTable [alvo.nome]]
alvo_overall = alvo_overall - alvo
end
end
end
--> foreach na e_energy
for index, classe_energy in _ipairs (combate[3]._ActorTable) do
local nome = classe_energy.nome
local no_overall = overall[3]._ActorTable [overall[3]._NameIndexTable [nome]]
no_overall = no_overall - classe_energy
local alvos = classe_energy.targets
for index, alvo in _ipairs (alvos._ActorTable) do
local alvo_overall = no_overall.targets._ActorTable [no_overall.targets._NameIndexTable [alvo.nome]]
alvo_overall = alvo_overall - alvo
end
local habilidades = classe_energy.spell_tables
for _spellid, habilidade in _pairs (habilidades._ActorTable) do
local habilidade_overall = no_overall.spell_tables._ActorTable [_spellid]
habilidade_overall = habilidade_overall - habilidade
local alvos = habilidade.targets
for index, alvo in _ipairs (alvos._ActorTable) do
local alvo_overall = habilidade_overall.targets._ActorTable [habilidade_overall.targets._NameIndexTable [alvo.nome]]
alvo_overall = alvo_overall - alvo
end
end
end
--> foreach no misc
for index, classe_misc in _ipairs (combate[4]._ActorTable) do
local nome = classe_misc.nome
local no_overall = overall[4]._ActorTable [overall[4]._NameIndexTable [nome]]
no_overall = no_overall - classe_misc
if (classe_misc.interrupt) then
local alvos = classe_misc.interrupt_targets
local habilidades = classe_misc.interrupt_spell_tables
for index, alvo in _ipairs (alvos._ActorTable) do
local alvo_overall = no_overall.interrupt_targets._ActorTable [no_overall.interrupt_targets._NameIndexTable [alvo.nome]]
alvo_overall = alvo_overall - alvo
end
for _spellid, habilidade in _pairs (habilidades._ActorTable) do
local habilidade_overall = no_overall.interrupt_spell_tables._ActorTable [_spellid]
habilidade_overall = habilidade_overall - habilidade
local alvos = habilidade.targets
for index, alvo in _ipairs (alvos._ActorTable) do
local alvo_overall = habilidade_overall.targets._ActorTable [habilidade_overall.targets._NameIndexTable [alvo.nome]]
alvo_overall = alvo_overall - alvo
end
end
end
if (classe_misc.ress) then
local alvos = classe_misc.ress_targets
local habilidades = classe_misc.ress_spell_tables
for index, alvo in _ipairs (alvos._ActorTable) do
local alvo_overall = no_overall.ress_targets._ActorTable [no_overall.ress_targets._NameIndexTable [alvo.nome]]
alvo_overall = alvo_overall - alvo
end
for _spellid, habilidade in _pairs (habilidades._ActorTable) do
local habilidade_overall = no_overall.ress_spell_tables._ActorTable [_spellid]
habilidade_overall = habilidade_overall - habilidade
local alvos = habilidade.targets
for index, alvo in _ipairs (alvos._ActorTable) do
local alvo_overall = habilidade_overall.targets._ActorTable [habilidade_overall.targets._NameIndexTable [alvo.nome]]
alvo_overall = alvo_overall - alvo
end
end
end
if (classe_misc.dispell) then
local alvos = classe_misc.dispell_targets
local habilidades = classe_misc.dispell_spell_tables
for index, alvo in _ipairs (alvos._ActorTable) do
local alvo_overall = no_overall.dispell_targets._ActorTable [no_overall.dispell_targets._NameIndexTable [alvo.nome]]
alvo_overall = alvo_overall - alvo
end
for _spellid, habilidade in _pairs (habilidades._ActorTable) do
local habilidade_overall = no_overall.dispell_spell_tables._ActorTable [_spellid]
habilidade_overall = habilidade_overall - habilidade
local alvos = habilidade.targets
for index, alvo in _ipairs (alvos._ActorTable) do
local alvo_overall = habilidade_overall.targets._ActorTable [habilidade_overall.targets._NameIndexTable [alvo.nome]]
alvo_overall = alvo_overall - alvo
end
end
end
if (classe_misc.cc_break) then
local alvos = classe_misc.cc_break_targets
local habilidades = classe_misc.cc_break_spell_tables
for index, alvo in _ipairs (alvos._ActorTable) do
local alvo_overall = no_overall.cc_break_targets._ActorTable [no_overall.cc_break_targets._NameIndexTable [alvo.nome]]
alvo_overall = alvo_overall - alvo
end
for _spellid, habilidade in _pairs (habilidades._ActorTable) do
local habilidade_overall = no_overall.cc_break_spell_tables._ActorTable [_spellid]
habilidade_overall = habilidade_overall - habilidade
local alvos = habilidade.targets
for index, alvo in _ipairs (alvos._ActorTable) do
local alvo_overall = habilidade_overall.targets._ActorTable [habilidade_overall.targets._NameIndexTable [alvo.nome]]
alvo_overall = alvo_overall - alvo
end
end
end
end
--> diminui o total
overall.totals[1] = overall.totals[1] - combate.totals[1]
overall.totals[2] = overall.totals[2] - combate.totals[2]
overall.totals[3].mana = overall.totals[3].mana - combate.totals[3].mana
overall.totals[3].e_rage = overall.totals[3].e_rage - combate.totals[3].e_rage
overall.totals[3].e_energy = overall.totals[3].e_energy - combate.totals[3].e_energy
overall.totals[3].runepower = overall.totals[3].runepower - combate.totals[3].runepower
overall.totals[4].cc_break = overall.totals[4].cc_break - combate.totals[4].cc_break
overall.totals[4].ress = overall.totals[4].ress - combate.totals[4].ress
overall.totals[4].interrupt = overall.totals[4].interrupt - combate.totals[4].interrupt
overall.totals[4].dispell = overall.totals[4].dispell - combate.totals[4].dispell
overall.totals[4].dead = overall.totals[4].dead - combate.totals[4].dead
overall.totals_grupo[1] = overall.totals_grupo[1] - combate.totals_grupo[1]
overall.totals_grupo[2] = overall.totals_grupo[2] - combate.totals_grupo[2]
overall.totals_grupo[3].mana = overall.totals_grupo[3].mana - combate.totals_grupo[3].mana
overall.totals_grupo[3].e_rage = overall.totals_grupo[3].e_rage - combate.totals_grupo[3].e_rage
overall.totals_grupo[3].e_energy = overall.totals_grupo[3].e_energy - combate.totals_grupo[3].e_energy
overall.totals_grupo[3].runepower = overall.totals_grupo[3].runepower - combate.totals_grupo[3].runepower
overall.totals_grupo[4].cc_break = overall.totals_grupo[4].cc_break - combate.totals_grupo[4].cc_break
overall.totals_grupo[4].ress = overall.totals_grupo[4].ress - combate.totals_grupo[4].ress
overall.totals_grupo[4].interrupt = overall.totals_grupo[4].interrupt - combate.totals_grupo[4].interrupt
overall.totals_grupo[4].dispell = overall.totals_grupo[4].dispell - combate.totals_grupo[4].dispell
overall.totals_grupo[4].dead = overall.totals_grupo[4].dead - combate.totals_grupo[4].dead
return overall
end
function _detalhes:UpdateCombat()
_tempo = _detalhes._tempo
end
+137
View File
@@ -0,0 +1,137 @@
local _detalhes = _G._detalhes
local AceLocale = LibStub ("AceLocale-3.0")
local Loc = AceLocale:GetLocale ( "Details" )
--lua locals
local _cstr = string.format
local _math_floor = math.floor
local _table_sort = table.sort
local _table_insert = table.insert
local _table_size = table.getn
local _setmetatable = setmetatable
local _ipairs = ipairs
local _pairs = pairs
local _rawget= rawget
local _math_min = math.min
local _math_max = math.max
local _bit_band = bit.band
local _unpack = unpack
local _type = type
--api locals
local _GetSpellInfo = _detalhes.getspellinfo
local _UnitName = UnitName
local _IsInRaid = IsInRaid
local _IsInGroup = IsInGroup
local _GetNumGroupMembers = GetNumGroupMembers
local _GetNumPartyMembers = GetNumPartyMembers or GetNumSubgroupMembers
local _GetNumRaidMembers = GetNumRaidMembers or GetNumGroupMembers
local _GetUnitName = GetUnitName
local gump = _detalhes.gump
local atributo_custom = _detalhes.atributo_custom
function atributo_custom:RefreshWindow (instancia, _combat, forcar, exportar)
--> partir do principio que:
-- sempre vai ter um SPELLID
-- não vai ter target ou input output
--> instancia.sub_atributo armazena o index da tabela de custons
local CustomObject = _detalhes.custom [instancia.sub_atributo]
_combat.totals [CustomObject.name] = 0
instancia.customName = CustomObject.name
--print (CustomObject)
--print (CustomObject.source)
--print ("source: " .. CustomObject.source)
if (not CustomObject.source) then
print ("Sem Source")
return
elseif (CustomObject.source == "") then
print ("Source esta em branco")
return
end
--print ("atributo " .. CustomObject.attribute)
if (CustomObject.source == "[raid]") then
if (_IsInRaid()) then
for i = 1, _GetNumGroupMembers(), 1 do
local nome = _GetUnitName ("raid"..i, true):gsub (("%s+"), "")
local Actor = _combat (CustomObject.attribute, nome)
if (Actor) then
Actor:Custom (CustomObject.name, _combat, CustomObject.sattribute, CustomObject.spell, CustomObject.target)
end
end
elseif (_IsInGroup()) then
for i = 1, _GetNumGroupMembers()-1, 1 do
local nome = _GetUnitName ("raid"..i, true):gsub (("%s+"), "")
local Actor = _combat (CustomObject.attribute, nome)
if (Actor) then
Actor:Custom (CustomObject.name, _combat, CustomObject.sattribute, CustomObject.spell, CustomObject.target)
end
end
local Actor = _combat (CustomObject.attribute, _detalhes.playername)
if (Actor) then
Actor:Custom (CustomObject.name, _combat, CustomObject.sattribute, CustomObject.spell, CustomObject.target)
end
else
local Actor = _combat (CustomObject.attribute, _detalhes.playername)
if (Actor) then
Actor:Custom (CustomObject.name, _combat, CustomObject.sattribute, CustomObject.spell, CustomObject.target)
end
end
elseif (CustomObject.source == "[all]") then
for _, Actor in _ipairs (_combat [CustomObject.attribute]._ActorTable) do
Actor:Custom (CustomObject.name, _combat, CustomObject.sattribute, CustomObject.spell, CustomObject.target)
end
elseif (CustomObject.source == "[player]") then
local Actor = _combat (CustomObject.attribute, _detalhes.playername)
if (Actor) then
Actor:Custom (CustomObject.name, _combat, CustomObject.sattribute, CustomObject.spell, CustomObject.target)
end
else
local _thisActor = _combat (CustomObject.attribute, CustomObject.source)
if (_thisActor) then
_thisActor:Custom (CustomObject.name, _combat, CustomObject.sattribute, CustomObject.spell, CustomObject.target)
end
end
--> agora result tem os atores que usaram a habilidade
if (CustomObject.attribute == 1) then
return _detalhes.atributo_damage:RefreshWindow (instancia, _combat, forcar, exportar)
elseif (CustomObject.attribute == 2) then
_detalhes.atributo_heal:RefreshWindow (instancia, _combat, forcar, exportar)
end
--> aqui precisa fazer algo para retornar algo pro report reconhecer a tabela
end
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,364 @@
--[[ classe do dano aplicado, usado nos eventos:
- SPELL_PERIODIC_DAMAGE
- SPELL_DAMAGE
- SWING_DAMAGE
- RANGE_DAMAGE
Parents:
addon -> combate atual -> Npc/Player Swicth -> Container de Habilidades -> esta tabela
]]
local _detalhes = _G._detalhes
local gump = _detalhes.gump
local alvo_da_habilidade = _detalhes.alvo_da_habilidade
local habilidade_dano = _detalhes.habilidade_dano
local container_combatentes = _detalhes.container_combatentes
local container_damage_target = _detalhes.container_type.CONTAINER_DAMAGETARGET_CLASS
--lua locals
local _setmetatable = setmetatable
local _ipairs = ipairs
local _pairs = pairs
--api locals
local _UnitAura = UnitAura
--local _GetSpellInfo = _detalhes.getspellinfo
local container_playernpc = _detalhes.container_type.CONTAINER_PLAYERNPC
local _recording_ability_with_buffs = false
--id, nome, type, miss, dano, cura, overkill, school, resisted, blocked, absorbed, critico, glacing, crushing
function habilidade_dano:NovaTabela (id, link, token) --aqui eu não sei que parâmetros passar
local esta_tabela = {}
_setmetatable (esta_tabela, habilidade_dano)
esta_tabela.quem_sou = "classe_damage_habilidade"
-- esta_tabela.jogador = serial
esta_tabela.total = 0 --total de dano aplicado por esta habilidade
esta_tabela.counter = 0 --conta quantas vezes a habilidade foi chamada
esta_tabela.id = id
esta_tabela.school = 0
--> normal hits
--esta_tabela.normal = {["min"] = 0, ["max"] = 0, ["amt"] = 0, ["dmg"] = 0}
esta_tabela.n_min = 0
esta_tabela.n_max = 0
esta_tabela.n_amt = 0
esta_tabela.n_dmg = 0
--> hits criticos
--esta_tabela.critico = {["min"] = 0, ["max"] = 0, ["amt"] = 0, ["dmg"] = 0}
esta_tabela.c_min = 0
esta_tabela.c_max = 0
esta_tabela.c_amt = 0
esta_tabela.c_dmg = 0
--> hit glacing
--esta_tabela.glacing = {["min"] = 0, ["max"] = 0, ["amt"] = 0, ["dmg"] = 0}
esta_tabela.g_min = 0
esta_tabela.g_max = 0
esta_tabela.g_amt = 0
esta_tabela.g_dmg = 0
--informações e detalhes gerais desta habilidade
--esta_tabela.resisted = {["min"] = 0, ["max"] = 0, ["amt"] = 0, ["dmg"] = 0}
esta_tabela.r_min = 0
esta_tabela.r_max = 0
esta_tabela.r_amt = 0
esta_tabela.r_dmg = 0
--esta_tabela.blocked = {["min"] = 0, ["max"] = 0, ["amt"] = 0, ["dmg"] = 0}
esta_tabela.b_min = 0
esta_tabela.b_max = 0
esta_tabela.b_amt = 0
esta_tabela.b_dmg = 0
--esta_tabela.absorbed = {["min"] = 0, ["max"] = 0, ["amt"] = 0, ["dmg"] = 0}
esta_tabela.a_min = 0
esta_tabela.a_max = 0
esta_tabela.a_amt = 0
esta_tabela.a_dmg = 0
esta_tabela.crushing = 0 -- ??
esta_tabela.targets = container_combatentes:NovoContainer (container_damage_target)
if (link) then
esta_tabela.targets.shadow = link.targets
end
if (token == "SPELL_PERIODIC_DAMAGE") then
_detalhes:SpellIsDot (id)
end
return esta_tabela
end
function habilidade_dano:AddMiss (serial, nome, flags, who_nome, missType)
self.counter = self.counter + 1
local miss = self [missType] or 0
miss = miss + 1
self [missType] = miss
local alvo = self.targets:PegarCombatente (serial, nome, flags, true)
return alvo:AddQuantidade (0)
end
function habilidade_dano:AddFF (amount)
self.counter = self.counter + 1
self.total = self.total + amount
if (self.shadow) then
return self.shadow:AddFF (amount)
end
end
function habilidade_dano:Add (serial, nome, flag, amount, who_nome, resisted, blocked, absorbed, critical, glacing, token)
self.counter = self.counter + 1
--local alvo = self.targets:PegarCombatente (serial, nome, flag, true)
local alvo = self.targets._NameIndexTable [nome]
if (not alvo) then
alvo = self.targets:PegarCombatente (serial, nome, flag, true)
else
alvo = self.targets._ActorTable [alvo]
end
if (resisted and resisted > 0) then
self.r_dmg = self.r_dmg+amount --> tabela.total é o total de dano
self.r_amt = self.r_amt+1 --> tabela.total é o total de dano
if (amount > self.r_max) then
self.r_max = amount
end
if (self.r_min > amount or self.r_min == 0) then
self.r_min = amount
end
end
if (blocked and blocked > 0) then
self.b_dmg = self.b_dmg+amount --> amount é o total de dano
self.b_amt = self.b_amt+1 --> amount é o total de dano
if (amount > self.b_max) then
self.b_max = amount
end
if (self.b_min > amount or self.b_min == 0) then
self.b_min = amount
end
end
if (absorbed and absorbed > 0) then
self.a_dmg = self.a_dmg+amount --> amount é o total de dano
self.a_amt = self.a_amt+1 --> amount é o total de dano
if (amount > self.a_max) then
self.a_max = amount
end
if (self.a_min > amount or self.a_min == 0) then
self.a_min = amount
end
end
if (amount and amount > 0) then
self.total = self.total + amount
--alvo:AddQuantidade (amount)
alvo.total = alvo.total + amount
if (glacing) then
-- esta_tabela.glacing = {["mim"] = 0, ["max"] = 0, ["total"] = 0, ["dmg"] = 0}
self.g_dmg = self.g_dmg+amount --> amount é o total de dano
self.g_amt = self.g_amt+1 --> amount é o total de dano
if (amount > self.g_max) then
self.g_max = amount
end
if (self.g_min > amount or self.g_min == 0) then
self.g_min = amount
end
elseif (critical) then
--esta_tabela.critico = {["mim"] = 0, ["max"] = 0, ["total"] = 0, ["dmg"] = 0}
self.c_dmg = self.c_dmg+amount --> amount é o total de dano
self.c_amt = self.c_amt+1 --> amount é o total de dano
if (amount > self.c_max) then
self.c_max = amount
end
if (self.c_min > amount or self.c_min == 0) then
self.c_min = amount
end
else
--esta_tabela.normal = {["mim"] = 0, ["max"] = 0, ["total"] = 0, ["dmg"] = 0}
self.n_dmg = self.n_dmg+amount
self.n_amt = self.n_amt+1
if (amount > self.n_max) then
self.n_max = amount
end
if (self.n_min > amount or self.n_min == 0) then
self.n_min = amount
end
end
end
if (self.shadow) then
if (_recording_ability_with_buffs) then
if (who_nome == _detalhes.playername) then --aqui ele vai detalhar tudo sobre a magia usada
local buffsNames = _detalhes.SoloTables.BuffsTableNameCache
local SpellBuffDetails = self.BuffTable
if (not SpellBuffDetails) then
self.BuffTable = {}
SpellBuffDetails = self.BuffTable
end
if (token == "SPELL_PERIODIC_DAMAGE") then
--> precisa ver se ele tinha na hora que aplicou
local SoloDebuffPower = _detalhes.tabela_vigente.SoloDebuffPower
if (SoloDebuffPower) then
local ThisDebuff = SoloDebuffPower [self.id]
if (ThisDebuff) then
local ThisDebuffOnTarget = ThisDebuff [serial]
if (ThisDebuffOnTarget) then
for index, buff_name in _ipairs (ThisDebuffOnTarget.buffs) do
local buff_info = SpellBuffDetails [buff_name] or {["counter"] = 0, ["total"] = 0, ["critico"] = 0, ["critico_dano"] = 0}
buff_info.counter = buff_info.counter+1
buff_info.total = buff_info.total+amount
if (critical ~= nil) then
buff_info.critico = buff_info.critico+1
buff_info.critico_dano = buff_info.critico_dano+amount
end
SpellBuffDetails [buff_name] = buff_info
end
end
end
end
else
for BuffName, _ in _pairs (_detalhes.Buffs.BuffsTable) do
local name = _UnitAura ("player", BuffName)
if (name ~= nil) then
local buff_info = SpellBuffDetails [name] or {["counter"] = 0, ["total"] = 0, ["critico"] = 0, ["critico_dano"] = 0}
buff_info.counter = buff_info.counter+1
buff_info.total = buff_info.total+amount
if (critical ~= nil) then
buff_info.critico = buff_info.critico+1
buff_info.critico_dano = buff_info.critico_dano+amount
end
SpellBuffDetails [name] = buff_info
end
end
end
end
end
return self.shadow:Add (serial, nome, flag, amount, who_nome, resisted, blocked, absorbed, critical, glacing, token)
end
end
function _detalhes.refresh:r_habilidade_dano (habilidade, shadow) --recebeu o container shadow
_setmetatable (habilidade, habilidade_dano)
habilidade.__index = habilidade_dano
if (shadow ~= -1) then
habilidade.shadow = shadow._ActorTable[habilidade.id]
_detalhes.refresh:r_container_combatentes (habilidade.targets, habilidade.shadow.targets) else
_detalhes.refresh:r_container_combatentes (habilidade.targets, -1)
end
end
function _detalhes.clear:c_habilidade_dano (habilidade)
habilidade.__index = {}
habilidade.shadow = nil
_detalhes.clear:c_container_combatentes (habilidade.targets)
end
habilidade_dano.__add = function (tabela1, tabela2)
tabela1.total = tabela1.total + tabela2.total
tabela1.counter = tabela1.counter + tabela2.counter
tabela1.n_min = tabela1.n_min + tabela2.n_min
tabela1.n_max = tabela1.n_max + tabela2.n_max
tabela1.n_amt = tabela1.n_amt + tabela2.n_amt
tabela1.n_dmg = tabela1.n_dmg + tabela2.n_dmg
tabela1.c_min = tabela1.c_min + tabela2.c_min
tabela1.c_max = tabela1.c_max + tabela2.c_max
tabela1.c_amt = tabela1.c_amt + tabela2.c_amt
tabela1.c_dmg = tabela1.c_dmg + tabela2.c_dmg
tabela1.g_min = tabela1.g_min + tabela2.g_min
tabela1.g_max = tabela1.g_max + tabela2.g_max
tabela1.g_amt = tabela1.g_amt + tabela2.g_amt
tabela1.g_dmg = tabela1.g_dmg + tabela2.g_dmg
tabela1.r_min = tabela1.r_min + tabela2.r_min
tabela1.r_max = tabela1.r_max + tabela2.r_max
tabela1.r_amt = tabela1.r_amt + tabela2.r_amt
tabela1.r_dmg = tabela1.r_dmg + tabela2.r_dmg
tabela1.b_min = tabela1.b_min + tabela2.b_min
tabela1.b_max = tabela1.b_max + tabela2.b_max
tabela1.b_amt = tabela1.b_amt + tabela2.b_amt
tabela1.b_dmg = tabela1.b_dmg + tabela2.b_dmg
tabela1.a_min = tabela1.a_min + tabela2.a_min
tabela1.a_max = tabela1.a_max + tabela2.a_max
tabela1.a_amt = tabela1.a_amt + tabela2.a_amt
tabela1.a_dmg = tabela1.a_dmg + tabela2.a_dmg
tabela1.crushing = tabela1.crushing + tabela2.crushing
return tabela1
end
habilidade_dano.__sub = function (tabela1, tabela2)
tabela1.total = tabela1.total - tabela2.total
tabela1.counter = tabela1.counter - tabela2.counter
tabela1.n_min = tabela1.n_min - tabela2.n_min
tabela1.n_max = tabela1.n_max - tabela2.n_max
tabela1.n_amt = tabela1.n_amt - tabela2.n_amt
tabela1.n_dmg = tabela1.n_dmg - tabela2.n_dmg
tabela1.c_min = tabela1.c_min - tabela2.c_min
tabela1.c_max = tabela1.c_max - tabela2.c_max
tabela1.c_amt = tabela1.c_amt - tabela2.c_amt
tabela1.c_dmg = tabela1.c_dmg - tabela2.c_dmg
tabela1.g_min = tabela1.g_min - tabela2.g_min
tabela1.g_max = tabela1.g_max - tabela2.g_max
tabela1.g_amt = tabela1.g_amt - tabela2.g_amt
tabela1.g_dmg = tabela1.g_dmg - tabela2.g_dmg
tabela1.r_min = tabela1.r_min - tabela2.r_min
tabela1.r_max = tabela1.r_max - tabela2.r_max
tabela1.r_amt = tabela1.r_amt - tabela2.r_amt
tabela1.r_dmg = tabela1.r_dmg - tabela2.r_dmg
tabela1.b_min = tabela1.b_min - tabela2.b_min
tabela1.b_max = tabela1.b_max - tabela2.b_max
tabela1.b_amt = tabela1.b_amt - tabela2.b_amt
tabela1.b_dmg = tabela1.b_dmg - tabela2.b_dmg
tabela1.a_min = tabela1.a_min - tabela2.a_min
tabela1.a_max = tabela1.a_max - tabela2.a_max
tabela1.a_amt = tabela1.a_amt - tabela2.a_amt
tabela1.a_dmg = tabela1.a_dmg - tabela2.a_dmg
tabela1.crushing = tabela1.crushing - tabela2.crushing
return tabela1
end
function _detalhes:UpdateDamageAbilityGears()
_recording_ability_with_buffs = _detalhes.RecordPlayerAbilityWithBuffs
end
+751
View File
@@ -0,0 +1,751 @@
--[[ Esta classe irá abrigar todo a e_energy ganha de uma habilidade
Parents:
addon -> combate atual -> e_energy-> container de jogadores -> esta classe
]]
--lua locals
local _cstr = string.format
local _math_floor = math.floor
local _table_sort = table.sort
local _table_insert = table.insert
local _setmetatable = setmetatable
local _ipairs = ipairs
local _pairs = pairs
local _rawget= rawget
local _math_min = math.min
local _math_max = math.max
local _bit_band = bit.band
local _unpack = unpack
local _type = type
--api locals
local _GetSpellInfo = _detalhes.getspellinfo
local GameTooltip = GameTooltip
local _detalhes = _G._detalhes
local AceLocale = LibStub ("AceLocale-3.0")
local Loc = AceLocale:GetLocale ( "Details" )
local gump = _detalhes.gump
local alvo_da_habilidade = _detalhes.alvo_da_habilidade
local container_habilidades = _detalhes.container_habilidades
local container_combatentes = _detalhes.container_combatentes
local container_pets = _detalhes.container_pets
local atributo_energy = _detalhes.atributo_energy
local habilidade_energy = _detalhes.habilidade_energy
--local container_damage_target = _detalhes.container_type.CONTAINER_DAMAGETARGET_CLASS
local container_playernpc = _detalhes.container_type.CONTAINER_PLAYERNPC
local container_energy = _detalhes.container_type.CONTAINER_ENERGY_CLASS
local container_energy_target = _detalhes.container_type.CONTAINER_ENERGYTARGET_CLASS
--local container_friendlyfire = _detalhes.container_type.CONTAINER_FRIENDLYFIRE
--local modo_ALONE = _detalhes.modos.alone
local modo_GROUP = _detalhes.modos.group
local modo_ALL = _detalhes.modos.all
local class_type = _detalhes.atributos.e_energy
local DATA_TYPE_START = _detalhes._detalhes_props.DATA_TYPE_START
local DATA_TYPE_END = _detalhes._detalhes_props.DATA_TYPE_END
local DFLAG_player = _detalhes.flags.player
local DFLAG_group = _detalhes.flags.in_group
local DFLAG_player_group = _detalhes.flags.player_in_group
local div_abre = _detalhes.divisores.abre
local div_fecha = _detalhes.divisores.fecha
local div_lugar = _detalhes.divisores.colocacao
local info = _detalhes.janela_info
local keyName
function atributo_energy:NovaTabela (serial, nome, link)
local esta_tabela = {}
esta_tabela.quem_sou = "classe_energy" --> DEBUG deleta-me
--print ("CRIANDO NOVO OBJETO")
_setmetatable (esta_tabela, atributo_energy)
--> grava o tempo que a tabela foi criada para o garbage collector interno
esta_tabela.CriadaEm = time()
esta_tabela.last_event = 0
esta_tabela.tipo = class_type --> atributo 3 = e_energy
esta_tabela.mana = 0
esta_tabela.e_rage = 0
esta_tabela.e_energy = 0
esta_tabela.runepower = 0
esta_tabela.focus = 0
esta_tabela.holypower = 0
esta_tabela.mana_r = 0
esta_tabela.e_rage_r = 0
esta_tabela.e_energy_r = 0
esta_tabela.runepower_r = 0
esta_tabela.focus_r = 0
esta_tabela.holypower_r = 0
esta_tabela.mana_from = {}
esta_tabela.e_rage_from = {}
esta_tabela.e_energy_from = {}
esta_tabela.runepower_from = {}
esta_tabela.focus_from = {}
esta_tabela.holypower_from = {}
esta_tabela.last_value = nil --> ultimo valor que este jogador teve, salvo quando a barra dele é atualizada
esta_tabela.pets = {}
--container armazenará os seriais dos alvos que o player aplicou dano
esta_tabela.targets = container_combatentes:NovoContainer (container_energy_target)
--container armazenará os IDs das habilidades usadas por este jogador
esta_tabela.spell_tables = container_habilidades:NovoContainer (container_energy)
if (link) then
esta_tabela.targets.shadow = link.targets
esta_tabela.spell_tables.shadow = link.spell_tables
end
return esta_tabela
end
function atributo_energy:RefreshWindow (instancia, tabela_do_combate, forcar, exportar)
local showing = tabela_do_combate [class_type] --> o que esta sendo mostrado -> [1] - dano [2] - cura --> pega o container com ._NameIndexTable ._ActorTable
if (#showing._ActorTable < 1) then --> não há barras para mostrar
return _detalhes:EsconderBarrasNaoUsadas (instancia, showing)
end
local total = 0 --> total iniciado como ZERO
instancia.top = 0
local sub_atributo = instancia.sub_atributo --> o que esta sendo mostrado nesta instância
local conteudo = showing._ActorTable
local amount = #conteudo
local modo = instancia.modo
if (exportar) then
if (_type (exportar) == "boolean") then
if (sub_atributo == 1) then --> MANA RECUPERADA
keyName = "mana"
elseif (sub_atributo == 2) then --> e_rage GANHA
keyName = "e_rage"
elseif (sub_atributo == 3) then --> ENERGIA GANHA
keyName = "e_energy"
elseif (sub_atributo == 4) then --> RUNEPOWER GANHO
keyName = "runepower"
end
else
keyName = exportar.key
modo = exportar.modo
end
elseif (instancia.atributo == 5) then --> custom
keyName = "custom"
total = tabela_do_combate.totals [instancia.customName]
else
if (sub_atributo == 1) then --> MANA RECUPERADA
keyName = "mana"
elseif (sub_atributo == 2) then --> e_rage GANHA
keyName = "e_rage"
elseif (sub_atributo == 3) then --> ENERGIA GANHA
keyName = "e_energy"
elseif (sub_atributo == 4) then --> RUNEPOWER GANHO
keyName = "runepower"
end
end
if (instancia.atributo == 5) then --> custom
--> faz o sort da categoria e retorna o amount corrigido
amount = _detalhes:ContainerSort (conteudo, amount, keyName)
--> grava o total
instancia.top = conteudo[1][keyName]
elseif (modo == modo_ALL) then --> mostrando ALL
--> faz o sort da categoria
_table_sort (conteudo, function (a, b) return a[keyName] > b[keyName] end)
--> não mostrar resultados com zero
for i = amount, 1, -1 do --> de trás pra frente
if (conteudo[i][keyName] < 1) then
amount = amount-1
else
break
end
end
total = tabela_do_combate.totals [class_type] [keyName] --> pega o total de dano já aplicado
instancia.top = conteudo[1] [keyName]
elseif (modo == modo_GROUP) then --> mostrando GROUP
_table_sort (conteudo, function (a, b)
if (a.grupo and b.grupo) then
return a[keyName] > b[keyName]
elseif (a.grupo and not b.grupo) then
return true
elseif (not a.grupo and b.grupo) then
return false
else
return a[keyName] > b[keyName]
end
end)
for index, player in _ipairs (conteudo) do
if (_bit_band (player.flag, DFLAG_player_group) >= 0x101) then --> é um player e esta em grupo
if (player[keyName] < 1) then --> dano menor que 1, interromper o loop
amount = index - 1
break
elseif (index == 1) then --> esse IF aqui, precisa mesmo ser aqui? não daria pra pega-lo com uma chave [1] nad grupo == true?
instancia.top = conteudo[1][keyName]
end
total = total + player[keyName]
else
amount = index-1
break
end
end
end
showing:remapear()
if (exportar) then
return total, keyName, instancia.top
end
if (amount < 1) then --> não há barras para mostrar
instancia:EsconderScrollBar()
return _detalhes:EndRefresh (instancia, total, tabela_do_combate, showing) --> retorna a tabela que precisa ganhar o refresh
end
instancia:AtualizarScrollBar (amount)
local qual_barra = 1
local barras_container = instancia.barras
for i = instancia.barraS[1], instancia.barraS[2], 1 do --> vai atualizar só o range que esta sendo mostrado
conteudo[i]:AtualizaBarra (instancia, barras_container, qual_barra, i, total, sub_atributo, forcar) --> instância, index, total, valor da 1º barra
qual_barra = qual_barra+1
end
if (instancia.atributo == 5) then --> custom
--> zerar o .custom dos Actors
for index, player in _ipairs (conteudo) do
if (player.custom > 0) then
player.custom = 0
else
break
end
end
end
--> beta, hidar barras não usadas durante um refresh forçado
if (forcar) then
if (instancia.modo == 2) then --> group
for i = qual_barra, instancia.barrasInfo.cabem do
gump:Fade (instancia.barras [i], "in", 0.3)
end
end
end
return _detalhes:EndRefresh (instancia, total, tabela_do_combate, showing) --> retorna a tabela que precisa ganhar o refresh
end
function atributo_energy:Custom (_customName, _combat, sub_atributo, spell, alvo)
local _Skill = self.spell_tables._ActorTable [tonumber (spell)]
if (_Skill) then
local spellName = _GetSpellInfo (tonumber (spell))
local SkillTargets = _Skill.targets._ActorTable
for _, TargetActor in _ipairs (SkillTargets) do
local TargetActorSelf = _combat (class_type, TargetActor.nome)
TargetActorSelf.custom = TargetActor.total + TargetActorSelf.custom
_combat.totals [_customName] = _combat.totals [_customName] + TargetActor.total
end
end
end
function atributo_energy:AtualizaBarra (instancia, barras_container, qual_barra, lugar, total, sub_atributo, forcar)
local esta_barra = instancia.barras[qual_barra] --> pega a referência da barra na janela
if (not esta_barra) then
print ("DEBUG: problema com <instancia.esta_barra> "..qual_barra.." "..lugar)
return
end
local tabela_anterior = esta_barra.minha_tabela
esta_barra.minha_tabela = self
esta_barra.colocacao = lugar
self.minha_barra = esta_barra
self.colocacao = lugar
local esta_e_energy_total = self [keyName] --> total de dano que este jogador deu
local porcentagem = esta_e_energy_total / total * 100
local esta_porcentagem = _math_floor ((esta_e_energy_total/instancia.top) * 100)
esta_barra.texto_direita:SetText (_detalhes:ToK (esta_e_energy_total) .. " " .. div_abre .. _cstr ("%.1f", porcentagem).."%" .. div_fecha) --seta o texto da direita
if (esta_barra.mouse_over and not instancia.baseframe.isMoving) then --> precisa atualizar o tooltip
gump:UpdateTooltip (qual_barra, esta_barra, instancia)
end
return self:RefreshBarra2 (esta_barra, instancia, tabela_anterior, forcar, esta_porcentagem, qual_barra, barras_container)
end
--------------------------------------------- // TOOLTIPS // ---------------------------------------------
function atributo_energy:KeyNames (sub_atributo)
if (sub_atributo == 1) then --> MANA RECUPERADA
return "mana", "mana_from"
elseif (sub_atributo == 2) then --> e_rage GANHA
return "e_rage", "e_rage_from"
elseif (sub_atributo == 3) then --> ENERGIA GANHA
return "e_energy", "e_energy_from"
elseif (sub_atributo == 4) then --> RUNEPOWER GANHO
return "runepower", "runepower_from"
end
end
function atributo_energy:Fontes_e_Habilidades (recebido_from, showing, keyName, habilidade_alvo)
local habilidades = {}
local fontes = {}
local spells_alvo = {}
local max = 0
for nome, _ in _pairs (recebido_from) do
local esta_fonte = showing._ActorTable [showing._NameIndexTable [nome]]
if (esta_fonte) then
local alvos = esta_fonte.targets
local _habilidades = esta_fonte.spell_tables
local este_alvo = alvos._ActorTable [alvos._NameIndexTable[self.nome]]
if (este_alvo) then
fontes [#fontes+1] = {nome, este_alvo [keyName], esta_fonte.classe} --> mostra QUEM deu regen, a QUANTIDADE e a CLASSE
--print (nome, este_alvo [keyName], esta_fonte.classe)
end
for spellid, habilidade in _pairs (_habilidades._ActorTable) do
local alvos = habilidade.targets
local este_alvo = alvos._ActorTable [alvos._NameIndexTable[self.nome]]
if (este_alvo) then
if (not habilidades [spellid]) then
habilidades [spellid] = 0 --> mostra A SPELL e a quantidade que ela deu regen
end
habilidades [spellid] = habilidades [spellid] + este_alvo [keyName]
if (habilidades [spellid] > max) then
max = habilidades [spellid]
end
if (habilidade_alvo and habilidade_alvo == spellid) then
spells_alvo [#spells_alvo + 1] = {nome, este_alvo [keyName], esta_fonte.classe}
elseif (habilidade_alvo == true) then
--print (nome, nome, este_alvo [keyName], spellid)
spells_alvo [#spells_alvo + 1] = {nome, este_alvo [keyName], spellid}
end
end
end
end
end
local sorted_table = {}
for spellid, amt in _pairs (habilidades) do
local nome, _, icone = _GetSpellInfo (spellid)
sorted_table [#sorted_table+1] = {spellid, amt, amt/max*100, nome, icone}
end
_table_sort (sorted_table, function (a, b) return a[2] > b[2] end)
_table_sort (fontes, function (a, b) return a[2] > b[2] end)
if (habilidade_alvo) then
_table_sort (spells_alvo, function (a, b) return a[2] > b[2] end)
end
return fontes, sorted_table, spells_alvo
end
---------> TOOLTIPS BIFURCAÇÃO
function atributo_energy:ToolTip (instancia, numero, barra)
--> seria possivel aqui colocar o icone da classe dele?
GameTooltip:ClearLines()
GameTooltip:AddLine (barra.colocacao..". "..self.nome)
if (instancia.sub_atributo <= 4) then
return self:ToolTipRegenRecebido (instancia, numero, barra)
end
end
function atributo_energy:ToolTipRegenRecebido (instancia, numero, barra)
local tabela_do_combate = instancia.showing
local showing = tabela_do_combate [class_type]
local keyName, keyName_from = atributo_energy:KeyNames (instancia.sub_atributo)
local total_regenerado = self [keyName]
local recebido_from = self [keyName_from]
local fontes, habilidades = self:Fontes_e_Habilidades (recebido_from, showing, keyName)
-----------------------------------------------------------------
GameTooltip:AddLine (Loc ["STRING_SPELLS"])
local max = #habilidades
if (max > 3) then
max = 3
end
for i = 1, max do
local nome_magia, _, icone_magia = _GetSpellInfo (habilidades[i][1])
GameTooltip:AddDoubleLine (nome_magia..": ", _detalhes:comma_value (habilidades[i][2]).." (".._cstr("%.1f", (habilidades[i][2]/total_regenerado) * 100).."%)", 1, 1, 1, 1, 1, 1)
GameTooltip:AddTexture (icone_magia)
end
-----------------------------------------------------------------
GameTooltip:AddLine (Loc ["STRING_PLAYERS"]..":")
max = #fontes
if (max > 3) then
max = 3
end
for i = 1, max do
GameTooltip:AddDoubleLine (fontes[i][1]..": ", _detalhes:comma_value (fontes[i][2]).." (".._cstr("%.1f", (fontes[i][2]/total_regenerado) * 100).."%)", 1, 1, 1, 1, 1, 1)
local classe = fontes[i][3]
if (not classe) then
classe = "monster"
end
GameTooltip:AddTexture ("Interface\\AddOns\\Details\\images\\"..classe:lower().."_small")
end
return true
end
--------------------------------------------- // JANELA DETALHES // ---------------------------------------------
---------> DETALHES BIFURCAÇÃO
function atributo_energy:MontaInfo()
if (info.sub_atributo <= 4) then --> damage done & dps
return self:MontaInfoRegenRecebido()
end
end
---------> DETALHES bloco da direita BIFURCAÇÃO
function atributo_energy:MontaDetalhes (spellid, barra)
if (info.sub_atributo <= 4) then
return self:MontaDetalhesRegenRecebido (spellid, barra)
end
end
function atributo_energy:MontaInfoRegenRecebido()
local barras = info.barras1
local barras2 = info.barras2
local barras3 = info.barras3
local instancia = info.instancia
local keyName, keyName_from = atributo_energy:KeyNames (instancia.sub_atributo)
local tabela_do_combate = instancia.showing
local showing = tabela_do_combate [class_type]
local total_regenerado = self [keyName]
local recebido_from = self [keyName_from]
if (not recebido_from) then
return
end
local fontes, habilidades = self:Fontes_e_Habilidades (recebido_from, showing, keyName)
local amt = #habilidades
if (amt < 1) then --> caso houve apenas friendly fire
return true
end
gump:JI_AtualizaContainerBarras (amt)
local max_ = habilidades [1][2]
for index, tabela in _ipairs (habilidades) do
local barra = barras [index]
if (not barra) then
barra = gump:CriaNovaBarraInfo1 (instancia, index)
barra.textura:SetStatusBarColor (1, 1, 1, 1)
barra.on_focus = false
end
self:FocusLock (barra, tabela[1])
self:UpdadeInfoBar (barra, index, tabela[1], tabela[4], tabela[2], max_, tabela[3], tabela[5], true)
barra.minha_tabela = self
barra.show = tabela[1]
barra:Show()
if (self.detalhes and self.detalhes == barra.show) then
self:MontaDetalhes (self.detalhes, barra)
end
end
local amt_fontes = #fontes
gump:JI_AtualizaContainerAlvos (amt_fontes)
local max_fontes = fontes[1][2]
local barra
for index, tabela in _ipairs (fontes) do
barra = info.barras2 [index]
if (not barra) then
barra = gump:CriaNovaBarraInfo2 (instancia, index)
barra.textura:SetStatusBarColor (1, 1, 1, 1)
end
if (index == 1) then
barra.textura:SetValue (100)
else
barra.textura:SetValue (tabela[2]/max_fontes*100)
end
barra.texto_esquerdo:SetText (index..instancia.divisores.colocacao..tabela[1]) --seta o texto da esqueda
barra.texto_direita:SetText (_detalhes:comma_value (tabela[2]) .." ".. instancia.divisores.abre .._cstr("%.1f", tabela[2]/total_regenerado * 100) .. instancia.divisores.fecha) --seta o texto da direita
if (barra.mouse_over) then --> atualizar o tooltip
if (barra.isAlvo) then
GameTooltip:Hide()
GameTooltip:SetOwner (barra, "ANCHOR_TOPRIGHT")
if (not barra.minha_tabela:MontaTooltipAlvos (barra, index)) then
return
end
GameTooltip:Show()
end
end
barra.minha_tabela = self --> grava o jogador na tabela
barra.nome_inimigo = tabela [1] --> salva o nome do inimigo na barra --> isso é necessário?
barra:Show()
end
end
function atributo_energy:MontaDetalhesRegenRecebido (nome, barra)
for _, barra in _ipairs (info.barras3) do
barra:Hide()
end
local barras = info.barras3
local instancia = info.instancia
local tabela_do_combate = info.instancia.showing
local showing = tabela_do_combate [class_type]
local keyName, keyName_from = atributo_energy:KeyNames (instancia.sub_atributo)
local recebido_from = self [keyName_from]
local total_regenerado = self [keyName]
local _, _, from = self:Fontes_e_Habilidades (recebido_from, showing, keyName, nome)
if (not from [1] or not from [1][2]) then
return
end
local max_ = from [1][2]
local barra
for index, tabela in _ipairs (from) do
barra = barras [index]
if (not barra) then --> se a barra não existir, criar ela então
barra = gump:CriaNovaBarraInfo3 (instancia, index)
barra.textura:SetStatusBarColor (1, 1, 1, 1) --> isso aqui é a parte da seleção e desceleção
end
if (index == 1) then
barra.textura:SetValue (100)
else
barra.textura:SetValue (tabela[2]/max_*100) --> muito mais rapido...
end
barra.texto_esquerdo:SetText (index..instancia.divisores.colocacao..tabela[1]) --seta o texto da esqueda
barra.texto_direita:SetText (_detalhes:comma_value (tabela[2]) .." ".. instancia.divisores.abre .._cstr("%.1f", tabela[2] /total_regenerado *100) .."%".. instancia.divisores.fecha) --seta o texto da direita
barra.textura:SetStatusBarColor (_unpack (_detalhes.class_colors [tabela[3]]))
barra.icone:SetTexture ("Interface\\AddOns\\Details\\images\\classes_small")
barra.icone:SetTexCoord (_unpack (_detalhes.class_coords [tabela[3]]))
barra:Show() --> mostra a barra
if (index == 15) then
break
end
end
end
function atributo_energy:MontaTooltipAlvos (esta_barra, index)
local instancia = info.instancia
local tabela_do_combate = instancia.showing
local showing = tabela_do_combate [class_type]
local keyName, keyName_from = atributo_energy:KeyNames (instancia.sub_atributo)
local total_regenerado = self [keyName]
local recebido_from = self [keyName_from]
local _, _, spells_alvo = self:Fontes_e_Habilidades (recebido_from, showing, keyName, true)
-----------------------------------------------------------------
GameTooltip:AddLine (Loc ["STRING_SPELLS"]..":")
for _, tabela in _ipairs (spells_alvo) do
if (tabela[1] == esta_barra.nome_inimigo) then
local nome_magia, _, icone_magia = _GetSpellInfo (tabela[3])
GameTooltip:AddDoubleLine (nome_magia..": ", _detalhes:comma_value (tabela[2]).." (".._cstr("%.1f", (tabela[2]/total_regenerado) * 100).."%)", 1, 1, 1, 1, 1, 1)
GameTooltip:AddTexture (icone_magia)
end
end
return true
end
--controla se o dps do jogador esta travado ou destravado
function atributo_energy:Iniciar (iniciar)
return false --retorna se o dps esta aberto ou fechado para este jogador
end
function atributo_energy:ColetarLixo()
return _detalhes:ColetarLixo (class_type)
end
local function ReconstroiMapa (tabela)
local mapa = {}
for i = 1, #tabela._ActorTable do
mapa [tabela._ActorTable[i].nome] = i
end
tabela._NameIndexTable = mapa
end
function _detalhes.refresh:r_atributo_energy (este_jogador, shadow)
_setmetatable (este_jogador, _detalhes.atributo_energy)
este_jogador.__index = _detalhes.atributo_energy
if (shadow ~= -1) then
este_jogador.shadow = shadow
_detalhes.refresh:r_container_combatentes (este_jogador.targets, shadow.targets)
_detalhes.refresh:r_container_habilidades (este_jogador.spell_tables, shadow.spell_tables)
else
_detalhes.refresh:r_container_combatentes (este_jogador.targets, -1)
_detalhes.refresh:r_container_habilidades (este_jogador.spell_tables, -1)
end
end
function _detalhes.clear:c_atributo_energy (este_jogador)
este_jogador.__index = {}
este_jogador.shadow = nil
este_jogador.links = nil
este_jogador.minha_barra = nil
_detalhes.clear:c_container_combatentes (este_jogador.targets)
_detalhes.clear:c_container_habilidades (este_jogador.spell_tables)
end
atributo_energy.__add = function (shadow, tabela2)
shadow.mana = shadow.mana + tabela2.mana
shadow.e_rage = shadow.e_rage + tabela2.e_rage
shadow.e_energy = shadow.e_energy + tabela2.e_energy
shadow.runepower = shadow.runepower + tabela2.runepower
shadow.focus = shadow.focus + tabela2.focus
shadow.holypower = shadow.holypower + tabela2.holypower
_detalhes.tabela_overall.totals[3]["mana"] = _detalhes.tabela_overall.totals[3]["mana"] + tabela2.mana
_detalhes.tabela_overall.totals[3]["e_rage"] = _detalhes.tabela_overall.totals[3]["e_rage"] + tabela2.e_rage
_detalhes.tabela_overall.totals[3]["e_energy"] = _detalhes.tabela_overall.totals[3]["e_energy"] + tabela2.e_energy
_detalhes.tabela_overall.totals[3]["runepower"] = _detalhes.tabela_overall.totals[3]["runepower"] + tabela2.runepower
if (tabela2.grupo) then
_detalhes.tabela_overall.totals_grupo[3]["mana"] = _detalhes.tabela_overall.totals_grupo[3]["mana"] + tabela2.mana
_detalhes.tabela_overall.totals_grupo[3]["e_rage"] = _detalhes.tabela_overall.totals_grupo[3]["e_rage"] + tabela2.e_rage
_detalhes.tabela_overall.totals_grupo[3]["e_energy"] = _detalhes.tabela_overall.totals_grupo[3]["e_energy"] + tabela2.e_energy
_detalhes.tabela_overall.totals_grupo[3]["runepower"] = _detalhes.tabela_overall.totals_grupo[3]["runepower"] + tabela2.runepower
end
shadow.mana_r = shadow.mana_r + tabela2.mana_r
shadow.e_rage_r = shadow.e_rage_r + tabela2.e_rage_r
shadow.e_energy_r = shadow.e_energy_r + tabela2.e_energy_r
shadow.runepower_r = shadow.runepower_r + tabela2.runepower_r
shadow.focus_r = shadow.focus_r + tabela2.focus_r
shadow.holypower_r = shadow.holypower_r + tabela2.holypower_r
for index, alvo in _ipairs (tabela2.targets._ActorTable) do
local alvo_shadow = shadow.targets:PegarCombatente (alvo.serial, alvo.nome, _, true)
alvo_shadow.total = alvo_shadow.total + alvo.total
end
--> copia o container de habilidades
for spellid, habilidade in _pairs (tabela2.spell_tables._ActorTable) do
local habilidade_shadow = shadow.spell_tables:PegaHabilidade (spellid, true, nil, true)
for index, alvo in _ipairs (habilidade.targets._ActorTable) do
local alvo_shadow = habilidade_shadow.targets:PegarCombatente (alvo.serial, alvo.nome, _, true)
alvo_shadow.total = alvo_shadow.total + alvo.total
end
for key, value in _pairs (habilidade) do
if (_type (value) == "number") then
if (key ~= "id") then
if (not habilidade_shadow [key]) then
habilidade_shadow [key] = 0
end
habilidade_shadow [key] = habilidade_shadow [key] + value
end
end
end
end
return shadow
end
atributo_energy.__sub = function (tabela1, tabela2)
tabela1.mana = tabela1.mana - tabela2.mana
tabela1.e_rage = tabela1.e_rage - tabela2.e_rage
tabela1.e_energy = tabela1.e_energy - tabela2.e_energy
tabela1.runepower = tabela1.runepower - tabela2.runepower
tabela1.focus = tabela1.focus - tabela2.focus
tabela1.holypower = tabela1.holypower - tabela2.holypower
tabela1.mana_r = tabela1.mana_r - tabela2.mana_r
tabela1.e_rage_r = tabela1.e_rage_r - tabela2.e_rage_r
tabela1.e_energy_r = tabela1.e_energy_r - tabela2.e_energy_r
tabela1.runepower_r = tabela1.runepower_r - tabela2.runepower_r
tabela1.focus_r = tabela1.focus_r - tabela2.focus_r
tabela1.holypower_r = tabela1.holypower_r - tabela2.holypower_r
return tabela1
end
@@ -0,0 +1,102 @@
local _detalhes = _G._detalhes
local gump = _detalhes.gump
local alvo_da_habilidade = _detalhes.alvo_da_habilidade
local habilidade_energy = _detalhes.habilidade_e_energy
local container_combatentes = _detalhes.container_combatentes
local container_energy_target = _detalhes.container_type.CONTAINER_ENERGYTARGET_CLASS
--lua locals
local _setmetatable = setmetatable
local _ipairs = ipairs
--api locals
local _UnitAura = UnitAura
--local _GetSpellInfo = _detalhes.getspellinfo
local container_playernpc = _detalhes.container_type.CONTAINER_PLAYERNPC
--id, nome, type, miss, dano, cura, overkill, school, resisted, blocked, absorbed, critico, glacing, crushing
function habilidade_energy:NovaTabela (id, link, token) --aqui eu não sei que parâmetros passar
local esta_tabela = {}
_setmetatable (esta_tabela, habilidade_energy)
esta_tabela.quem_sou = "classe_energy_habilidade"
esta_tabela.id = id
esta_tabela.counter = 0
esta_tabela.mana = 0
esta_tabela.e_rage = 0
esta_tabela.e_energy = 0
esta_tabela.runepower = 0
esta_tabela.targets = container_combatentes:NovoContainer (container_energy_target)
if (link) then
esta_tabela.targets.shadow = link.targets
end
return esta_tabela
end
function habilidade_energy:Add (serial, nome, flag, amount, who_nome, powertype)
self.counter = self.counter + 1
--local alvo = self.targets:PegarCombatente (serial, nome, flag, true)
local alvo = self.targets._NameIndexTable [nome]
if (not alvo) then
alvo = self.targets:PegarCombatente (serial, nome, flag, true)
else
alvo = self.targets._ActorTable [alvo]
end
if (powertype == 0) then --> MANA
self.mana = self.mana + amount
alvo.mana = alvo.mana + amount
elseif (powertype == 1) then --> e_rage
self.e_rage = self.e_rage + amount
alvo.e_rage = alvo.e_rage + amount
elseif (powertype == 3) then --> ENERGIA
self.e_energy = self.e_energy + amount
alvo.e_energy = alvo.e_energy + amount
elseif (powertype == 6) then --> RUNEPOWER
self.runepower = self.runepower + amount
alvo.runepower = alvo.runepower + amount
end
if (self.shadow) then
return self.shadow:Add (serial, nome, flag, amount, who_nome, powertype)
end
end
function _detalhes.refresh:r_habilidade_e_energy (habilidade, shadow) --recebeu o container shadow
_setmetatable (habilidade, habilidade_energy)
habilidade.__index = habilidade_energy
if (shadow ~= -1) then
habilidade.shadow = shadow._ActorTable[habilidade.id]
_detalhes.refresh:r_container_combatentes (habilidade.targets, habilidade.shadow.targets)
else
_detalhes.refresh:r_container_combatentes (habilidade.targets, -1)
end
end
function _detalhes.clear:c_habilidade_e_energy (habilidade)
habilidade.__index = {}
habilidade.shadow = nil
_detalhes.clear:c_container_combatentes (habilidade.targets)
end
habilidade_energy.__sub = function (tabela1, tabela2)
tabela1.mana = tabela1.mana - tabela2.mana
tabela1.e_rage = tabela1.e_rage - tabela2.e_rage
tabela1.e_energy = tabela1.e_energy - tabela2.e_energy
tabela1.runepower = tabela1.runepower - tabela2.runepower
tabela1.counter = tabela1.counter - tabela2.counter
return tabela1
end
+27
View File
@@ -0,0 +1,27 @@
do
local _detalhes = _G._detalhes
local _error = {
["error"] = true,
["errortext"] = ""
}
_error.__index = _error
_error.__newindex = function()
assert (false, "Attempt to modify an read-only object.\nUse object() or object.errortext\n"..debugstack (2, 1 , 0))
return
end
_error.__tostring = function()
return _error.errortext
end
_error.__call = function (_this)
print (_this.errortext)
end
function _detalhes:NewError (_msg)
local this_error = {}
this_error.errortext = _msg
setmetatable (this_error, _error)
return this_error
end
end
File diff suppressed because it is too large Load Diff
+154
View File
@@ -0,0 +1,154 @@
--[[ classe do dano aplicado, usado nos eventos:
- SPELL_HEAL
- SPELL_PERIODIC_HEAL
Parents:
addon -> combate atual -> Npc/Player Swicth -> Container de Habilidades -> esta tabela
]]
local _detalhes = _G._detalhes
local gump = _detalhes.gump
local alvo_da_habilidade = _detalhes.alvo_da_habilidade
local habilidade_cura = _detalhes.habilidade_cura
local container_combatentes = _detalhes.container_combatentes
local container_heal_target = _detalhes.container_type.CONTAINER_HEALTARGET_CLASS
local container_playernpc = _detalhes.container_type.CONTAINER_PLAYERNPC
--lua locals
local _setmetatable = setmetatable
--api locals
function habilidade_cura:NovaTabela (id, link) --aqui eu não sei que parâmetros passar
local esta_tabela = {}
_setmetatable (esta_tabela, habilidade_cura)
esta_tabela.CriadaEm = time()
esta_tabela.quem_sou = "classe_heal_habilidade"
-- esta_tabela.jogador = serial
esta_tabela.total = 0 --total de dano aplicado por esta habilidade
esta_tabela.counter = 0 --conta quantas vezes a habilidade foi chamada
esta_tabela.id = id
--> normal hits
esta_tabela.n_min = 0
esta_tabela.n_max = 0
esta_tabela.n_amt = 0
esta_tabela.n_curado = 0
--> critical hits
esta_tabela.c_min = 0
esta_tabela.c_max = 0
esta_tabela.c_amt = 0
esta_tabela.c_curado = 0
esta_tabela.absorbed = 0
esta_tabela.overheal = 0
esta_tabela.targets = container_combatentes:NovoContainer (container_heal_target)
if (link) then
esta_tabela.targets.shadow = link.targets
end
return esta_tabela
end
function habilidade_cura:Add (serial, nome, flag, amount, who_nome, absorbed, critical, overhealing, is_shield)
self.counter = self.counter + 1
--local alvo = self.targets:PegarCombatente (serial, nome, flag, true)
local alvo = self.targets._NameIndexTable [nome]
if (not alvo) then
alvo = self.targets:PegarCombatente (serial, nome, flag, true)
else
alvo = self.targets._ActorTable [alvo]
end
if (absorbed and absorbed > 0) then
self.absorbed = self.absorbed + absorbed
alvo.absorbed = alvo.absorbed + absorbed
end
if (overhealing and overhealing > 0) then
self.overheal = self.overheal + overhealing
alvo.overheal = alvo.overheal + overhealing
end
if (amount and amount > 0) then
self.total = self.total + amount
alvo:AddQuantidade (amount)
if (critical) then
self.c_curado = self.c_curado+amount --> amount é o total de dano
self.c_amt = self.c_amt+1 --> amount é o total de dano
if (amount > self.c_max) then
self.c_max = amount
end
if (self.c_min > amount or self.c_min == 0) then
self.c_min = amount
end
else
self.n_curado = self.n_curado+amount
self.n_amt = self.n_amt+1
if (amount > self.n_max) then
self.n_max = amount
end
if (self.n_min > amount or self.n_min == 0) then
self.n_min = amount
end
end
else
alvo:AddQuantidade (0)
end
if (self.shadow) then
return self.shadow:Add (serial, nome, flag, amount, who_nome, absorbed, critical, overhealing)
end
end
function _detalhes.refresh:r_habilidade_cura (habilidade, shadow)
_setmetatable (habilidade, habilidade_cura)
habilidade.__index = habilidade_cura
if (shadow ~= -1) then
habilidade.shadow = shadow._ActorTable[habilidade.id]
_detalhes.refresh:r_container_combatentes (habilidade.targets, habilidade.shadow.targets)
else
_detalhes.refresh:r_container_combatentes (habilidade.targets, -1)
end
end
function _detalhes.clear:c_habilidade_cura (habilidade)
habilidade.__index = {}
habilidade.shadow = nil
_detalhes.clear:c_container_combatentes (habilidade.targets)
end
habilidade_cura.__sub = function (tabela1, tabela2)
tabela1.total = tabela1.total - tabela2.total
tabela1.counter = tabela1.counter - tabela2.counter
tabela1.n_min = tabela1.n_min - tabela2.n_min
tabela1.n_max = tabela1.n_max - tabela2.n_max
tabela1.n_amt = tabela1.n_amt - tabela2.n_amt
tabela1.n_curado = tabela1.n_curado - tabela2.n_curado
tabela1.c_min = tabela1.c_min - tabela2.c_min
tabela1.c_max = tabela1.c_max - tabela2.c_max
tabela1.c_amt = tabela1.c_amt - tabela2.c_amt
tabela1.c_curado = tabela1.c_curado - tabela2.c_curado
tabela1.absorbed = tabela1.absorbed - tabela2.absorbed
tabela1.overheal = tabela1.overheal - tabela2.overheal
return tabela1
end
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,160 @@
local _detalhes = _G._detalhes
--local gump = _detalhes.gump
local alvo_da_habilidade = _detalhes.alvo_da_habilidade
local habilidade_misc = _detalhes.habilidade_misc
local container_combatentes = _detalhes.container_combatentes
local container_misc_target = _detalhes.container_type.CONTAINER_MISCTARGET_CLASS
--lua locals
local _setmetatable = setmetatable
local _ipairs = ipairs
--api locals
local _UnitAura = UnitAura
local container_playernpc = _detalhes.container_type.CONTAINER_PLAYERNPC
function habilidade_misc:NovaTabela (id, link, token) --aqui eu não sei que parâmetros passar
local esta_tabela = {}
_setmetatable (esta_tabela, habilidade_misc)
esta_tabela.quem_sou = "classe_others_habilidade"
esta_tabela.id = id
--print ("token: " .. token)
if (token == "SPELL_INTERRUPT") then
--print ("token de interrupt")
esta_tabela.interrompeu_oque = {}
end
if (token == "SPELL_DISPEL" or token == "SPELL_STOLEN") then
--print ("token de interrupt")
esta_tabela.dispell_oque = {}
end
if (token == "SPELL_AURA_BROKEN" or token == "SPELL_AURA_BROKEN_SPELL") then
--print ("token de interrupt")
esta_tabela.cc_break_oque = {}
end
-- isso aqui não pode ser assim... ou pode?
esta_tabela.counter = 0
--esta_tabela.res = 0
esta_tabela.targets = container_combatentes:NovoContainer (container_misc_target)
if (link) then
esta_tabela.targets.shadow = link.targets
end
return esta_tabela
end
function habilidade_misc:Add (serial, nome, flag, who_nome, token, spellID, spellName)
--local alvo = self.targets:PegarCombatente (serial, nome, flag, true)
local alvo = self.targets._NameIndexTable [nome]
if (not alvo) then
alvo = self.targets:PegarCombatente (serial, nome, flag, true)
else
alvo = self.targets._ActorTable [alvo]
end
alvo.total = alvo.total + 1
--alvo:AddQuantidade (1)
if (token == "SPELL_INTERRUPT") then
self.counter = self.counter + 1
if (not self.interrompeu_oque [spellID]) then --> interrompeu_oque a NIL value
self.interrompeu_oque [spellID] = 1
else
self.interrompeu_oque [spellID] = self.interrompeu_oque [spellID] + 1
end
elseif (token == "SPELL_RESURRECT") then
if (not self.ress) then
self.ress = 1
else
self.ress = self.ress + 1
end
elseif (token == "SPELL_DISPEL" or token == "SPELL_STOLEN") then
if (not self.dispell) then
self.dispell = 1
else
self.dispell = self.dispell + 1
end
if (not self.dispell_oque [spellID]) then
self.dispell_oque [spellID] = 1
else
self.dispell_oque [spellID] = self.dispell_oque [spellID] + 1
end
elseif (token == "SPELL_AURA_BROKEN_SPELL" or token == "SPELL_AURA_BROKEN") then
if (not self.cc_break) then
self.cc_break = 1
else
self.cc_break = self.cc_break + 1
end
if (not self.cc_break_oque [spellID]) then
self.cc_break_oque [spellID] = 1
else
self.cc_break_oque [spellID] = self.cc_break_oque [spellID] + 1
end
end
if (self.shadow) then
return self.shadow:Add (serial, nome, flag, who_nome, token, spellID, spellName)
end
end
--> habilidade atual e o container de habilidades da shadow
function _detalhes.refresh:r_habilidade_misc (habilidade, shadow) --recebeu o container shadow
_setmetatable (habilidade, habilidade_misc)
habilidade.__index = habilidade_misc
if (shadow ~= -1) then
habilidade.shadow = shadow._ActorTable[habilidade.id]
_detalhes.refresh:r_container_combatentes (habilidade.targets, habilidade.shadow.targets)
else
_detalhes.refresh:r_container_combatentes (habilidade.targets, -1)
end
end
function _detalhes.clear:c_habilidade_misc (habilidade)
habilidade.__index = {}
habilidade.shadow = nil
_detalhes.clear:c_container_combatentes (habilidade.targets)
end
habilidade_misc.__sub = function (tabela1, tabela2)
--interrupts
tabela1.counter = tabela1.counter - tabela2.counter
--ressesrs
if (tabela1.ress and tabela2.ress) then
tabela1.ress = tabela1.ress - tabela2.ress
end
--dispells
if (tabela1.dispell and tabela2.dispell) then
tabela1.dispell = tabela1.dispell - tabela2.dispell
end
--cc_breaks
if (tabela1.cc_break and tabela2.cc_break) then
tabela1.cc_break = tabela1.cc_break - tabela2.cc_break
end
return tabela1
end
+55
View File
@@ -0,0 +1,55 @@
local _detalhes = _G._detalhes
--local AceLocale = LibStub ("AceLocale-3.0")
--local Loc = AceLocale:GetLocale ( "Details" )
local gump = _detalhes.gump
local alvo_da_habilidade = _detalhes.alvo_da_habilidade
--lua locals
local _setmetatable = setmetatable
--api locals
--esta tabela irá ser usada por todas os tipos? tipo dano, cura, interrupts?
function alvo_da_habilidade:NovaTabela (link)
local esta_tabela = {}
_setmetatable (esta_tabela, alvo_da_habilidade)
esta_tabela.quem_sou = "classe_alvo_da_habilidade"
esta_tabela.total = 0 --total que a habilidade fez.
return esta_tabela
end
function alvo_da_habilidade:AddQuantidade (amt)
self.total = self.total + amt
if (self.shadow) then
return self.shadow:AddQuantidade (amt)
end
end
function _detalhes.refresh:r_alvo_da_habilidade (este_alvo, shadow)
--print (shadow)
--print (este_alvo.shadow)
_setmetatable (este_alvo, alvo_da_habilidade)
este_alvo.__index = alvo_da_habilidade
if (shadow ~= -1) then
este_alvo.shadow = shadow._ActorTable [shadow._NameIndexTable[este_alvo.nome]]
end
end
function _detalhes.clear:c_alvo_da_habilidade (este_alvo)
este_alvo.shadow = nil
este_alvo.__index = {}
end
alvo_da_habilidade.__sub = function (tabela1, tabela2)
tabela1.total = tabela1.total - tabela2.total
if (tabela1.overheal) then
tabela1.overheal = tabela1.overheal - tabela2.overheal
tabela1.absorbed = tabela1.absorbed - tabela2.absorbed
end
end
+531
View File
@@ -0,0 +1,531 @@
local _detalhes = _G._detalhes
local gump = _detalhes.gump
local combatente = _detalhes.combatente
local container_combatentes = _detalhes.container_combatentes
local alvo_da_habilidade = _detalhes.alvo_da_habilidade
local atributo_damage = _detalhes.atributo_damage
local atributo_heal = _detalhes.atributo_heal
local atributo_energy = _detalhes.atributo_energy
local atributo_misc = _detalhes.atributo_misc
local container_playernpc = _detalhes.container_type.CONTAINER_PLAYERNPC
local container_damage = _detalhes.container_type.CONTAINER_DAMAGE_CLASS
local container_heal = _detalhes.container_type.CONTAINER_HEAL_CLASS
local container_heal_target = _detalhes.container_type.CONTAINER_HEALTARGET_CLASS
local container_friendlyfire = _detalhes.container_type.CONTAINER_FRIENDLYFIRE
local container_damage_target = _detalhes.container_type.CONTAINER_DAMAGETARGET_CLASS
local container_energy = _detalhes.container_type.CONTAINER_ENERGY_CLASS
local container_energy_target = _detalhes.container_type.CONTAINER_ENERGYTARGET_CLASS
local container_misc = _detalhes.container_type.CONTAINER_MISC_CLASS
local container_misc_target = _detalhes.container_type.CONTAINER_MISCTARGET_CLASS
--api locals
local _UnitClass = UnitClass
local _GetPlayerInfoByGUID = GetPlayerInfoByGUID
--lua locals
local _setmetatable = setmetatable
local _getmetatable = getmetatable
local _bit_band = bit.band
local _ipairs = ipairs
local _pairs = pairs
--local table_insert = table.insert
--> FLAGS <== qual o tipo do objeto
local OBJECT_TYPE_MASK = 0x0000FC00
local OBJECT_TYPE_OBJECT = 0x00004000
local OBJECT_TYPE_PETGUARDIAN = 0x00003000
local OBJECT_TYPE_GUARDIAN = 0x00002000
local OBJECT_TYPE_PET = 0x00001000
local OBJECT_TYPE_NPC = 0x00000800
local OBJECT_TYPE_PLAYER = 0x00000400
local OBJECT_TYPE_PETS = OBJECT_TYPE_PET + OBJECT_TYPE_GUARDIAN
local REACTION_HOSTILE = COMBATLOG_OBJECT_REACTION_HOSTILE or 0x00000040
function container_combatentes:NovoContainer (tipo_do_container, combatTable, combatId)
local esta_tabela = {}
_setmetatable (esta_tabela, container_combatentes)
esta_tabela.funcao_de_criacao = container_combatentes:FuncaoDeCriacao (tipo_do_container)
if (not esta_tabela.funcao_de_criacao) then
print ("Debug: Container criado mas sem funcao de criacao. TIPO: ")
print (tipo_do_container)
print (debugstack(2))
return
end
esta_tabela.tipo = tipo_do_container
esta_tabela.combatId = combatId
esta_tabela._ActorTable = {}
esta_tabela._NameIndexTable = {}
esta_tabela.meu_tipo = "container_combatentes"
return esta_tabela
end
local function get_class_ (novo_objeto, nome, flag)
local _, engClass = _UnitClass (nome)
if (engClass) then
novo_objeto.classe = engClass
return
else
if (flag) then
--print ("tem flag: " .. flag)
--> conferir se o jogador é um player
if (_bit_band (flag, OBJECT_TYPE_PLAYER) ~= 0) then
--print ("eh um player sem grupo: "..novo_objeto.nome)
novo_objeto.classe = "UNGROUPPLAYER"
return
elseif (_bit_band (flag, OBJECT_TYPE_PETGUARDIAN) ~= 0) then
--print ("eh um pet: "..novo_objeto.nome)
novo_objeto.classe = "PET"
return
end
end
novo_objeto.classe = "UNKNOW"
return
end
end
local EM_GRUPO = 0x00000007
function container_combatentes:Dupe (who)
local novo_objeto = {}
if (_getmetatable (who)) then
_setmetatable (novo_objeto, _getmetatable (who))
end
for cprop, value in _pairs (who) do
novo_objeto[cprop] = value
end
return novo_objeto
end
function container_combatentes:CriarShadow (who)
--> o self é o container no combate_overall -- who é o objeto na tabela do historico [1 2 3]
local mapa = self._NameIndexTable
local conteudo = self._ActorTable
local novo_objeto = self.funcao_de_criacao (_, who.serial, who.nome)
novo_objeto.nome = who.nome
novo_objeto.flag = who.flag
novo_objeto.classe = who.classe
for _, pet in _ipairs (who.pets) do
novo_objeto.pets [#novo_objeto.pets+1] = pet
end
if (who.enemy) then
novo_objeto.enemy = true
end
self._ActorTable [#self._ActorTable+1] = novo_objeto
self._NameIndexTable[who.nome] = #self._ActorTable
return novo_objeto
end
function container_combatentes:GetAmount (actorName, key)
key = key or "total"
local index = self._NameIndexTable [actorName]
if (index) then
return self._ActorTable [index] [key] or 0
else
return 0
end
end
function container_combatentes:PegarCombatente (serial, nome, flag, criar, isOwner)
--> antes de mais nada, vamos verificar se é um pet
local dono_do_pet
if (flag and _bit_band (flag, OBJECT_TYPE_PETS) ~= 0) then --> é um pet
--> aqui ele precisaria achar as tag < > pra saber se o nome passado já não veio com o dono imbutido
--> se não tiver as tags, terá que ser posto aqui
if (not nome:find ("<") or not nome:find (">")) then --> find é lento, não teria outra forma de fazer isso?
local nome_dele, dono_nome, dono_serial, dono_flag = _detalhes.tabela_pets:PegaDono (serial, nome, flag)
if (nome_dele) then
nome = nome_dele
--> aqui pode ocorrer bug caso o dono tenha sido adicionado ao container de pets enquanto não estava na party ou raide
--[[ old debug lines
if (self.shadow and self.tipo == container_damage and not self._NameIndexTable [dono_nome]) then
print ("CONTAINER 1: Criando Actor do Dono:", dono_nome, "Pet: ", nome)
elseif (self.shadow and self.tipo == container_damage and self._NameIndexTable [dono_nome]) then
print ("CONTAINER 1: criado actor repedido",nome)
end
--]]
dono_do_pet = self:PegarCombatente (dono_serial, dono_nome, dono_flag, true, nome)
end
end
end
local index = self._NameIndexTable [nome] --> pega o index no mapa
if (index) then
return self._ActorTable [index], dono_do_pet, nome
elseif (criar) then
--[[ old debug lines
if (isOwner and self.shadow and self.tipo == container_damage) then
print ("CONTAINER 2: Criando actor do Dono do Pet: OWNER:", nome, "PET:", isOwner)
if (self._NameIndexTable [nome]) then
print ("Repetido")
end
end
--]]
-- rotinas de criação do objeto shadow
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
local shadow = self.shadow --> espelho do container no overall
local shadow_objeto = nil
if (shadow) then --> se tiver o espelho (não for a tabela overall já)
shadow_objeto = shadow:PegarCombatente (_, nome) --> apenas verifica se ele existe ou não
if (not shadow_objeto) then --> se não existir, cria-lo
local novo_nome = nome:gsub ((" <.*"), "") --> tira o nome do pet
shadow_objeto = shadow:PegarCombatente (serial, novo_nome, flag, true)
end
end
local novo_objeto = self.funcao_de_criacao (_, serial, nome, shadow_objeto) --> shadow_objeto passa para o classe_damage gravar no .targets e .spell_tables, mas não grava nele mesmo
novo_objeto.nome = nome
-- converte a flag do wow em flag do details
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> pega afiliação
local details_flag = 0x00000000
if (flag) then
--print ("tem flag")
if (_bit_band (flag, 0x00000400) ~= 0) then --> é um player
details_flag = details_flag+0x00000001
if (IsInInstance()) then
novo_objeto.displayName = nome:gsub (("%-.*"), "")
else
novo_objeto.displayName = nome
end
if (_bit_band (flag, EM_GRUPO) ~= 0) then --> faz parte do grupo
details_flag = details_flag+0x00000100
novo_objeto.grupo = true
if (shadow_objeto) then
shadow_objeto.grupo = true
end
end
elseif (dono_do_pet) then --> é um pet
details_flag = details_flag+0x00000002
novo_objeto.owner = dono_do_pet
novo_objeto.ownerName = dono_do_pet.nome
if (IsInInstance()) then
novo_objeto.displayName = nome:gsub (("%-.*"), ">")
else
novo_objeto.displayName = nome
end
--if (not novo_objeto.displayName:find (">")) then
-- novo_objeto.displayName = novo_objeto.displayName .. ">"
--end
--print ("pet -> " .. nome)
else
novo_objeto.displayName = nome
end
-- 0x00000060 --> inimigo neutro
if (_bit_band (flag, 0x00000010) ~= 0) then --> é amigo
details_flag = details_flag+0x00000010
elseif (_bit_band (flag, 0x00000020) ~= 0) then --> é neutro
details_flag = details_flag+0x00000020
--print ("neutro -> " .. nome)
elseif (_bit_band (flag, 0x00000040) ~= 0) then --> é inimigo
details_flag = details_flag+0x00000040
--print ("inimigos -> " .. nome)
end
else
--print (flag)
end
novo_objeto.flag = details_flag
novo_objeto.flag_original = flag
novo_objeto.serial = serial
-- tipo do container
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
if (self.tipo == container_playernpc) then --> CONTAINER COMUM
elseif (self.tipo == container_damage) then --> CONTAINER DAMAGE
get_class_ (novo_objeto, nome, flag)
if (dono_do_pet) then
dono_do_pet.pets [#dono_do_pet.pets+1] = nome
end
if (shadow_objeto) then
novo_objeto.shadow = shadow_objeto
novo_objeto:CriaLink (shadow_objeto) --> criando o link
shadow_objeto.flag = details_flag
end
if (novo_objeto.classe == "UNGROUPPLAYER") then --> is a player
if (_bit_band (flag, REACTION_HOSTILE ) ~= 0) then --> is hostile
novo_objeto.enemy = true
end
--> try to guess his class
if (shadow) then --> não executar 2x
_detalhes:ScheduleTimer ("GuessClass", 1, {novo_objeto, self, 1})
end
end
elseif (self.tipo == container_heal) then --> CONTAINER HEALING
get_class_ (novo_objeto, nome, flag)
if (dono_do_pet) then
dono_do_pet.pets [#dono_do_pet.pets+1] = nome
end
if (shadow_objeto) then
novo_objeto.shadow = shadow_objeto
novo_objeto:CriaLink (shadow_objeto) --> criando o link
shadow_objeto.flag = details_flag
end
if (novo_objeto.classe == "UNGROUPPLAYER") then --> is a player
if (_bit_band (flag, REACTION_HOSTILE ) ~= 0) then --> is hostile
novo_objeto.enemy = true --print (nome.." EH UM INIMIGO -> " .. engRace)
end
--> try to guess his class
if (shadow) then --> não executar 2x
_detalhes:ScheduleTimer ("GuessClass", 1, {novo_objeto, self, 1})
end
end
elseif (self.tipo == container_energy) then --> CONTAINER ENERGY
get_class_ (novo_objeto, nome, flag)
if (dono_do_pet) then
dono_do_pet.pets [#dono_do_pet.pets+1] = nome
end
if (shadow_objeto) then
novo_objeto.shadow = shadow_objeto
novo_objeto:CriaLink (shadow_objeto) --> criando o link
shadow_objeto.flag = details_flag
end
if (novo_objeto.classe == "UNGROUPPLAYER") then --> is a player
if (_bit_band (flag, REACTION_HOSTILE ) ~= 0) then --> is hostile
novo_objeto.enemy = true --print (nome.." EH UM INIMIGO -> " .. engRace)
end
--> try to guess his class
if (shadow) then --> não executar 2x
_detalhes:ScheduleTimer ("GuessClass", 1, {novo_objeto, self, 1})
end
end
elseif (self.tipo == container_misc) then --> CONTAINER MISC
get_class_ (novo_objeto, nome, flag)
--local teste_classe =
if (dono_do_pet) then
dono_do_pet.pets [#dono_do_pet.pets+1] = nome
end
if (shadow_objeto) then
novo_objeto.shadow = shadow_objeto
novo_objeto:CriaLink (shadow_objeto) --> criando o link
shadow_objeto.flag = details_flag
end
if (novo_objeto.classe == "UNGROUPPLAYER") then --> is a player
if (_bit_band (flag, REACTION_HOSTILE ) ~= 0) then --> is hostile
novo_objeto.enemy = true --print (nome.." EH UM INIMIGO -> " .. engRace)
end
--> try to guess his class
if (shadow) then --> não executar 2x
_detalhes:ScheduleTimer ("GuessClass", 1, {novo_objeto, self, 1})
end
end
elseif (self.tipo == container_damage_target) then --> CONTAINER ALVO DO DAMAGE
if (shadow_objeto) then
novo_objeto.shadow = shadow_objeto
shadow_objeto.flag = details_flag
end
elseif (self.tipo == container_heal_target) then --> CONTAINER ALVOS DO HEALING
novo_objeto.overheal = 0
novo_objeto.absorbed = 0
if (shadow_objeto) then
novo_objeto.shadow = shadow_objeto
shadow_objeto.flag = details_flag
end
elseif (self.tipo == container_energy_target) then --> CONTAINER ALVOS DO ENERGY
novo_objeto.mana = 0
novo_objeto.e_rage = 0
novo_objeto.e_energy = 0
novo_objeto.runepower = 0
if (shadow_objeto) then
novo_objeto.shadow = shadow_objeto
shadow_objeto.flag = details_flag
end
elseif (self.tipo == container_misc_target) then --> CONTAINER ALVOS DO MISC
if (shadow_objeto) then
novo_objeto.shadow = shadow_objeto
shadow_objeto.flag = details_flag
end
elseif (self.tipo == container_friendlyfire) then --> CONTAINER FRIENDLY FIRE
get_class_ (novo_objeto, nome)
if (shadow_objeto) then
novo_objeto.shadow = shadow_objeto
shadow_objeto.flag = details_flag
end
end
-- grava o objeto no mapa do container
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- novo_objeto.combatID = _detalhes:NumeroCombate() --> grava no objeto qual o ID do combate que ele pertence -- Não serve pra nada? melhor DELETAR
--if (self.shadow and self.tipo == container_damage and self._NameIndexTable [nome]) then
-- print ("CONTAINER 3: criado actor repedido",nome, isOwner)
--end
local size = #self._ActorTable+1
self._ActorTable [size] = novo_objeto --> grava na tabela de indexes
self._NameIndexTable [nome] = size --> grava no hash map o index deste jogador
return novo_objeto, dono_do_pet, nome
else
return nil, nil, nil
end
end
function container_combatentes:FuncaoDeCriacao (tipo)
if (tipo == container_damage_target) then
return alvo_da_habilidade.NovaTabela
elseif (tipo == container_damage) then
return atributo_damage.NovaTabela
elseif (tipo == container_heal_target) then
return alvo_da_habilidade.NovaTabela
elseif (tipo == container_heal) then
return atributo_heal.NovaTabela
elseif (tipo == container_friendlyfire) then
return atributo_damage.FF_funcao_de_criacao
elseif (tipo == container_energy) then
return atributo_energy.NovaTabela
elseif (tipo == container_energy_target) then
return alvo_da_habilidade.NovaTabela
elseif (tipo == container_misc) then
return atributo_misc.NovaTabela
elseif (tipo == container_misc_target) then
return alvo_da_habilidade.NovaTabela
end
end
function container_combatentes:remapear()
local mapa = self._NameIndexTable
local conteudo = self._ActorTable
for i = 1, #conteudo do
mapa [conteudo[i].nome] = i
end
end
local function ReparaMapa (tabela)
local mapa = {}
for i = 1, #tabela._ActorTable do
mapa [tabela._ActorTable[i].nome] = i
end
tabela._NameIndexTable = mapa
end
function _detalhes.refresh:r_container_combatentes (container, shadow)
_setmetatable (container, _detalhes.container_combatentes)
container.__index = _detalhes.container_combatentes
container.funcao_de_criacao = container_combatentes:FuncaoDeCriacao (container.tipo)
ReparaMapa (container)
if (shadow ~= -1) then
container.shadow = shadow
end
end
function _detalhes.clear:c_container_combatentes (container)
container.__index = {}
container.shadow = nil
container._NameIndexTable = nil
container.need_refresh = nil
container.funcao_de_criacao = nil
end
--[[
if (not serial) then
print ("DEBUG: objeto sem serial: "..nome)
novo_objeto.classe = "UNKNOW"
else
if (_bit_band (flag, 0x00000400) ~= 0) then --> é player
local _, engClass, _, engRace = _GetPlayerInfoByGUID (serial)
novo_objeto.classe = engClass
--print (novo_objeto.classe)
--print ("eh um player ".. nome.." da classe "..engClass)
else
--print ("nao eh um player "..nome)
local _, engClass = _UnitClass (nome)
--print (engClass)
if (engClass) then
novo_objeto.classe = engClass
else
novo_objeto.classe = "UNKNOW"
end
end
--novo_objeto.classe = "UNKNOW"
end
--]]
+130
View File
@@ -0,0 +1,130 @@
local _detalhes = _G._detalhes
--local AceLocale = LibStub ("AceLocale-3.0")
--local Loc = AceLocale:GetLocale ( "Details" )
local gump = _detalhes.gump
local _setmetatable = setmetatable
local container_playernpc = _detalhes.container_type.CONTAINER_PLAYERNPC
local container_damage = _detalhes.container_type.CONTAINER_DAMAGE_CLASS
local container_heal = _detalhes.container_type.CONTAINER_HEAL_CLASS
local container_heal_target = _detalhes.container_type.CONTAINER_HEALTARGET_CLASS
local container_friendlyfire = _detalhes.container_type.CONTAINER_FRIENDLYFIRE
local container_damage_target = _detalhes.container_type.CONTAINER_DAMAGETARGET_CLASS
local container_energy = _detalhes.container_type.CONTAINER_ENERGY_CLASS
local container_energy_target = _detalhes.container_type.CONTAINER_ENERGYTARGET_CLASS
local container_misc = _detalhes.container_type.CONTAINER_MISC_CLASS
local container_misc_target = _detalhes.container_type.CONTAINER_MISCTARGET_CLASS
local habilidade_dano = _detalhes.habilidade_dano
local habilidade_cura = _detalhes.habilidade_cura
local habilidade_e_energy = _detalhes.habilidade_e_energy
local habilidade_misc = _detalhes.habilidade_misc
local container_habilidades = _detalhes.container_habilidades
function container_habilidades:NovoContainer (tipo_do_container)
local esta_tabela = {}
_setmetatable (esta_tabela, container_habilidades)
esta_tabela.funcao_de_criacao = container_habilidades:FuncaoDeCriacao (tipo_do_container)
if (not esta_tabela.funcao_de_criacao) then
print ("DEBUG: Sem funcao de criacao para a habilidade... TIPO: ")
print (tipo_do_container)
end
esta_tabela.tipo = tipo_do_container
esta_tabela._ActorTable = {}
return esta_tabela
end
function container_habilidades:Dupe (who)
local novo_objeto = {}
if (_getmetatable (who)) then
_setmetatable (novo_objeto, _getmetatable (who))
end
for cprop, value in _pairs (who) do
novo_objeto[cprop] = value
end
return novo_objeto
end
function container_habilidades:GetSpell (id)
return self._ActorTable [id]
end
function container_habilidades:PegaHabilidade (id, criar, token, cria_shadow)
local esta_habilidade = self._ActorTable [id]
if (esta_habilidade) then
return esta_habilidade
else
if (criar) then
if (cria_shadow) then
local novo_objeto = self.funcao_de_criacao (_, id, nil, "")
self._ActorTable [id] = novo_objeto
return novo_objeto
end
local shadow = self.shadow --> retorna o container semelhante a esta na tabela overall
local shadow_objeto = nil
if (shadow) then --> talvez possa mandar todos os parâmetros de criação logo no inicio
shadow_objeto = shadow:PegaHabilidade (id) --> apenas verifica se ele existe ou não
if (not shadow_objeto) then --> se não existir, cria-lo
shadow_objeto = shadow:PegaHabilidade (id, true, token)
end
end
--local novo_objeto = habilidade_dano:NovaTabela (id, shadow_objeto)
local novo_objeto = self.funcao_de_criacao (_, id, shadow_objeto, token)
if (shadow_objeto) then --> link é esta mesma tabela mas no container do overall
novo_objeto.shadow = shadow_objeto --> diz ao objeto qual a shadow dele na tabela overall
--novo_objeto:CriaLink (shadow_objeto) --> cria o link entre o objeto e a sua shadow
end
self._ActorTable [id] = novo_objeto
return novo_objeto
else
return nil
end
end
end
function container_habilidades:FuncaoDeCriacao (tipo)
if (tipo == container_damage) then
return habilidade_dano.NovaTabela
elseif (tipo == container_heal) then
return habilidade_cura.NovaTabela
elseif (tipo == container_energy) then
return habilidade_e_energy.NovaTabela
elseif (tipo == container_misc) then
return habilidade_misc.NovaTabela
end
end
function _detalhes.refresh:r_container_habilidades (container, shadow)
_setmetatable (container, _detalhes.container_habilidades)
container.__index = _detalhes.container_habilidades
local func_criacao = container_habilidades:FuncaoDeCriacao (container.tipo)
container.funcao_de_criacao = func_criacao
if (shadow ~= -1) then
container.shadow = shadow
end
end
function _detalhes.clear:c_container_habilidades (container)
container.__index = {}
container.shadow = nil
container.funcao_de_criacao = nil
end
+131
View File
@@ -0,0 +1,131 @@
--lua api
local _table_remove = table.remove
local _table_insert = table.insert
local _setmetatable = setmetatable
local _table_wipe = table.wipe
local _detalhes = _G._detalhes
local gump = _detalhes.gump
local combate = _detalhes.combate
local historico = _detalhes.historico
local barra_total = _detalhes.barra_total
local container_pets = _detalhes.container_pets
local timeMachine = _detalhes.timeMachine
function historico:NovoHistorico()
local esta_tabela = {}
_setmetatable (esta_tabela, historico)
esta_tabela.tabelas = {} --guarda as tabelas dos combates
return esta_tabela
end
--> sai do combate, chamou adicionar a tabela ao histórico
function historico:adicionar (tabela)
local tamanho = #self.tabelas
--> verifica se precisa dar UnFreeze()
if (tamanho < _detalhes.segments_amount) then --> vai preencher um novo index vazio
local ultima_tabela = self.tabelas[tamanho]
if (not ultima_tabela) then --> não ha tabelas no historico, esta será a #1
--> pega a tabela do combate atual
ultima_tabela = tabela
end
_detalhes:InstanciaCallFunction (_detalhes.CheckFreeze, tamanho+1, ultima_tabela)
end
--> reordena as tabelas
_table_insert (self.tabelas, 1, tabela)
--> chama a função que irá atualizar as instâncias com segmentos no histórico
_detalhes:InstanciaCallFunction (_detalhes.AtualizaSegmentos_AfterCombat, self)
--> verifica se precisa apagar a última tabela do histórico
if (#self.tabelas > _detalhes.segments_amount) then
-- BETA subtração do combate overall
_detalhes.tabela_overall = _detalhes.tabela_overall - self.tabelas [#self.tabelas]
_detalhes.tabela_overall.start_time = _detalhes.tabela_overall.start_time + (self.tabelas[#self.tabelas].end_time-self.tabelas[#self.tabelas].start_time)
--print (#self.tabelas)
local amt_mortes = #self.tabelas[#self.tabelas].last_events_tables --> quantas mortes teve nessa luta
if (amt_mortes > 0) then
for i = #_detalhes.tabela_overall.last_events_tables, #_detalhes.tabela_overall.last_events_tables-amt_mortes, -1 do
_table_remove (_detalhes.tabela_overall.last_events_tables, #_detalhes.tabela_overall.last_events_tables)
end
end
_table_remove (self.tabelas, #self.tabelas)
_detalhes:SendEvent ("DETAILS_DATA_SEGMENTREMOVED", nil, nil)
end
_detalhes:InstanciaCallFunction (_detalhes.AtualizarJanela)
end
--> verifica se tem alguma instancia congelada mostrando o segmento recém liberado
function _detalhes:CheckFreeze (instancia, index_liberado, tabela)
if (instancia.freezed) then --> esta congelada
if (instancia.segmento == index_liberado) then
instancia.showing = tabela
instancia:UnFreeze()
end
end
end
function historico:resetar()
if (_detalhes.bosswindow) then
_detalhes.bosswindow:Reset()
end
if (_detalhes.tabela_vigente.verifica_combate) then --> finaliza a checagem se esta ou não no combate
_detalhes:CancelTimer (_detalhes.tabela_vigente.verifica_combate)
end
--> fecha a janela de informações do jogador
_detalhes:FechaJanelaInfo()
-- novo container de historico
_detalhes.tabela_historico = historico:NovoHistorico() --joga fora a tabela antiga e cria uma nova
--novo container para armazenar pets
_detalhes.tabela_pets = _detalhes.container_pets:NovoContainer()
_detalhes.container_pets:BuscarPets()
-- nova tabela do overall e current
_detalhes.tabela_overall = combate:NovaTabela() --joga fora a tabela antiga e cria uma nova
-- cria nova tabela do combate atual
_detalhes.tabela_vigente = combate:NovaTabela (_, _detalhes.tabela_overall)
--marca o addon como fora de combate
_detalhes.in_combat = false
--zera o contador de combates
_detalhes:NumeroCombate (0)
--> limpa o cache de magias
_detalhes:ClearSpellCache()
--> limpa a tabela de escudos
_table_wipe (_detalhes.escudos)
--> reinicia a time machine
timeMachine:Reiniciar()
_detalhes:InstanciaCallFunction (_detalhes.AtualizaSegmentos) -- atualiza o instancia.showing para as novas tabelas criadas
_detalhes:InstanciaCallFunction (_detalhes.AtualizaSoloMode_AfertReset) -- verifica se precisa zerar as tabela da janela solo mode
_detalhes:InstanciaCallFunction (_detalhes.ResetaGump) --_detalhes:ResetaGump ("de todas as instancias")
_detalhes:InstanciaCallFunction (gump.Fade, "in", nil, "barras")
_detalhes:AtualizaGumpPrincipal (-1) --atualiza todas as instancias
_detalhes:UpdateParserGears()
_detalhes:SendEvent ("DETAILS_DATA_RESET", nil, nil)
end
function _detalhes.refresh:r_historico (este_historico)
_setmetatable (este_historico, historico)
--este_historico.__index = historico
end
+149
View File
@@ -0,0 +1,149 @@
local _detalhes = _G._detalhes
local gump = _detalhes.gump
local container_pets = _detalhes.container_pets
-- api locals
local _UnitGUID = UnitGUID
local _UnitName = UnitName
local _GetUnitName = GetUnitName
local _IsInRaid = IsInRaid
local _IsInGroup = IsInGroup
local _GetNumGroupMembers = GetNumGroupMembers
-- lua locals
local _setmetatable = setmetatable
function container_pets:NovoContainer()
local esta_tabela = {}
_setmetatable (esta_tabela, _detalhes.container_pets)
esta_tabela.pets = {} --> armazena a pool -> uma dictionary com o [serial do pet] -> nome do dono
esta_tabela._ActorTable = {} --> armazena os 15 ultimos pets do jogador -> [jogador nome] -> {nil, nil, nil, ...}
return esta_tabela
end
function container_pets:PegaDono (pet_serial, pet_nome, pet_flags)
local busca = self.pets [pet_serial]
local dono_nome, dono_serial, dono_flags
if (busca) then
--debug: print ("achou o pet no container de donos")
dono_nome, dono_serial, dono_flags = busca[1], busca[2], busca[3]
return pet_nome .." <"..dono_nome..">", dono_nome, dono_serial, dono_flags
end
if (_IsInRaid()) then
--print ("estou em RAIDE")
for i = 1, _GetNumGroupMembers(), 1 do
if (pet_serial == _UnitGUID ("raidpet"..i)) then
dono_serial = _UnitGUID ("raid"..i)
dono_flags = 0x00000417 --> emulate sourceflag flag
local nome, realm = _UnitName ("raid"..i)
if (realm) then
nome = nome.."-"..realm
end
dono_nome = nome
--print ("Dono encontrado na raide")
end
end
elseif (_IsInGroup()) then
--print ("DEBUG estou em PARTY")
for i = 1, _GetNumGroupMembers()-1, 1 do
if (pet_serial == _UnitGUID ("partypet"..i)) then
dono_serial = _UnitGUID ("party"..i)
dono_flags = 0x00000417 --> emulate sourceflag flag
local nome, realm = _UnitName ("party"..i)
if (realm) then
nome = nome.."-"..realm
end
dono_nome = nome
--print ("DEBUG Dono encontrado na party")
end
end
end
if (not dono_nome) then
if (pet_serial == _UnitGUID ("pet")) then
dono_nome = _GetUnitName ("player")
dono_serial = _UnitGUID ("player")
if (_IsInGroup() or _IsInRaid()) then
dono_flags = 0x00000417 --> emulate sourceflag flag
else
dono_flags = 0x00000411 --> emulate sourceflag flag
end
end
end
if (dono_nome) then
--print ("dono encontrado, adicionando ao cache")
self.pets [pet_serial] = {dono_nome, dono_serial, dono_flags, _detalhes._tempo} --> adicionada a flag emulada
return pet_nome .." <"..dono_nome..">", dono_nome, dono_serial, dono_flags
else
--if (_GetNumGroupMembers() > 0) then
--print ("DEBUG: Pet sem dono: "..pet_nome)
--end
--print ("DEBUG Nao foi possivel achar o dono de "..pet_nome)
end
return nil, nil, nil, nil
end
--> ao ter raid roster update, precisa dar foreach no container de pets e verificar as flags
--> o mesmo precisa ser feito com as tabelas de combate
function container_pets:BuscarPets()
if (_IsInRaid()) then
for i = 1, _GetNumGroupMembers(), 1 do
local pet_serial = _UnitGUID ("raidpet"..i)
if (pet_serial) then
if (not _detalhes.tabela_pets.pets [pet_serial]) then
local nome, realm = _UnitName ("raid"..i)
if (realm) then
nome = nome.."-"..realm
end
_detalhes.tabela_pets:Adicionar (pet_serial, _UnitName ("raidpet"..i), 2600, _UnitGUID ("raid"..i), nome, 0x514, true)
--print ("PET FOUND on Buscar Pets!", _GetUnitName ("raid"..i, true), _detalhes:trim (_GetUnitName ("raid"..i, true)))
end
end
end
elseif (_IsInGroup()) then
for i = 1, _GetNumGroupMembers()-1, 1 do
local pet_serial = _UnitGUID ("partypet"..i)
if (pet_serial) then
if (not _detalhes.tabela_pets.pets [pet_serial]) then
local nome, realm = _UnitName ("party"..i)
if (realm) then
nome = nome.."-"..realm
end
_detalhes.tabela_pets:Adicionar (pet_serial, _UnitName ("partypet"..i), 2600, _UnitGUID ("party"..i), nome, 0x514)
end
end
end
end
end
function container_pets:Adicionar (pet_serial, pet_nome, pet_flags, dono_serial, dono_nome, dono_flags, fromSearch)
self.pets [pet_serial] = {dono_nome, dono_serial, dono_flags, _detalhes._tempo}
--if (fromSearch) then
-- local d = self.pets [pet_serial]
--print ("dono nome:",d[1], "dono serial:", d[2], "dono flags:", d[3], "tempo:", d[4])
--end
if (self.pets [dono_serial]) then
--print ("debug: a owner is a pet, Owner: ", dono_nome, " Pet: ", pet_nome)
end
end
function _detalhes.refresh:r_container_pets (container)
_setmetatable (container, container_pets)
--container.__index = container_pets
end
+481
View File
@@ -0,0 +1,481 @@
--File Revision: 1
--Last Modification: 27/07/2013
-- Change Log:
-- 27/07/2013: Finished alpha version.
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
local _detalhes = _G._detalhes
local Loc = LibStub ("AceLocale-3.0"):GetLocale ( "Details" )
local _tempo = time()
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> local pointers
local _math_floor = math.floor --lua local
local _ipairs = ipairs --lua local
local _pairs = pairs --lua local
local _table_wipe = table.wipe --lua local
local _bit_band = bit.band --lua local
local _GetInstanceInfo = GetInstanceInfo --wow api local
local _UnitExists = UnitExists --wow api local
local _UnitGUID = UnitGUID --wow api local
local atributo_damage = _detalhes.atributo_damage --details local
local atributo_heal = _detalhes.atributo_heal --details local
local atributo_energy = _detalhes.atributo_energy --details local
local atributo_misc = _detalhes.atributo_misc --details local
local atributo_custom = _detalhes.atributo_custom --details local
local info = _detalhes.janela_info --details local
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> constants
local modo_GROUP = _detalhes.modos.group
local modo_ALL = _detalhes.modos.all
local class_type_dano = _detalhes.atributos.dano
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> details api functions
--> try to find the opponent of last fight, can be called during a fight as well
function _detalhes:FindEnemy()
for _, actor in _ipairs (_detalhes.tabela_vigente[class_type_dano]._ActorTable) do
if (not actor.grupo and not actor.owner and not actor.nome:find ("[*]") and _bit_band (actor.flag, 0x00000060) ~= 0) then --> 0x20+0x40 neutral + enemy reaction
for name, _ in _pairs (actor.targets._NameIndexTable) do
if (name == _detalhes.playername) then
return actor.nome
else
local _target_actor = _detalhes.tabela_vigente (class_type_dano, name)
if (_target_actor and _target_actor.grupo) then
return actor.nome
end
end
end
end
end
return Loc ["STRING_UNKNOW"]
end
-- try get the current encounter name during the encounter
function _detalhes:ReadBossFrames()
for index = 1, 5, 1 do
if (_UnitExists ("boss"..index)) then
local guid = _UnitGUID ("boss"..index)
if (guid) then
local serial = tonumber (guid:sub(6, 10), 16)
if (serial) then
local ZoneName, _, _, _, _, _, _, ZoneMapID = _GetInstanceInfo()
local BossIds = _detalhes:GetBossIds (ZoneMapID)
if (BossIds) then
local BossIndex = BossIds [serial]
if (BossIndex) then
if (_detalhes.in_combat) then
local bossFunction, bossFunctionType = _detalhes:GetBossFunction (ZoneMapID, BossIndex)
if (bossFunction) then
if (_bit_band (bossFunctionType, 0x1) ~= 0) then --realtime
_detalhes.bossFunction = bossFunction
local combat = _detalhes:GetCombat ("current")
combat.bossFunction = _detalhes:ScheduleTimer ("bossFunction", 1)
end
end
end
_detalhes.tabela_vigente.is_boss = {
index = BossIndex,
name = _detalhes:GetBossName (ZoneMapID, BossIndex),
zone = ZoneName,
mapid = ZoneMapID,
encounter = _detalhes:GetBossName (ZoneMapID, BossIndex)
}
_detalhes:SendEvent ("COMBAT_BOSS_FOUND", nil, _detalhes.tabela_vigente.is_boss.index, _detalhes.tabela_vigente.is_boss.name)
return _detalhes.tabela_vigente.is_boss
end
end
end
end
end
end
end
--try to get the encounter name after the encounter (can be called during the combat as well)
function _detalhes:FindBoss()
local ZoneName, _, _, _, _, _, _, ZoneMapID = _GetInstanceInfo()
local BossIds = _detalhes:GetBossIds (ZoneMapID)
if (BossIds) then
local BossIndex = nil
local ActorsContainer = _detalhes.tabela_vigente [class_type_dano]._ActorTable
if (ActorsContainer) then
for index, Actor in _ipairs (ActorsContainer) do
if (not Actor.grupo) then
local serial = tonumber (Actor.serial:sub(6, 10), 16)
if (serial) then
BossIndex = BossIds [serial]
if (BossIndex) then
Actor.boss = true
Actor.shadow.boss = true
_detalhes:FlagActorsOnBossFight()
return {
index = BossIndex,
name =_detalhes:GetBossName (ZoneMapID, BossIndex),
zone = ZoneName,
mapid = ZoneMapID,
encounter = _detalhes:GetBossName (ZoneMapID, BossIndex)}
end
end
end
end
end
end
return false
end
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> internal functions
function _detalhes:EntrarEmCombate (...)
if (_detalhes.debug) then
print ("Details started a new combat.")
end
--> não tem historico, addon foi resetado, a primeira tabela é descartada -- Erase first table is does not have a firts segment history, this occour after reset or first run
if (not _detalhes.tabela_historico.tabelas[1]) then
--> precisa zerar aqui a tabela overall
_table_wipe (_detalhes.tabela_overall)
_table_wipe (_detalhes.tabela_vigente)
--> aqui ele perdeu o self.showing das instâncias, precisa fazer com que elas atualizem
_detalhes.tabela_overall = _detalhes.combate:NovaTabela()
_detalhes:InstanciaCallFunction (_detalhes.ResetaGump, _, -1) --> reseta scrollbar, iterators, rodapé, etc
_detalhes:InstanciaCallFunction (_detalhes.InstanciaFadeBarras, -1) --> esconde todas as barras
_detalhes:InstanciaCallFunction (_detalhes.AtualizaSegmentos) --> atualiza o showing
end
--> conta o tempo na tabela overall -- start time at overall table
if (_detalhes.tabela_overall.end_time) then
_detalhes.tabela_overall.start_time = _tempo - (_detalhes.tabela_overall.end_time - _detalhes.tabela_overall.start_time)
_detalhes.tabela_overall.end_time = nil
else
_detalhes.tabela_overall.start_time = _tempo
end
--> re-lock nos tempos da tabela passada -- lock again last table times
_detalhes.tabela_vigente:TravarTempos() --> lá em cima é feito wipe, não deveria ta dando merda nisso aqui? ou ela puxa da __index e da zero jogadores no mapa e container
local n_combate = _detalhes:NumeroCombate (1) --aumenta o contador de combates -- combat number up
--> cria a nova tabela de combates -- create new table
_detalhes.tabela_vigente = _detalhes.combate:NovaTabela (true, _detalhes.tabela_overall, n_combate, ...) --cria uma nova tabela de combate
--> verifica se há alguma instância mostrando o segmento atual -- change segment
_detalhes:InstanciaCallFunction (_detalhes.TrocaSegmentoAtual)
_detalhes.tabela_vigente:seta_data (_detalhes._detalhes_props.DATA_TYPE_START) --seta na tabela do combate a data do inicio do combate -- setup time data
_detalhes.in_combat = true --sinaliza ao addon que há um combate em andamento -- in combat flag up
_detalhes.tabela_vigente.combat_id = n_combate --> grava o número deste combate na tabela atual -- setup combat id on new table
--> é o timer que ve se o jogador ta em combate ou não -- check if any party or raid members are in combat
_detalhes.tabela_vigente.verifica_combate = _detalhes:ScheduleRepeatingTimer ("EstaEmCombate", 1)
_detalhes.container_pets:BuscarPets()
_detalhes:UpdateParserGears()
_detalhes:SendEvent ("COMBAT_PLAYER_ENTER", nil, _detalhes.tabela_vigente)
end
function _detalhes:SairDoCombate()
--> pega a zona do jogador e vê se foi uma luta contra um Boss -- identifica se a luta foi com um boss
if (not _detalhes.tabela_vigente.is_boss) then
_detalhes.tabela_vigente.is_boss = _detalhes:FindBoss()
else
_detalhes:FlagActorsOnBossFight()
end
if (_detalhes.debug) then
print ("Details ended a combat.")
end
if (not _detalhes.tabela_vigente.is_boss) then
local inimigo = _detalhes:FindEnemy()
if (inimigo) then
if (_detalhes.debug) then
print ("Details last fight against: " .. inimigo)
end
end
_detalhes.tabela_vigente.enemy = inimigo
else
_detalhes.tabela_vigente.enemy = _detalhes.tabela_vigente.is_boss.encounter
_detalhes:CaptureSet (false, "damage", false, 30)
_detalhes:CaptureSet (false, "heal", false, 30)
if (_detalhes.debug) then
print ("Details found a boss on last fight, freezing parser for 30 seconds.")
end
local bossFunction, bossFunctionType = _detalhes:GetBossFunction (_detalhes.tabela_vigente.is_boss.mapid, _detalhes.tabela_vigente.is_boss.index)
if (bossFunction) then
if (_bit_band (bossFunctionType, 0x2) ~= 0) then --end of combat
bossFunction()
end
end
end
if (_detalhes.tabela_vigente.bossFunction) then
_detalhes:CancelTimer (_detalhes.tabela_vigente.bossFunction)
_detalhes.bossFunction = nil
end
--> finaliza a checagem se esta ou não no combate -- finish combat check
if (_detalhes.tabela_vigente.verifica_combate) then
_detalhes:CancelTimer (_detalhes.tabela_vigente.verifica_combate)
_detalhes.tabela_vigente.verifica_combate = nil
end
--> lock timers
_detalhes.tabela_vigente:TravarTempos()
_detalhes.tabela_vigente:seta_data (_detalhes._detalhes_props.DATA_TYPE_END) --> salva hora, minuto, segundo do fim da luta
_detalhes.tabela_overall:seta_data (_detalhes._detalhes_props.DATA_TYPE_END) --> salva hora, minuto, segundo do fim da luta
_detalhes.tabela_vigente:seta_tempo_decorrido() --> salva o end_time
_detalhes.tabela_overall:seta_tempo_decorrido() --seta o end_time
local tempo_do_combate = _detalhes.tabela_vigente.end_time - _detalhes.tabela_vigente.start_time
if (_detalhes.solo) then
--> debuffs need a checkup, not well functional right now
_detalhes.CloseSoloDebuffs()
end
if ( tempo_do_combate >= _detalhes.minimum_combat_time) then --> tempo minimo precisa ser 5 segundos pra acrecentar a tabela ao historico
_detalhes.tabela_historico:adicionar (_detalhes.tabela_vigente) --move a tabela atual para dentro do histórico
else
--> this is a little bit complicated, need a specific function for combat cancellation
if (_detalhes.tabela_overall.end_time) then --> no inicio do combate o tempo do overall vai pra NIL o.0
_detalhes.tabela_overall.start_time = _detalhes.tabela_overall.start_time + tempo_do_combate --> assim ele descarta o tempo de combate na tabela do everall
else
_detalhes.tabela_overall.start_time = 0 --> tempo inicio igual a zero pois se o end_time é NIL significa que é a primeira vez que ocorre o combate na tabela overall
end
_detalhes.tabela_overall = _detalhes.tabela_overall - _detalhes.tabela_vigente --> isso aqui é novo, ele vai subtrair da overall qualquer dado adicionado na tabela descardata
_table_wipe (_detalhes.tabela_vigente) --> descarta ela, não será mais usada
_detalhes.tabela_vigente = _detalhes.tabela_historico.tabelas[1] --> pega a tabela do ultimo combate
if (not _detalhes.tabela_vigente) then --> provavel foi o primeiro combate após um reset
_detalhes.tabela_vigente = _detalhes.combate:NovaTabela (false, _detalhes.tabela_overall) --cria uma nova tabela de combate caso não tenha nenhuma no historico
end
--> tabela foi descartada, precisa atualizar os baseframes // precisa atualizer todos ou apenas o overall?
_detalhes:InstanciaCallFunction (_detalhes.AtualizarJanela)
if (_detalhes.solo) then
local esta_instancia = _detalhes.tabela_instancias[_detalhes.solo]
if (_detalhes.SoloTables.CombatID == _detalhes:NumeroCombate()) then --> significa que o solo mode validou o combate, como matar um bixo muito low level com uma só porrada
if (_detalhes.SoloTables.CombatIDLast and _detalhes.SoloTables.CombatIDLast ~= 0) then --> volta os dados da luta anterior
_detalhes.SoloTables.CombatID = _detalhes.SoloTables.CombatIDLast
_detalhes:RefreshSolo()
else
_detalhes:RefreshSolo()
_detalhes.SoloTables.CombatID = nil
end
end
end
_detalhes:NumeroCombate (-1)
_detalhes:UpdateParserGears()
end
_detalhes.in_combat = false --sinaliza ao addon que não há combate no momento
_detalhes:UpdateParserGears()
_detalhes:SendEvent ("COMBAT_PLAYER_LEAVE", nil, _detalhes.tabela_vigente)
end
function _detalhes:FlagActorsOnBossFight()
for class_type, container in _ipairs (_detalhes.tabela_vigente) do
for _, actor in _ipairs (container._ActorTable) do
if (not actor.grupo and not actor.boss) then
if (_bit_band (actor.flag, _detalhes.flags.friend) == 0) then
actor.boss_fight_component = true
local shadow = _detalhes.tabela_overall (class_type, actor.nome)
if (shadow) then
shadow.boss_fight_component = true
else
print ("Nao achou a shadow em FlagActorsOnBossFight()")
end
end
end
end
end
end
function _detalhes:AtualizarJanela (instancia, _segmento)
if (_segmento) then --> apenas atualizar janelas que estejam mostrando o segmento solicitado
if (_segmento == instancia.segmento) then
instancia:TrocaTabela (instancia, instancia.segmento, instancia.atributo, instancia.sub_atributo, true)
end
else
if (instancia.modo == modo_GROUP or instancia.modo == modo_ALL) then
instancia:TrocaTabela (instancia, instancia.segmento, instancia.atributo, instancia.sub_atributo, true)
end
end
end
function _detalhes:TrocaSegmentoAtual (instancia)
if (instancia.segmento == 0) then --> esta mostrando a tabela Atual
instancia.showing =_detalhes.tabela_vigente
instancia:ResetaGump()
_detalhes.gump:Fade (instancia, "in", nil, "barras")
end
end
--> internal GetCombatId() version
function _detalhes:NumeroCombate (flag)
if (flag == 0) then
_detalhes.combat_id = 0
elseif (flag) then
_detalhes.combat_id = _detalhes.combat_id + flag
end
return _detalhes.combat_id
end
--> tooltip fork
function _detalhes:MontaTooltip (qual_barra)
local esta_barra = self.barras [qual_barra] --> barra que o mouse passou em cima e irá mostrar o tooltip
local objeto = esta_barra.minha_tabela --> pega a referencia da tabela --> retorna a classe_damage ou classe_heal
if (not objeto) then --> a barra não possui um objeto
return false
end
_detalhes.popup:Close()
--verifica por tooltips especiais:
if (objeto.dead) then --> é uma barra de dead
return _detalhes:ToolTipDead (self, objeto, esta_barra) --> instância, [morte], barra
end
return objeto:ToolTip (self, qual_barra, esta_barra) --> instância, nº barra, objeto barra
end
function _detalhes:EndRefresh (instancia, total, tabela_do_combate, showing)
_detalhes:EsconderBarrasNaoUsadas (instancia, showing)
end
function _detalhes:EsconderBarrasNaoUsadas (instancia, showing)
--> primeira atualização após uma mudança de segmento --> verifica se há mais barras sendo mostradas do que o necessário
--------------------
if (instancia.v_barras) then
for barra_numero = instancia.barrasInfo.mostrando+1, instancia.barrasInfo.criadas do
_detalhes.gump:Fade (instancia.barras[barra_numero], "in")
end
instancia.v_barras = false
end
return showing
end
--> call update functions
function _detalhes:AtualizarALL (forcar)
local tabela_do_combate = self.showing
--> confere se a instância possui uma tabela válida
if (not tabela_do_combate) then
if (not self.freezed) then
return self:Freeze()
end
return
end
if (not tabela_do_combate[self.atributo].need_refresh and not forcar) then
return --> não precisa de refresh
end
if (self.atributo == 1) then --> damage
return atributo_damage:RefreshWindow (self, tabela_do_combate, forcar)
elseif (self.atributo == 2) then --> heal
return atributo_heal:RefreshWindow (self, tabela_do_combate, forcar)
elseif (self.atributo == 3) then --> energy
return atributo_energy:RefreshWindow (self, tabela_do_combate, forcar)
elseif (self.atributo == 4) then --> outros
return atributo_misc:RefreshWindow (self, tabela_do_combate, forcar)
elseif (self.atributo == 5) then --> ocustom
return atributo_custom:RefreshWindow (self, tabela_do_combate, forcar)
end
end
function _detalhes:AtualizaGumpPrincipal (instancia, forcar)
if (not instancia or type (instancia) == "boolean") then --> o primeiro parâmetro não foi uma instância ou ALL
forcar = instancia
instancia = self
end
if (instancia == -1) then
local refresh_poll = {}
for _, esta_instancia in _ipairs (_detalhes.tabela_instancias) do
if (esta_instancia.ativa) then
if (esta_instancia.modo == modo_GROUP or esta_instancia.modo == modo_ALL) then
local atributo = esta_instancia:AtualizarALL (forcar)
if (atributo) then
refresh_poll [#refresh_poll+1] = atributo
end
end
end
end
for _, atributo in _ipairs (refresh_poll) do
atributo.need_refresh = false
end
if (not forcar) then --atualizar o gump de detalhes também se ele estiver aberto
if (info.ativo) then
return info.jogador:MontaInfo()
end
end
return
else
if (not instancia.ativa) then
return
end
end
if (instancia.modo == modo_ALL or instancia.modo == modo_GROUP) then
return instancia:AtualizarALL (forcar)
end
end
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> core
function _detalhes:UpdateControl()
_tempo = _detalhes._tempo
end
+9
View File
@@ -0,0 +1,9 @@
local _detalhes = _G._detalhes
function _detalhes:UpdateGears()
_detalhes:UpdateParser()
_detalhes:UpdateControl()
_detalhes:UpdateCombat()
end
+856
View File
@@ -0,0 +1,856 @@
--File Revision: 1
--Last Modification: 27/07/2013
-- Change Log:
-- 27/07/2013: Finished alpha version.
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
local _detalhes = _G._detalhes
local _tempo = time()
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> local pointers
local _pairs = pairs --lua local
local _ipairs = ipairs --lua local
local _rawget = rawget --lua local
local _setmetatable = setmetatable --lua local
local _table_remove = table.remove --lua local
local _bit_band = bit.band --lua local
local _table_wipe = table.wipe --lua local
local _time = time --lua local
local _InCombatLockdown = InCombatLockdown --wow api local
local atributo_damage = _detalhes.atributo_damage --details local
local atributo_heal = _detalhes.atributo_heal --details local
local atributo_energy = _detalhes.atributo_energy --details local
local atributo_misc = _detalhes.atributo_misc --details local
local alvo_da_habilidade = _detalhes.alvo_da_habilidade --details local
local habilidade_dano = _detalhes.habilidade_dano --details local
local habilidade_cura = _detalhes.habilidade_cura --details local
local container_habilidades = _detalhes.container_habilidades --details local
local container_combatentes = _detalhes.container_combatentes --details local
local container_damage_target = _detalhes.container_type.CONTAINER_DAMAGETARGET_CLASS
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> constants
local class_type_dano = _detalhes.atributos.dano
local class_type_cura = _detalhes.atributos.cura
local class_type_e_energy = _detalhes.atributos.e_energy
local class_type_misc = _detalhes.atributos.misc
local DFLAG_pet = _detalhes.flags.pet
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> core
local function ReconstroiMapa (tabela)
local mapa = {}
for i = 1, #tabela._ActorTable do
mapa [tabela._ActorTable[i].nome] = i
end
tabela._NameIndexTable = mapa
end
local function ReduzTotal (_actor, _combate)
if (_actor.tipo == class_type_dano) then
_combate.totals [class_type_dano] = _combate.totals [class_type_dano] - _actor.total
if (_actor.grupo) then
_combate.totals_grupo [class_type_dano] = _combate.totals_grupo [class_type_dano] - _actor.total
end
elseif (_actor.tipo == class_type_cura) then
_combate.totals [class_type_cura] = _combate.totals [class_type_cura] - _actor.total
if (_actor.grupo) then
_combate.totals_grupo [class_type_cura] = _combate.totals_grupo [class_type_cura] - _actor.total
end
elseif (_actor.tipo == class_type_e_energy) then
_combate.totals [_actor.tipo] ["mana"] = _combate.totals [_actor.tipo] ["mana"] - _actor.mana
_combate.totals [_actor.tipo] ["e_rage"] = _combate.totals [_actor.tipo] ["e_rage"] - _actor.e_rage
_combate.totals [_actor.tipo] ["e_energy"] = _combate.totals [_actor.tipo] ["e_energy"] - _actor.e_energy
_combate.totals [_actor.tipo] ["runepower"] = _combate.totals [_actor.tipo] ["runepower"] - _actor.runepower
if (_actor.grupo) then
_combate.totals_grupo [_actor.tipo] ["runepower"] = _combate.totals_grupo [_actor.tipo] ["runepower"] - _actor.runepower
_combate.totals_grupo [_actor.tipo] ["e_energy"] = _combate.totals_grupo [_actor.tipo] ["e_energy"] - _actor.e_energy
_combate.totals_grupo [_actor.tipo] ["e_rage"] = _combate.totals_grupo [_actor.tipo] ["e_rage"] - _actor.e_rage
_combate.totals_grupo [_actor.tipo] ["mana"] = _combate.totals_grupo [_actor.tipo] ["mana"] - _actor.mana
end
elseif (_actor.tipo == class_type_misc) then
if (_actor.cc_break) then
_combate.totals [_actor.tipo] ["cc_break"] = _combate.totals [_actor.tipo] ["cc_break"] - _actor.cc_break
if (_actor.grupo) then
_combate.totals_grupo [_actor.tipo] ["cc_break"] = _combate.totals_grupo [_actor.tipo] ["cc_break"] - _actor.cc_break
end
end
if (_actor.ress) then
_combate.totals [_actor.tipo] ["ress"] = _combate.totals [_actor.tipo] ["ress"] - _actor.ress
if (_actor.grupo) then
_combate.totals_grupo [_actor.tipo] ["ress"] = _combate.totals_grupo [_actor.tipo] ["ress"] - _actor.ress
end
end
if (_actor.interrupt) then
_combate.totals [_actor.tipo] ["interrupt"] = _combate.totals [_actor.tipo] ["interrupt"] - _actor.interrupt
if (_actor.grupo) then
_combate.totals_grupo [_actor.tipo] ["interrupt"] = _combate.totals_grupo [_actor.tipo] ["interrupt"] - _actor.interrupt
end
end
if (_actor.dispell) then
_combate.totals [_actor.tipo] ["dispell"] = _combate.totals [_actor.tipo] ["dispell"] - _actor.dispell
if (_actor.grupo) then
_combate.totals_grupo [_actor.tipo] ["dispell"] = _combate.totals_grupo [_actor.tipo] ["dispell"] - _actor.dispell
end
end
if (_actor.dead) then
_combate.totals [_actor.tipo] ["dead"] = _combate.totals [_actor.tipo] ["dead"] - _actor.dead
if (_actor.grupo) then
_combate.totals_grupo [_actor.tipo] ["dead"] = _combate.totals_grupo [_actor.tipo] ["dead"] - _actor.dead
end
end
end
end
function _detalhes:RestauraMetaTables()
----------------------------//containers principais
_detalhes.refresh:r_container_pets (_detalhes.tabela_pets)
_detalhes.refresh:r_historico (_detalhes.tabela_historico)
----------------------------//combates
local tabela_overall = _detalhes.tabela_overall
local overall_dano = tabela_overall [class_type_dano]
local overall_cura = tabela_overall [class_type_cura]
local overall_energy = tabela_overall [class_type_e_energy]
local overall_misc = tabela_overall [class_type_misc]
local tabelas_de_combate = {}
for _, _tabela in _ipairs (_detalhes.tabela_historico.tabelas) do
tabelas_de_combate [#tabelas_de_combate+1] = _tabela
_tabela.__call = _detalhes.call_combate
end
tabela_overall.end_time = _tempo
tabela_overall.start_time = _tempo
if (#tabelas_de_combate > 0) then
for index, combate in _ipairs (tabelas_de_combate) do
if (combate.end_time and combate.start_time) then
tabela_overall.start_time = tabela_overall.start_time - (combate.end_time - combate.start_time)
end
_detalhes.refresh:r_combate (combate, tabela_overall)
_detalhes.refresh:r_container_combatentes (combate [class_type_dano], overall_dano)
_detalhes.refresh:r_container_combatentes (combate [class_type_cura], overall_cura)
_detalhes.refresh:r_container_combatentes (combate [class_type_e_energy], overall_energy)
_detalhes.refresh:r_container_combatentes (combate [class_type_misc], overall_misc)
local todos_atributos = {combate [class_type_dano]._ActorTable,
combate [class_type_cura]._ActorTable,
combate [class_type_e_energy]._ActorTable,
combate [class_type_misc]._ActorTable}
for class_type, atributo in _ipairs (todos_atributos) do
for _, esta_classe in _ipairs (atributo) do
local nome = esta_classe.nome
esta_classe.displayName = nome:gsub (("%-.*"), "")
local shadow
if (class_type == class_type_dano) then
shadow = overall_dano._ActorTable [overall_dano._NameIndexTable[nome]]
if (not shadow) then
--shadow = overall_dano:CriarShadow (esta_classe)
shadow = overall_dano:PegarCombatente (esta_classe.serial, esta_classe.nome, esta_classe.flag_original, true)
shadow.classe = esta_classe.classe
shadow.start_time = _tempo
shadow.end_time = _tempo
end
-- Reconstruir o container do friendly fire shadow aqui
for index, friendlyfire in _ipairs (esta_classe.friendlyfire._ActorTable) do
--> criando o objeto do friendly fire na shadow
local ff_shadow = shadow.friendlyfire:PegarCombatente (friendlyfire.serial, friendlyfire.nome, friendlyfire.flag_original, true)
friendlyfire.shadow = ff_shadow
end
_detalhes.refresh:r_atributo_damage (esta_classe, shadow)
shadow = shadow + esta_classe
elseif (class_type == class_type_cura) then
shadow = overall_cura._ActorTable [overall_cura._NameIndexTable[nome]]
if (not shadow) then
--shadow = overall_cura:CriarShadow (esta_classe)
shadow = overall_cura:PegarCombatente (esta_classe.serial, esta_classe.nome, esta_classe.flag_original, true)
shadow.classe = esta_classe.classe
shadow.start_time = _tempo
shadow.end_time = _tempo
end
_detalhes.refresh:r_atributo_heal (esta_classe, shadow)
shadow = shadow + esta_classe
elseif (class_type == class_type_e_energy) then
shadow = overall_energy._ActorTable [overall_energy._NameIndexTable[nome]]
if (not shadow) then
--shadow = overall_energy:CriarShadow (esta_classe)
shadow = overall_energy:PegarCombatente (esta_classe.serial, esta_classe.nome, esta_classe.flag_original, true)
shadow.classe = esta_classe.classe
end
_detalhes.refresh:r_atributo_energy (esta_classe, shadow)
shadow = shadow + esta_classe
elseif (class_type == class_type_misc) then
-- o problema ta na habilidade do interrupt, aqui ele só ta recriando os containers no Actor principal e não esta itinerando nas habilidades
shadow = overall_misc._ActorTable [overall_misc._NameIndexTable[nome]]
if (not shadow) then
--shadow = overall_misc:CriarShadow (esta_classe)
shadow = overall_misc:PegarCombatente (esta_classe.serial, esta_classe.nome, esta_classe.flag_original, true)
shadow.classe = esta_classe.classe
end
if (esta_classe.interrupt) then
if (not shadow.interrupt_targets) then
shadow.interrupt = 0
shadow.interrupt_targets = container_combatentes:NovoContainer (container_damage_target) --> pode ser um container de alvo de dano, pois irá usar apenas o .total
shadow.interrupt_spell_tables = container_habilidades:NovoContainer (_detalhes.container_type.CONTAINER_MISC_CLASS) --> cria o container das habilidades usadas para interromper
shadow.interrompeu_oque = {}
end
end
if (esta_classe.ress) then
if (not shadow.ress_targets) then
shadow.ress = 0
shadow.ress_targets = container_combatentes:NovoContainer (container_damage_target) --> pode ser um container de alvo de dano, pois irá usar apenas o .total
shadow.ress_spell_tables = container_habilidades:NovoContainer (_detalhes.container_type.CONTAINER_MISC_CLASS) --> cria o container das habilidades usadas para interromper
end
end
if (esta_classe.dispell) then
if (not shadow.dispell_targets) then
shadow.dispell = 0
shadow.dispell_targets = container_combatentes:NovoContainer (container_damage_target) --> pode ser um container de alvo de dano, pois irá usar apenas o .total
shadow.dispell_spell_tables = container_habilidades:NovoContainer (_detalhes.container_type.CONTAINER_MISC_CLASS) --> cria o container das habilidades usadas para interromper
shadow.dispell_oque = {}
end
end
if (esta_classe.cc_break) then
if (not shadow.cc_break) then
shadow.cc_break = 0
shadow.cc_break_targets = container_combatentes:NovoContainer (container_damage_target) --> pode ser um container de alvo de dano, pois irá usar apenas o .total
shadow.cc_break_spell_tables = container_habilidades:NovoContainer (_detalhes.container_type.CONTAINER_MISC_CLASS) --> cria o container das habilidades usadas para interromper
shadow.cc_break_oque = {}
end
end
_detalhes.refresh:r_atributo_misc (esta_classe, shadow)
shadow = shadow + esta_classe
if (esta_classe.interrupt) then
for _, este_alvo in _ipairs (esta_classe.interrupt_targets._ActorTable) do
_detalhes.refresh:r_alvo_da_habilidade (este_alvo, shadow.interrupt_targets)
end
end
if (esta_classe.ress) then
for _, este_alvo in _ipairs (esta_classe.ress_targets._ActorTable) do
_detalhes.refresh:r_alvo_da_habilidade (este_alvo, shadow.ress_targets)
end
end
if (esta_classe.dispell) then
for _, este_alvo in _ipairs (esta_classe.dispell_targets._ActorTable) do
_detalhes.refresh:r_alvo_da_habilidade (este_alvo, shadow.dispell_targets)
end
end
if (esta_classe.cc_break) then
for _, este_alvo in _ipairs (esta_classe.cc_break_targets._ActorTable) do
_detalhes.refresh:r_alvo_da_habilidade (este_alvo, shadow.cc_break_targets)
end
end
end
shadow:FazLinkagem (esta_classe)
if (class_type ~= class_type_misc) then
for _, este_alvo in _ipairs (esta_classe.targets._ActorTable) do
_detalhes.refresh:r_alvo_da_habilidade (este_alvo, shadow.targets)
end
for _, habilidade in _pairs (esta_classe.spell_tables._ActorTable) do
if (class_type == class_type_dano) then
_detalhes.refresh:r_habilidade_dano (habilidade, shadow.spell_tables) --> passando o container de habilidades
elseif (class_type == class_type_cura) then
_detalhes.refresh:r_habilidade_cura (habilidade, shadow.spell_tables)
elseif (class_type == class_type_e_energy) then
_detalhes.refresh:r_habilidade_e_energy (habilidade, shadow.spell_tables)
end
for _, este_alvo in _ipairs (habilidade.targets._ActorTable) do
_detalhes.refresh:r_alvo_da_habilidade (este_alvo, habilidade.targets.shadow)
end
end
else
if (esta_classe.interrupt) then
for _, habilidade in _pairs (esta_classe.interrupt_spell_tables._ActorTable) do
_detalhes.refresh:r_habilidade_misc (habilidade, shadow.interrupt_spell_tables)
for _, este_alvo in _ipairs (habilidade.targets._ActorTable) do
_detalhes.refresh:r_alvo_da_habilidade (este_alvo, habilidade.targets.shadow)
end
end
end
if (esta_classe.ress) then
for _, habilidade in _pairs (esta_classe.ress_spell_tables._ActorTable) do
_detalhes.refresh:r_habilidade_misc (habilidade, shadow.ress_spell_tables)
for _, este_alvo in _ipairs (habilidade.targets._ActorTable) do
_detalhes.refresh:r_alvo_da_habilidade (este_alvo, habilidade.targets.shadow)
end
end
end
if (esta_classe.dispell) then
for _, habilidade in _pairs (esta_classe.dispell_spell_tables._ActorTable) do
_detalhes.refresh:r_habilidade_misc (habilidade, shadow.dispell_spell_tables)
for _, este_alvo in _ipairs (habilidade.targets._ActorTable) do
_detalhes.refresh:r_alvo_da_habilidade (este_alvo, habilidade.targets.shadow)
end
end
end
if (esta_classe.cc_break) then
for _, habilidade in _pairs (esta_classe.cc_break_spell_tables._ActorTable) do
_detalhes.refresh:r_habilidade_misc (habilidade, shadow.cc_break_spell_tables)
for _, este_alvo in _ipairs (habilidade.targets._ActorTable) do
_detalhes.refresh:r_alvo_da_habilidade (este_alvo, habilidade.targets.shadow)
end
end
end
end
end
end
--> reconstrói a tabela dos pets
for class_type, atributo in _ipairs (todos_atributos) do
for _, esta_classe in _ipairs (atributo) do
if (esta_classe.ownerName) then --> nome do owner
esta_classe.owner = combate (class_type, esta_classe.ownerName)
end
end
end
end
end
end
function _detalhes:PrepareTablesForSave()
----------------------------//overall
local tabelas_de_combate = {}
local historico_tabelas = _detalhes.tabela_historico.tabelas or {}
--local tabela_overall = _detalhes.tabela_overall
_detalhes.tabela_overall = nil
local tabela_atual = _detalhes.tabela_vigente or {}
for _, _tabela in _ipairs (historico_tabelas) do
tabelas_de_combate [#tabelas_de_combate+1] = _tabela
end
tabelas_de_combate [#tabelas_de_combate+1] = tabela_atual
--tabelas_de_combate [#tabelas_de_combate+1] = tabela_overall
--> make sure details database exists
_detalhes_database = _detalhes_database or {}
for tabela_index, _combate in _ipairs (tabelas_de_combate) do
--> limpa a tabela do grafico -- clear graphic table
if (_detalhes.clear_graphic) then
_combate.TimeData = {}
end
local container_dano = _combate [class_type_dano] or {}
local container_cura = _combate [class_type_cura] or {}
local container_e_energy = _combate [class_type_e_energy] or {}
local container_misc = _combate [class_type_misc] or {}
local todos_atributos = {container_dano, container_cura, container_e_energy, container_misc}
local IsBossEncounter = _combate.is_boss
if (IsBossEncounter) then
if (_combate.pvp) then
IsBossEncounter = false
end
end
for class_type, _tabela in _ipairs (todos_atributos) do
local conteudo = _tabela._ActorTable
--> Limpa tabelas que não estejam em grupo
if (_detalhes.clear_ungrouped) then
local _iter = {index = 1, data = conteudo[1], cleaned = 0} --> ._ActorTable[1] para pegar o primeiro index
while (_iter.data) do --serach key: deletar apagar
local can_erase = true
if (_iter.data.grupo or _iter.data.boss or _iter.data.boss_fight_component or IsBossEncounter) then
can_erase = false
else
local owner = _iter.data.owner
if (owner) then
local owner_actor = _combate (class_type, owner.nome)
if (owner_actor) then
if (owner.grupo or owner.boss or owner.boss_fight_component) then
can_erase = false
end
end
end
end
if (can_erase) then
if (not _iter.data.owner) then --> pet (not a pet?)
local myself = _iter.data
if (myself.tipo == class_type_dano or myself.tipo == class_type_cura) then
_combate.totals [myself.tipo] = _combate.totals [myself.tipo] - myself.total
if (myself.grupo) then
_combate.totals_grupo [myself.tipo] = _combate.totals_grupo [myself.tipo] - myself.total
end
elseif (myself.tipo == class_type_e_energy) then
_combate.totals [myself.tipo] ["mana"] = _combate.totals [myself.tipo] ["mana"] - myself.mana
_combate.totals [myself.tipo] ["e_rage"] = _combate.totals [myself.tipo] ["e_rage"] - myself.e_rage
_combate.totals [myself.tipo] ["e_energy"] = _combate.totals [myself.tipo] ["e_energy"] - myself.e_energy
_combate.totals [myself.tipo] ["runepower"] = _combate.totals [myself.tipo] ["runepower"] - myself.runepower
if (myself.grupo) then
_combate.totals_grupo [myself.tipo] ["mana"] = _combate.totals_grupo [myself.tipo] ["mana"] - myself.mana
_combate.totals_grupo [myself.tipo] ["e_rage"] = _combate.totals_grupo [myself.tipo] ["e_rage"] - myself.e_rage
_combate.totals_grupo [myself.tipo] ["e_energy"] = _combate.totals_grupo [myself.tipo] ["e_energy"] - myself.e_energy
_combate.totals_grupo [myself.tipo] ["runepower"] = _combate.totals_grupo [myself.tipo] ["runepower"] - myself.runepower
end
elseif (myself.tipo == class_type_misc) then
if (myself.cc_break) then
_combate.totals [myself.tipo] ["cc_break"] = _combate.totals [myself.tipo] ["cc_break"] - myself.cc_break
if (myself.grupo) then
_combate.totals_grupo [myself.tipo] ["cc_break"] = _combate.totals_grupo [myself.tipo] ["cc_break"] - myself.cc_break
end
end
if (myself.ress) then
_combate.totals [myself.tipo] ["ress"] = _combate.totals [myself.tipo] ["ress"] - myself.ress
if (myself.grupo) then
_combate.totals_grupo [myself.tipo] ["ress"] = _combate.totals_grupo [myself.tipo] ["ress"] - myself.ress
end
end
if (myself.interrupt) then
_combate.totals [myself.tipo] ["interrupt"] = _combate.totals [myself.tipo] ["interrupt"] - myself.interrupt
if (myself.grupo) then
_combate.totals_grupo [myself.tipo] ["interrupt"] = _combate.totals_grupo [myself.tipo] ["interrupt"] - myself.interrupt
end
end
if (myself.dispell) then
_combate.totals [myself.tipo] ["dispell"] = _combate.totals [myself.tipo] ["dispell"] - myself.dispell
if (myself.grupo) then
_combate.totals_grupo [myself.tipo] ["dispell"] = _combate.totals_grupo [myself.tipo] ["dispell"] - myself.dispell
end
end
if (myself.dead) then
_combate.totals [myself.tipo] ["dead"] = _combate.totals [myself.tipo] ["dead"] - myself.dead
if (myself.grupo) then
_combate.totals_grupo [myself.tipo] ["dead"] = _combate.totals_grupo [myself.tipo] ["dead"] - myself.dead
end
end
end
end
_table_remove (conteudo, _iter.index)
_iter.cleaned = _iter.cleaned + 1
_iter.data = conteudo [_iter.index]
else
_iter.index = _iter.index + 1
_iter.data = conteudo [_iter.index]
end
end
if (_iter.cleaned > 0) then --> desencargo de consciência, reconstruir o mapa depois de excluir
ReconstroiMapa (_tabela)
end
end
for _, esta_classe in _ipairs (conteudo) do
--> limpa o displayName, não precisa salvar
esta_classe.displayName = nil
esta_classe.owner = nil
if (class_type == class_type_dano) then
_detalhes.clear:c_atributo_damage (esta_classe)
elseif (class_type == class_type_cura) then
_detalhes.clear:c_atributo_heal (esta_classe)
elseif (class_type == class_type_e_energy) then
_detalhes.clear:c_atributo_energy (esta_classe)
elseif (class_type == class_type_misc) then
_detalhes.clear:c_atributo_misc (esta_classe)
if (esta_classe.interrupt) then
for _, _alvo in _ipairs (esta_classe.interrupt_targets._ActorTable) do
_detalhes.clear:c_alvo_da_habilidade (_alvo)
end
end
if (esta_classe.ress) then
for _, _alvo in _ipairs (esta_classe.ress_targets._ActorTable) do
_detalhes.clear:c_alvo_da_habilidade (_alvo)
end
end
if (esta_classe.dispell) then
for _, _alvo in _ipairs (esta_classe.dispell_targets._ActorTable) do
_detalhes.clear:c_alvo_da_habilidade (_alvo)
end
end
if (esta_classe.cc_break) then
for _, _alvo in _ipairs (esta_classe.cc_break_targets._ActorTable) do
_detalhes.clear:c_alvo_da_habilidade (_alvo)
end
end
end
if (class_type ~= class_type_misc) then
for _, _alvo in _ipairs (esta_classe.targets._ActorTable) do
_detalhes.clear:c_alvo_da_habilidade (_alvo)
end
for _, habilidade in _pairs (esta_classe.spell_tables._ActorTable) do
if (class_type == class_type_dano) then
_detalhes.clear:c_habilidade_dano (habilidade)
elseif (class_type == class_type_cura) then
_detalhes.clear:c_habilidade_cura (habilidade)
elseif (class_type == class_type_e_energy) then
_detalhes.clear:c_habilidade_e_energy (habilidade)
end
for _, _alvo in ipairs (habilidade.targets._ActorTable) do
_detalhes.clear:c_alvo_da_habilidade (_alvo)
end
end
else
if (esta_classe.interrupt) then
for _, habilidade in _pairs (esta_classe.interrupt_spell_tables._ActorTable) do
_detalhes.clear:c_habilidade_misc (habilidade)
for _, _alvo in ipairs (habilidade.targets._ActorTable) do
_detalhes.clear:c_alvo_da_habilidade (_alvo)
end
end
end
if (esta_classe.ress) then
for _, habilidade in _pairs (esta_classe.ress_spell_tables._ActorTable) do
_detalhes.clear:c_habilidade_misc (habilidade)
for _, _alvo in ipairs (habilidade.targets._ActorTable) do
_detalhes.clear:c_alvo_da_habilidade (_alvo)
end
end
end
if (esta_classe.dispell) then
for _, habilidade in _pairs (esta_classe.dispell_spell_tables._ActorTable) do
_detalhes.clear:c_habilidade_misc (habilidade)
for _, _alvo in ipairs (habilidade.targets._ActorTable) do
_detalhes.clear:c_alvo_da_habilidade (_alvo)
end
end
end
if (esta_classe.cc_break) then
for _, habilidade in _pairs (esta_classe.cc_break_spell_tables._ActorTable) do
_detalhes.clear:c_habilidade_misc (habilidade)
for _, _alvo in ipairs (habilidade.targets._ActorTable) do
_detalhes.clear:c_alvo_da_habilidade (_alvo)
end
end
end
end
end
end
end
--> Clear Containers
for tabela_index, _combate in _ipairs (tabelas_de_combate) do
local container_dano = _combate [class_type_dano]
local container_cura = _combate [class_type_cura]
local container_e_energy = _combate [class_type_e_energy]
local container_misc = _combate [class_type_misc]
local todos_atributos = {container_dano, container_cura, container_e_energy, container_misc}
for class_type, _tabela in _ipairs (todos_atributos) do
_detalhes.clear:c_combate (_combate)
_detalhes.clear:c_container_combatentes (container_dano)
_detalhes.clear:c_container_combatentes (container_cura)
_detalhes.clear:c_container_combatentes (container_e_energy)
_detalhes.clear:c_container_combatentes (container_misc)
end
end
--> Limpa instâncias
for _, esta_instancia in _ipairs (_detalhes.tabela_instancias) do
--> detona a janela do Solo Mode
esta_instancia.barras = nil
esta_instancia.showing = nil
--> apaga os frames
esta_instancia.scroll = nil
esta_instancia.baseframe = nil
esta_instancia.bgframe = nil
esta_instancia.bgdisplay = nil
esta_instancia.freeze_icon = nil
esta_instancia.freeze_texto = nil
esta_instancia.agrupada_a = nil
esta_instancia.grupada_pos = nil
esta_instancia.agrupado = nil
if (esta_instancia.StatusBar.left) then
esta_instancia.StatusBarSaved = {
["left"] = esta_instancia.StatusBar.left.real_name or "NONE",
["center"] = esta_instancia.StatusBar.center.real_name or "NONE",
["right"] = esta_instancia.StatusBar.right.real_name or "NONE",
["options"] = esta_instancia.StatusBar.options
}
end
esta_instancia.StatusBar = nil
end
end
function _detalhes:reset_window (instancia)
if (instancia.segmento == -1) then
instancia.showing[instancia.atributo].need_refresh = true
instancia.v_barras = true
instancia:ResetaGump()
instancia:AtualizaGumpPrincipal (true)
end
end
function _detalhes:IniciarColetaDeLixo()
if (_detalhes.ultima_coleta + _detalhes.intervalo_coleta > _detalhes._tempo + 1) then
return
elseif (_detalhes.in_combat or _InCombatLockdown() or _detalhes:IsInInstance()) then
_detalhes:ScheduleTimer ("IniciarColetaDeLixo", 5)
return
end
_detalhes:ClearParserCache()
local limpados = atributo_damage:ColetarLixo() + atributo_heal:ColetarLixo() + atributo_energy:ColetarLixo() + atributo_misc:ColetarLixo()
if (limpados > 0) then
_detalhes:InstanciaCallFunction (_detalhes.reset_window)
end
--print ("coletados: " .. limpados)
_detalhes.ultima_coleta = _detalhes._tempo
end
local function FazColeta (_combate, tipo)
local conteudo = _combate [tipo]._ActorTable
local _iter = {index = 1, data = conteudo[1], cleaned = 0}
local _tempo = _time()
while (_iter.data) do
local _actor = _iter.data
local can_garbage = false
if (not _actor.grupo and not _actor.boss and not _actor.boss_fight_component and _actor.last_event + _detalhes.intervalo_coleta < _tempo) then
local owner = _actor.owner
if (owner) then
local owner_actor = _combate (tipo, owner.nome)
if (not owner.grupo and not owner.boss and not owner.boss_fight_component) then
can_garbage = true
end
else
can_garbage = true
end
end
if (can_garbage) then
if (not _actor.owner) then --> pet
ReduzTotal (_actor, _combate)
end
--> fix para a weak table
local shadow = _actor.shadow
local _it = {index = 1, link = shadow.links [1]}
while (_it.link) do
if (_it.link == _actor) then
_table_remove (shadow.links, _it.index)
_it.link = shadow.links [_it.index]
else
_it.index = _it.index+1
_it.link = shadow.links [_it.index]
end
end
_iter.cleaned = _iter.cleaned+1
_table_remove (conteudo, _iter.index)
_iter.data = conteudo [_iter.index]
else
_iter.index = _iter.index + 1
_iter.data = conteudo [_iter.index]
end
end
if (_iter.cleaned > 0) then
ReconstroiMapa (_combate [tipo])
_combate [tipo].need_refresh = true
end
return _iter.cleaned
end
function _detalhes:ColetarLixo (tipo)
for index, instancia in _ipairs (_detalhes.tabela_instancias) do
if (instancia:IsAtiva()) then
for i, barra in _ipairs (instancia.barras) do
if (not barra:IsShown()) then
barra.minha_tabela = nil
end
end
end
end
local _tempo = _time()
local limpados = 0
local tabelas_de_combate = {}
for _, _tabela in _ipairs (_detalhes.tabela_historico.tabelas) do
if (_tabela ~= _detalhes.tabela_vigente) then
tabelas_de_combate [#tabelas_de_combate+1] = _tabela
end
end
tabelas_de_combate [#tabelas_de_combate+1] = _detalhes.tabela_vigente
for _, _combate in _ipairs (tabelas_de_combate) do
limpados = limpados + FazColeta (_combate, tipo)
end
--> clear shadow tables
local _overall_combat = _detalhes.tabela_overall
local conteudo = _overall_combat [tipo]._ActorTable
_iter = {index = 1, data = conteudo[1], cleaned = 0} --> ._ActorTable[1] para pegar o primeiro index
collectgarbage()
while (_iter.data) do
local _actor = _iter.data
local meus_links = _rawget (_actor, "links")
local can_garbage = true
local new_weak_table = _setmetatable ({}, _detalhes.weaktable) --> precisa da nova weak table para remover os NILS da tabela antiga
if (meus_links) then
for _, ref in _pairs (meus_links) do --> trocando pairs por _ipairs
if (ref) then
can_garbage = false
new_weak_table [#new_weak_table+1] = ref
end
end
_table_wipe (meus_links)
end
if (tipo == 1 and #new_weak_table > 0) then
-- print (can_garbage, _actor.nome)
end
if (can_garbage or not meus_links) then --> não há referências a este objeto
if (not _actor.owner) then --> pet
ReduzTotal (_actor, _overall_combat)
end
--> apaga a referência deste jogador na tabela overall
_iter.cleaned = _iter.cleaned+1
_table_remove (conteudo, _iter.index)
_iter.data = conteudo [_iter.index]
else
_actor.links = new_weak_table
_iter.index = _iter.index + 1
_iter.data = conteudo [_iter.index]
end
end
--> elimina pets antigos
local _new_PetTable = {}
for PetSerial, PetTable in _pairs (_detalhes.tabela_pets.pets) do
if (PetTable[4] + _detalhes.intervalo_coleta > _detalhes._tempo + 1) then
_new_PetTable [PetSerial] = PetTable
end
end
_table_wipe (_detalhes.tabela_pets.pets)
_detalhes.tabela_pets.pets = _new_PetTable
--> wipa container de escudos
_table_wipe (_detalhes.escudos)
--> termina o coletor de lixo
if (_iter.cleaned > 0) then
_overall_combat[tipo].need_refresh = true
ReconstroiMapa (_overall_combat [tipo])
limpados = limpados + _iter.cleaned
end
if (limpados > 0) then
_detalhes:InstanciaCallFunction (_detalhes.ScheduleUpdate)
_detalhes:AtualizaGumpPrincipal (-1)
end
return limpados
end
File diff suppressed because it is too large Load Diff
+172
View File
@@ -0,0 +1,172 @@
--File Revision: 1
--Last Modification: 27/07/2013
-- Change Log:
-- 27/07/2013: Finished alpha version.
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
local Loc = LibStub ("AceLocale-3.0"):GetLocale ( "Details" )
local _detalhes = _G._detalhes
DETAILSPLUGIN_ALWAYSENABLED = 0x1
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> details api functions
function _detalhes:InstallPlugin (PluginType, PluginName, PluginIcon, PluginObject, PluginAbsoluteName, MinVersion)
if (MinVersion and MinVersion > _detalhes.realversion) then
print (PluginName, Loc ["STRING_TOOOLD"])
return _detalhes:NewError ("Details version is out of date.")
end
if (not PluginType) then
return _detalhes:NewError ("InstallPlugin parameter 1 (plugin type) not especified")
elseif (not PluginName) then
return _detalhes:NewError ("InstallPlugin parameter 2 (plugin name) can't be nil")
elseif (not PluginIcon) then
return _detalhes:NewError ("InstallPlugin parameter 3 (plugin icon) can't be nil")
elseif (not PluginObject) then
return _detalhes:NewError ("InstallPlugin parameter 4 (plugin object) can't be nil")
elseif (not PluginAbsoluteName) then
return _detalhes:NewError ("InstallPlugin parameter 5 (plugin absolut name) can't be nil")
end
if (_G [PluginAbsoluteName]) then
print (Loc ["STRING_PLUGIN_NAMEALREADYTAKEN"] .. ": " .. PluginName .. " name: " .. PluginAbsoluteName)
return
else
_G [PluginAbsoluteName] = PluginObject
PluginObject.real_name = PluginAbsoluteName
end
PluginObject.real_name = PluginAbsoluteName
if (PluginType == "SOLO") then
if (not PluginObject.Frame) then
return _detalhes:NewError ("plugin doesn't have a Frame, please check case-sensitive member name: Frame")
end
--> Install Plugin
_detalhes.SoloTables.Plugins [#_detalhes.SoloTables.Plugins+1] = PluginObject
_detalhes.SoloTables.Menu [#_detalhes.SoloTables.Menu+1] = {PluginName, PluginIcon}
_detalhes.SoloTables.NameTable [PluginAbsoluteName] = PluginObject
_detalhes:SendEvent ("INSTALL_OKEY", PluginObject)
_detalhes.PluginCount.SOLO = _detalhes.PluginCount.SOLO + 1
return true
elseif (PluginType == "TANK") then
--> Install Plugin
_detalhes.RaidTables.Plugins [#_detalhes.RaidTables.Plugins+1] = PluginObject
_detalhes.RaidTables.Menu [#_detalhes.RaidTables.Menu+1] = {PluginName, PluginIcon}
_detalhes.RaidTables.NameTable [PluginAbsoluteName] = PluginObject
_detalhes:SendEvent ("INSTALL_OKEY", PluginObject)
_detalhes.PluginCount.RAID = _detalhes.PluginCount.RAID + 1
return true
elseif (PluginType == "TOOLBAR") then
--> Install Plugin
_detalhes.ToolBar.Plugins [#_detalhes.ToolBar.Plugins+1] = PluginObject
_detalhes.ToolBar.NameTable [PluginAbsoluteName] = PluginObject
_detalhes:SendEvent ("INSTALL_OKEY", PluginObject)
_detalhes.PluginCount.TOOLBAR = _detalhes.PluginCount.TOOLBAR + 1
return true
elseif (PluginType == "STATUSBAR") then
--> Install Plugin
_detalhes.StatusBar.Plugins [#_detalhes.StatusBar.Plugins+1] = PluginObject
_detalhes.StatusBar.Menu [#_detalhes.StatusBar.Menu+1] = {PluginName, PluginIcon}
_detalhes.StatusBar.NameTable [PluginAbsoluteName] = PluginObject
_detalhes:SendEvent ("INSTALL_OKEY", PluginObject)
_detalhes.PluginCount.STATUSBAR = _detalhes.PluginCount.STATUSBAR + 1
return true
end
end
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> internal functions
_detalhes.PluginCount = {
["SOLO"] = 0,
["RAID"] = 0,
["TOOLBAR"] = 0,
["STATUSBAR"] = 0
}
local OnEnableFunction = function (self)
self.__parent.Enabled = true
_detalhes:SendEvent ("SHOW", self.__parent)
end
local OnDisableFunction = function (self)
_detalhes:SendEvent ("HIDE", self.__parent)
if (bit.band (self.__parent.__options, DETAILSPLUGIN_ALWAYSENABLED) == 0) then
self.__parent.Enabled = false
end
end
local BuildDefaultStatusBarMembers = function (self)
self.childs = {}
self.__index = self
function self:Setup()
_detalhes.StatusBar:OpenOptionsForChild (self)
end
end
local temp_event_function = function()
print ("=====================")
print ("Hello There plugin developer!")
print ("Please make sure you are declaring")
print ("A member called 'OnDetailsEvent' on your plugin object")
print ("With a function to receive the events like bellow:")
print ("function PluginObject:OnDetailsEvent (event, ...) end")
print ("Thank You Sir!===================")
end
function _detalhes:NewPluginObject (FrameName, PluginOptions, PluginType)
PluginOptions = PluginOptions or 0x0
local NewPlugin = {__options = PluginOptions}
local Frame = CreateFrame ("Frame", FrameName, UIParent)
Frame:RegisterEvent ("ADDON_LOADED")
Frame:RegisterEvent ("PLAYER_LOGOUT")
Frame:SetScript ("OnEvent", function(event, ...) return NewPlugin:OnEvent (event, ...) end)
Frame:Hide()
Frame.__parent = NewPlugin
if (bit.band (PluginOptions, DETAILSPLUGIN_ALWAYSENABLED) ~= 0) then
NewPlugin.Enabled = true
else
NewPlugin.Enabled = false
end
--> default members
if (PluginType == "STATUSBAR") then
BuildDefaultStatusBarMembers (NewPlugin)
end
NewPlugin.Frame = Frame
Frame:SetScript ("OnShow", OnEnableFunction)
Frame:SetScript ("OnHide", OnDisableFunction)
--> temporary details event function
NewPlugin.OnDetailsEvent = temp_event_function
setmetatable (NewPlugin, _detalhes)
return NewPlugin
end
+148
View File
@@ -0,0 +1,148 @@
--File Revision: 1
--Last Modification: 27/07/2013
-- Change Log:
-- 27/07/2013: Finished alpha version.
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
local _detalhes = _G._detalhes
local Loc = LibStub ("AceLocale-3.0"):GetLocale ( "Details" )
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> local pointers
local _math_floor = math.floor --lua local
local gump = _detalhes.gump --details local
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> constants
local modo_raid = _detalhes._detalhes_props["MODO_RAID"]
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> internal functions
function _detalhes:RaidMode (enable, instancia)
if (enable) then
_detalhes.RaidTables.instancia = instancia
_detalhes.RaidTables.Mode = _detalhes.RaidTables.Mode or 1 --> solo mode
instancia.modo = _detalhes._detalhes_props["MODO_RAID"]
gump:Fade (instancia, 1, nil, "barras")
if (instancia.rolagem) then
instancia:EsconderScrollBar (true) --> hida a scrollbar
end
_detalhes:ResetaGump (instancia)
instancia:DefaultIcons (true, false, true, false)
_detalhes.raid = instancia.meu_id
instancia:AtualizaGumpPrincipal (true)
if (not _detalhes.RaidTables.Plugins [1]) then
_detalhes:WaitForSoloPlugin (instancia)
else
if (not _detalhes.RaidTables.Plugins [_detalhes.RaidTables.Mode]) then
_detalhes.RaidTables.Mode = 1
end
_detalhes.RaidTables:switch (_, _detalhes.RaidTables.Mode)
end
else
_detalhes.RaidTables:switch()
_detalhes.raid = nil
if (_G.DetailsWaitForPluginFrame:IsShown()) then
_detalhes:CancelWaitForPlugin()
end
gump:Fade (instancia, 1, nil, "barras")
gump:Fade (instancia.scroll, 0)
if (instancia.need_rolagem) then
instancia:MostrarScrollBar (true)
else
--> precisa verificar se ele precisa a rolagem certo?
instancia:ReajustaGump()
end
instancia:DefaultIcons (true, true, true, true)
--> calcula se existem barras, etc...
if (not instancia.barrasInfo.cabem) then --> as barras não forma iniciadas ainda
instancia.barrasInfo.cabem = _math_floor (instancia.baseframe.BoxBarrasAltura / instancia.barrasInfo.alturaReal)
if (instancia.barrasInfo.criadas < instancia.barrasInfo.cabem) then
for i = #instancia.barras+1, instancia.barrasInfo.cabem do
local nova_barra = gump:CriaNovaBarra (instancia, i, 30) --> cria nova barra
nova_barra.texto_esquerdo:SetText (Loc ["STRING_NEWROW"])
nova_barra.statusbar:SetValue (100)
instancia.barras [i] = nova_barra
end
instancia.barrasInfo.criadas = #instancia.barras
end
end
end
end
function _detalhes:InstanciaCheckForDisabledRaid (instancia)
if (not instancia) then
instancia = self
end
if (instancia.modo == modo_raid) then
if (instancia.iniciada) then
_detalhes:AlteraModo (instancia, _detalhes._detalhes_props["MODO_GROUP"])
instancia:RaidMode (false, instancia)
_detalhes:ResetaGump (instancia)
else
instancia.modo = _detalhes._detalhes_props["MODO_GROUP"]
instancia.last_modo = _detalhes._detalhes_props["MODO_GROUP"]
end
end
end
function _detalhes.RaidTables:switch (_, _switchTo)
--> just hide all
if (not _switchTo) then
if (#_detalhes.RaidTables.Plugins > 0) then --> have at least one plugin
_detalhes.RaidTables.Plugins [_detalhes.RaidTables.Mode].Frame:Hide()
end
return
end
--> jump to the next
if (_switchTo == -1) then
_switchTo = _detalhes.RaidTables.Mode + 1
if (_switchTo > #_detalhes.RaidTables.Plugins) then
_switchTo = 1
end
end
local ThisFrame = _detalhes.RaidTables.Plugins [_detalhes.RaidTables.Mode]
if (not ThisFrame) then
--> frame not found, try in few second again
_detalhes.RaidTables.Mode = _switchTo
_detalhes:WaitForSoloPlugin (_detalhes:GetRaidMode())
return
end
--> hide current frame
_detalhes.RaidTables.Plugins [_detalhes.RaidTables.Mode].Frame:Hide()
--> switch mode
_detalhes.RaidTables.Mode = _switchTo
--> show and setpoint new frame
_detalhes.RaidTables.Plugins [_detalhes.RaidTables.Mode].Frame:Show()
_detalhes.RaidTables.Plugins [_detalhes.RaidTables.Mode].Frame:SetPoint ("TOPLEFT",_detalhes.RaidTables.instancia.bgframe)
_detalhes.RaidTables.instancia:ChangeIcon (_detalhes.RaidTables.Menu [_detalhes.RaidTables.Mode] [2])
end
+286
View File
@@ -0,0 +1,286 @@
--File Revision: 1
--Last Modification: 27/07/2013
-- Change Log:
-- 27/07/2013: Finished alpha version.
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
local _detalhes = _G._detalhes
local Loc = LibStub ("AceLocale-3.0"):GetLocale ( "Details" )
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> local pointers
local _pairs = pairs --lua locals
local _math_floor = math.floor --lua locals
local _UnitAura = UnitAura
local gump = _detalhes.gump --details local
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> constants
local modo_alone = _detalhes._detalhes_props["MODO_ALONE"]
local modo_grupo = _detalhes._detalhes_props["MODO_GROUP"]
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> internal functions
--> When a combat start
function _detalhes:UpdateSolo()
local SoloInstance = _detalhes.tabela_instancias[_detalhes.solo]
_detalhes.SoloTables.CombatIDLast = _detalhes.SoloTables.CombatID
_detalhes.SoloTables.CombatID = _detalhes:NumeroCombate()
_detalhes.SoloTables.Attribute = SoloInstance.atributo
end
--> details can call a refresh for an plugin window
function _detalhes:RefreshSolo()
if (_detalhes.SoloTables.Plugins [_detalhes.SoloTables.Mode].Refresh) then
_detalhes.SoloTables.Plugins [_detalhes.SoloTables.Mode].Refresh (_, SoloInstance)
end
end
--> enable and disable Solo Mode for an Instance
function _detalhes:SoloMode (show)
if (show) then
--> salvar a janela normal
if (self.mostrando ~= "solo") then --> caso o addon tenha ligado ja no painel solo, não precisa rodar isso aqui
self:SaveMainWindowPosition()
if (self.rolagem) then
self:EsconderScrollBar() --> hida a scrollbar
end
self.need_rolagem = false
self.baseframe:EnableMouseWheel (false)
gump:Fade (self, 1, nil, "barras") --> escondendo a janela da instância [instância [force hide [velocidade [hidar o que]]]]
self.mostrando = "solo"
end
self:DefaultIcons (true, false, true, false)
_detalhes.SoloTables.instancia = self
--> default plugin
if (not _detalhes.SoloTables.built) then
gump:PrepareSoloMode (self)
end
self.modo = _detalhes._detalhes_props["MODO_ALONE"]
_detalhes.solo = self.meu_id
--self:AtualizaSliderSolo (0)
if (not self.posicao.solo.w) then --> primeira vez que o solo mode é executado nessa instância
self.baseframe:SetWidth (300)
self.baseframe:SetHeight (300)
self:SaveMainWindowPosition()
else
self:RestoreMainWindowPosition()
end
if (not _detalhes.SoloTables.Plugins [1]) then
_detalhes:WaitForSoloPlugin (self)
else
if (not _detalhes.SoloTables.Plugins [_detalhes.SoloTables.Mode]) then
_detalhes.SoloTables.Mode = 1
end
_detalhes.SoloTables:switch (_, _detalhes.SoloTables.Mode)
end
else
if (_detalhes.PluginCount.SOLO > 0) then
local solo_frame = _detalhes.SoloTables.Plugins [_detalhes.SoloTables.Mode].Frame
if (solo_frame) then
_detalhes.SoloTables:switch()
end
end
_detalhes.solo = nil --> destranca a janela solo para ser usada em outras instâncias
self.mostrando = "normal"
self:RestoreMainWindowPosition()
self:DefaultIcons (true, true, true, true)
if (_G.DetailsWaitForPluginFrame:IsShown()) then
_detalhes:CancelWaitForPlugin()
end
gump:Fade (self, 1, nil, "barras")
gump:Fade (self.scroll, 0)
if (self.need_rolagem) then
self:MostrarScrollBar (true)
else
--> precisa verificar se ele precisa a rolagem certo?
self:ReajustaGump()
end
--> calcula se existem barras, etc...
if (not self.barrasInfo.cabem) then --> as barras não forma iniciadas ainda
self.barrasInfo.cabem = _math_floor (self.baseframe.BoxBarrasAltura / self.barrasInfo.alturaReal)
if (self.barrasInfo.criadas < self.barrasInfo.cabem) then
for i = #self.barras+1, self.barrasInfo.cabem do
local nova_barra = gump:CriaNovaBarra (self, i, 30) --> cria nova barra
nova_barra.texto_esquerdo:SetText (Loc ["STRING_NEWROW"])
nova_barra.statusbar:SetValue (100)
self.barras [i] = nova_barra
end
self.barrasInfo.criadas = #self.barras
end
end
end
end
--> Build Solo Mode Tables and Functions
function gump:PrepareSoloMode (instancia)
_detalhes.SoloTables.built = true
_detalhes.SoloTables.SpellCastTable = {} --> not used
_detalhes.SoloTables.TimeTable = {} --> not used
_detalhes.SoloTables.Mode = _detalhes.SoloTables.Mode or 1 --> solo mode
function _detalhes.SoloTables:GetActiveIndex()
return _detalhes.SoloTables.Mode
end
function _detalhes.SoloTables:switch (_, _switchTo)
--> just hide all
if (not _switchTo) then
if (#_detalhes.SoloTables.Plugins > 0) then --> have at least one plugin
_detalhes.SoloTables.Plugins [_detalhes.SoloTables.Mode].Frame:Hide()
end
_detalhes.SoloTables.Plugins [_detalhes.SoloTables.Mode].Frame:Hide()
return
end
--> jump to the next
if (_switchTo == -1) then
_switchTo = _detalhes.SoloTables.Mode + 1
if (_switchTo > #_detalhes.SoloTables.Plugins) then
_switchTo = 1
end
end
local ThisFrame = _detalhes.SoloTables.Plugins [_detalhes.SoloTables.Mode]
if (not ThisFrame) then
--> frame not found, try in few second again
_detalhes.SoloTables.Mode = _switchTo
_detalhes:WaitForSoloPlugin (instancia)
return
end
--> hide current frame
_detalhes.SoloTables.Plugins [_detalhes.SoloTables.Mode].Frame:Hide()
--> switch mode
_detalhes.SoloTables.Mode = _switchTo
--> show and setpoint new frame
_detalhes.SoloTables.Plugins [_detalhes.SoloTables.Mode].Frame:Show()
_detalhes.SoloTables.Plugins [_detalhes.SoloTables.Mode].Frame:SetPoint ("TOPLEFT",_detalhes.SoloTables.instancia.bgframe)
_detalhes.SoloTables.instancia:ChangeIcon (_detalhes.SoloTables.Menu [_detalhes.SoloTables.Mode] [2])
end
return true
end
function _detalhes:SoloCastTime (spell, start, tempo)
if (start) then
_detalhes.CastStart = tempo
else
local tempoGasto = _detalhes.CastStart - tempo
_detalhes.CastStart = nil
end
end
function _detalhes:CloseSoloDebuffs()
local SoloDebuffUptime = _detalhes.tabela_vigente.SoloDebuffUptime
if (not SoloDebuffUptime) then
return
end
for SpellId, DebuffTable in _pairs (SoloDebuffUptime) do
if (DebuffTable.start) then
DebuffTable.duration = DebuffTable.duration + (_detalhes._tempo - DebuffTable.start) --> time do parser será igual ao time()?
DebuffTable.start = nil
end
DebuffTable.Active = false
end
end
--> Buffs terá em todos os Solo Modes
function _detalhes.SoloTables:CatchBuffs()
--> reset bufftables
_detalhes.SoloTables.SoloBuffUptime = _detalhes.SoloTables.SoloBuffUptime or {}
for spellname, BuffTable in _pairs (_detalhes.SoloTables.SoloBuffUptime) do
--local BuffEntryTable = _detalhes.SoloTables.BuffTextEntry [BuffTable.tableIndex]
if (BuffTable.Active) then
BuffTable.start = _detalhes._tempo
BuffTable.castedAmt = 1
BuffTable.appliedAt = {}
--BuffEntryTable.backgroundFrame:Active()
else
BuffTable.start = nil
BuffTable.castedAmt = 0
BuffTable.appliedAt = {}
--BuffEntryTable.backgroundFrame:Desactive()
end
BuffTable.duration = 0
BuffTable.refreshAmt = 0
BuffTable.droppedAmt = 0
end
--> catch buffs untracked yet
for buffIndex = 1, 41 do
local name = _UnitAura ("player", buffIndex)
if (name) then
for index, BuffName in _pairs (_detalhes.SoloTables.BuffsTableNameCache) do
if (BuffName == name) then
local BuffObject = _detalhes.SoloTables.SoloBuffUptime [name]
if (not BuffObject) then
_detalhes.SoloTables.SoloBuffUptime [name] = {name = name, duration = 0, start = nil, castedAmt = 1, refreshAmt = 0, droppedAmt = 0, Active = true, tableIndex = index, appliedAt = {}}
end
end
end
end
end
end
function _detalhes:InstanciaCheckForDisabledSolo (instancia)
if (not instancia) then
instancia = self
end
if (instancia.modo == modo_alone) then
--print ("arrumando a instancia "..instancia.meu_id)
if (instancia.iniciada) then
_detalhes:AlteraModo (instancia, modo_grupo)
instancia:SoloMode (false)
_detalhes:ResetaGump (instancia)
else
instancia.modo = modo_grupo
instancia.last_modo = modo_grupo
end
end
end
function _detalhes:AtualizaSoloMode_AfertReset (instancia)
if (_detalhes.SoloTables.CombatIDLast) then
_detalhes.SoloTables.CombatIDLast = nil
end
if (_detalhes.SoloTables.CombatID) then
_detalhes.SoloTables.CombatID = 0
end
end
+965
View File
@@ -0,0 +1,965 @@
--File Revision: 1
--Last Modification: 27/07/2013
-- Change Log:
-- 27/07/2013: Finished alpha version.
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
local _detalhes = _G._detalhes
local Loc = LibStub ("AceLocale-3.0"):GetLocale ( "Details" )
local SharedMedia = LibStub:GetLibrary ("LibSharedMedia-3.0")
local DEFAULT_CHILD_WIDTH = 60
local DEFAULT_CHILD_HEIGHT = 16
local DEFAULT_CHILD_FONTFACE = "Friz Quadrata TT"
local DEFAULT_CHILD_FONTCOLOR = {1, 0.7333333333333333, 0, 1}
local DEFAULT_CHILD_FONTSIZE = 10
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> local pointers
local _math_floor = math.floor --> api local
local _ipairs = ipairs --> api local
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> status bar core functions
--[[ This file contains Api and Internal functions, plus 4 built-in plugins
You can use this four plugins to learn how they works--]]
--> create a plugin child for an instance
function _detalhes.StatusBar:CreateStatusBarChildForInstance (instance, pluginName)
local PluginObject = _detalhes.StatusBar.NameTable [pluginName]
if (PluginObject) then
local new_child = PluginObject:CreateChildObject (instance)
if (new_child) then
instance.StatusBar [#instance.StatusBar+1] = new_child
new_child.enabled = false
return new_child
end
end
return nil
end
function _detalhes.StatusBar:AlignPluginText (child, default)
local side = child.options.textAlign
if (child.options.textAlign == 0) then
side = default
end
child.text:ClearAllPoints()
if (side == 1) then
child.text:SetPoint ("left", child.frame, "left", child.options.textXMod, child.options.textYMod)
elseif (side == 2) then
child.text:SetPoint ("center", child.frame, "center", child.options.textXMod, child.options.textYMod)
elseif (side == 3) then
child.text:SetPoint ("right", child.frame, "right", child.options.textXMod, child.options.textYMod)
end
end
--> functions to set the three statusbar places: left, center and right
function _detalhes.StatusBar:SetCenterPlugin (instance, childObject)
childObject.frame:Show()
childObject.frame:SetPoint ("center", instance.baseframe.rodape.StatusBarCenterAnchor, "center")
_detalhes.StatusBar:AlignPluginText (childObject, 2)
instance.StatusBar.center = childObject
childObject.anchor = "center"
childObject.enabled = true
if (childObject.OnEnable) then
childObject:OnEnable()
end
return true
end
function _detalhes.StatusBar:SetLeftPlugin (instance, childObject)
childObject.frame:Show()
childObject.frame:SetPoint ("left", instance.baseframe.rodape.StatusBarLeftAnchor, "left")
_detalhes.StatusBar:AlignPluginText (childObject, 1)
instance.StatusBar.left = childObject
childObject.anchor = "left"
childObject.enabled = true
if (childObject.OnEnable) then
childObject:OnEnable()
end
return true
end
function _detalhes.StatusBar:SetRightPlugin (instance, childObject)
childObject.frame:Show()
childObject.frame:SetPoint ("right", instance.baseframe.rodape.direita, "right", -20, 10)
_detalhes.StatusBar:AlignPluginText (childObject, 3)
instance.StatusBar.right = childObject
childObject.anchor = "right"
childObject.enabled = true
if (childObject.OnEnable) then
childObject:OnEnable()
end
return true
end
--> disable all plugin childs attached to an specified instance and reactive the childs taking the instance statusbar anchors
function _detalhes.StatusBar:ReloadAnchors (instance)
for _, child in _ipairs (instance.StatusBar) do
child.frame:ClearAllPoints()
child.frame:Hide()
child.anchor = nil
child.enabled = false
if (child.OnDisable) then
child:OnDisable()
end
end
--> enable only needed plugins
if (instance.StatusBar.right) then
_detalhes.StatusBar:SetRightPlugin (instance, instance.StatusBar.right)
end
if (instance.StatusBar.center) then
_detalhes.StatusBar:SetCenterPlugin (instance, instance.StatusBar.center)
end
if (instance.StatusBar.left) then
_detalhes.StatusBar:SetLeftPlugin (instance, instance.StatusBar.left)
end
end
--> select a new plugin in for an instance anchor
local ChoosePlugin = function (_, _, index, current_child, anchor)
local pluginMestre = _detalhes.StatusBar.Plugins [index]
local instance = current_child.instance -- instance que estamos usando agora
local chosenChild = nil
for _, child_created in _ipairs (instance.StatusBar) do
if (child_created.mainPlugin == pluginMestre) then
chosenChild = child_created
break
end
end
if (not chosenChild) then
chosenChild = _detalhes.StatusBar:CreateStatusBarChildForInstance (current_child.instance, pluginMestre.real_name)
end
instance.StatusBar [anchor] = chosenChild
if (chosenChild.anchor) then
instance.StatusBar [chosenChild.anchor] = current_child
end
_detalhes.StatusBar:ReloadAnchors (instance)
_detalhes.popup:ShowMe (false)
end
--> on enter
local onEnterCooltipTexts = {
{text = "|TInterface\\TUTORIALFRAME\\UI-TUTORIAL-FRAME:14:14:0:1:512:512:8:70:224:306|t " .. Loc ["STRING_PLUGIN_TOOLTIP_LEFTBUTTON"]},
{text = "|TInterface\\TUTORIALFRAME\\UI-TUTORIAL-FRAME:14:14:0:1:512:512:8:70:328:409|t " .. Loc ["STRING_PLUGIN_TOOLTIP_RIGHTBUTTON"]}}
local OnEnter = function (frame)
--|TTexturePath: size X: size Y: point offset Y X : texture size : coordx1 L : coordx2 R : coordy1 T : coordy2 B |t
-- left click: 0.0019531:0.1484375:0.4257813:0.6210938 right click: 0.0019531:0.1484375:0.6269531:0.8222656
local passou = 0
frame:SetScript ("OnUpdate", function (self, elapsed)
passou = passou + elapsed
if (passou > 0.5) then
if (not _detalhes.popup.mouseOver and not _detalhes.popup.buttonOver and not _detalhes.popup.active) then
GameCooltip:Reset()
GameCooltip:AddFromTable (onEnterCooltipTexts)
GameCooltip:SetOption ("TextSize", 9.5)
GameCooltip:ShowCooltip (frame, "tooltip")
end
self:SetScript ("OnUpdate", nil)
_detalhes.popup.active = true
end
end)
return true
end
--> on leave
local OnLeave = function (frame)
if (_detalhes.popup.active) then
local passou = 0
frame:SetScript ("OnUpdate", function (self, elapsed)
passou = passou+elapsed
if (passou > 0.3) then
if (not _detalhes.popup.mouseOver and not _detalhes.popup.buttonOver and _detalhes.popup.Host == frame) then
_detalhes.popup:ShowMe (false)
end
_detalhes.popup.active = false
self:SetScript ("OnUpdate", nil)
end
end)
else
_detalhes.popup.active = false
frame:SetScript ("OnUpdate", nil)
end
return true
end
local OnMouseUp = function (frame, mouse)
if (mouse == "LeftButton") then
if (not frame.child.Setup) then
print (Loc ["STRING_STATUSBAR_NOOPTIONS"])
return
end
frame.child:Setup()
else
GameCooltip:Reset()
for index, _name_and_icon in _ipairs (_detalhes.StatusBar.Menu) do
GameCooltip:AddMenu (1, ChoosePlugin, index, frame.child, frame.child.anchor, _name_and_icon [1], _name_and_icon [2], true)
end
GameCooltip:SetOption ("NoLastSelectedBar", true)
GameCooltip:SetOption ("HeightAnchorMod", -12)
GameCooltip:ShowCooltip (frame, "menu")
end
return true
end
--> build-in function for create a frame for an plugin child
function _detalhes.StatusBar:CreateChildFrame (instance, name, w, h)
local frame = _detalhes.gump:NewPanel (instance.baseframe.cabecalho.fechar, nil, name..instance:GetInstanceId(), nil, w or DEFAULT_CHILD_WIDTH, h or DEFAULT_CHILD_HEIGHT, false)
--create widgets
local text = _detalhes.gump:NewLabel (frame, _, "$parentText", "text", "0")
text:SetPoint ("right", frame, "right", 0, 0)
text:SetJustifyH ("right")
_detalhes:SetFontSize (text, 9.8)
frame:SetHook ("OnEnter", OnEnter)
frame:SetHook ("OnLeave", OnLeave)
frame:SetHook ("OnMouseUp", OnMouseUp)
return frame
end
--> built-in function for create an table for the plugin child
function _detalhes.StatusBar:CreateChildTable (instance, mainObject, frame)
local _table = {}
--> treat as a class
setmetatable (_table, mainObject)
--> default members
_table.instance = instance
_table.frame = frame
_table.text = frame.text
_table.mainPlugin = mainObject
--> options table
_table.options = instance.StatusBar.options [mainObject.real_name]
if (not _table.options) then
_table.options = {
textStyle = 2,
textColor = {unpack (DEFAULT_CHILD_FONTCOLOR)},
textSize = DEFAULT_CHILD_FONTSIZE,
textAlign = 0,
textXMod = 0,
textYMod = 0,
textFace = DEFAULT_CHILD_FONTFACE}
instance.StatusBar.options [mainObject.real_name] = _table.options
end
_detalhes.StatusBar:ApplyOptions (_table, "textcolor")
_detalhes.StatusBar:ApplyOptions (_table, "textsize")
_detalhes.StatusBar:ApplyOptions (_table, "textface")
_detalhes.StatusBar:ReloadAnchors (instance)
--> table reference on frame widget
frame.frame.child = _table
--> adds this new child to parent child container
mainObject.childs [#mainObject.childs+1] = _table
return _table
end
function _detalhes.StatusBar:ApplyOptions (child, option, value)
option = string.lower (option)
if (option == "textxmod") then
if (value) then
child.options.textXMod = value
end
_detalhes.StatusBar:ReloadAnchors (child.instance)
elseif (option == "textymod") then
if (value) then
child.options.textYMod = value
end
_detalhes.StatusBar:ReloadAnchors (child.instance)
elseif (option == "textcolor") then
if (value) then
child.options.textColor = value
end
child.text:SetTextColor (unpack (child.options.textColor))
elseif (option == "textsize") then
if (value) then
child.options.textSize = value
end
child:SetFontSize (child.text, child.options.textSize)
elseif (option == "textface") then
if (value) then
child.options.textFace = value
end
child:SetFontFace (child.text, SharedMedia:Fetch ("font", child.options.textFace))
else
if (child [option] and type (child [option]) == "function") then
child [option] (_, child, value)
end
end
end
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> BUILT-IN DPS PLUGIN
do
--> Create the plugin Object [1] = frame name on _G [2] options [3] plugin type
local PDps = _detalhes:NewPluginObject ("Details_StatusBarDps", DETAILSPLUGIN_ALWAYSENABLED, "STATUSBAR")
--[[ Note: Declare all functions using : not . if you use . make sure to ignore first parameter and move all parameters 1 position to right ]]
-- handle event "COMBAT_PLAYER_ENTER"
function PDps:PlayerEnterCombat()
for index, child in _ipairs (PDps.childs) do
if (child.enabled and child.instance:GetSegment() == 0) then
child.tick = _detalhes:ScheduleRepeatingTimer ("PluginDpsUpdate", 1, child)
end
end
end
-- handle event "COMBAT_PLAYER_LEAVE"
function PDps:PlayerLeaveCombat()
for index, child in _ipairs (PDps.childs) do
if (child.tick) then
_detalhes:CancelTimer (child.tick)
child.tick = nil
end
end
end
-- handle event "DETAILS_INSTANCE_CHANGESEGMENT"
function PDps:ChangeSegment (instance, segment)
for index, child in _ipairs (PDps.childs) do
if (child.enabled and child.instance == instance) then
_detalhes:PluginDpsUpdate (child)
end
end
end
--handle event "DETAILS_DATA_RESET"
function PDps:DataReset()
for index, child in _ipairs (PDps.childs) do
if (child.enabled) then
child.text:SetText ("0")
end
end
end
function PDps:Refresh (child)
_detalhes:PluginDpsUpdate (child)
end
--still a little buggy, working on
function _detalhes:PluginDpsUpdate (child)
--> showing is the combat table which is current shown on instance
if (child.instance.showing) then
--GetCombatTime() return the time length of combat
local combatTime = child.instance.showing:GetCombatTime()
if (combatTime == 0) then
return child.text:SetText ("0")
end
--GetTotal (attribute, sub attribute, onlyGroup) return the total of requested attribute
local total = child.instance.showing:GetTotal (child.instance.atributo, child.instance.sub_atributo, true)
local dps = _math_floor (total / combatTime)
local textStyle = child.options.textStyle
if (textStyle == 1) then
child.text:SetText (_detalhes:ToK (dps))
elseif (textStyle == 2) then
child.text:SetText (_detalhes:comma_value (dps))
else
child.text:SetText (dps)
end
end
end
--> Create Plugin Frames
function PDps:CreateChildObject (instance)
--> create main frame and widgets
--> a statusbar frame is made of a panel with a member called 'text' which is a label
local myframe = _detalhes.StatusBar:CreateChildFrame (instance, "DetailsStatusBarDps", DEFAULT_CHILD_WIDTH, DEFAULT_CHILD_HEIGHT)
--> create the table for the child
--> a child table are the table which will hold parameters, default members:
-- ["instance"] = instance where this child are,
-- ["frame"] = myframe,
-- ["text"] = myframe.text,
-- ["mainPlugin"] = parent plugin
local new_child = _detalhes.StatusBar:CreateChildTable (instance, PDps, myframe)
return new_child
end
--> Handle events (must have, we'll use direct call to functions)
function PDps:OnDetailsEvent (event)
return
end
--> standard on enable and disable functions, this is for hook model. If isn't declared, details will auto modify member .enabled state
--function PDps:OnEnable()
-- self.enabled = true
--end
--function PDps:OnDisable()
-- self.enabled = false
--end
--> setup function runs when player click with left mouse over plugin frame
--> this is internal, but member Setup can be overwrite
--> for exclude any options panel, set Setup to nil
--function PDps:Setup()
-- _detalhes.StatusBar:OpenOptionsForChild (self)
--end
--> Install
-- _detalhes:InstallPlugin ( Plugin Type | Plugin Display Name | Plugin Icon | Plugin Object | Plugin Real Name )
local install = _detalhes:InstallPlugin ("STATUSBAR", Loc ["STRING_PLUGIN_PDPSNAME"], "Interface\\Icons\\Achievement_brewery_3", PDps, "DETAILS_STATUSBAR_PLUGIN_PDPS")
if (type (install) == "table" and install.error) then
print (install.errortext)
return
end
--> Register needed events
-- here we are redirecting the event to an specified function, otherwise events need to be handle inside "PDps:OnDetailsEvent (event)"
_detalhes:RegisterEvent (PDps, "DETAILS_INSTANCE_CHANGESEGMENT", PDps.ChangeSegment)
_detalhes:RegisterEvent (PDps, "COMBAT_PLAYER_ENTER", PDps.PlayerEnterCombat)
_detalhes:RegisterEvent (PDps, "COMBAT_PLAYER_LEAVE", PDps.PlayerLeaveCombat)
_detalhes:RegisterEvent (PDps, "DETAILS_DATA_RESET", PDps.DataReset)
end
---------> BUILT-IN SEGMENT PLUGIN ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
do
--> Create the plugin Object
local PSegment = _detalhes:NewPluginObject ("Details_Segmenter", DETAILSPLUGIN_ALWAYSENABLED, "STATUSBAR")
--> Handle events (must have)
function PSegment:OnDetailsEvent (event)
return
end
function PSegment:Change ()
for index, child in _ipairs (PSegment.childs) do
if (child.enabled and child.instance:IsEnabled()) then
if (child.instance.segmento == -1) then --> overall
child.text:SetText (Loc ["STRING_OVERALL"])
elseif (child.instance.segmento == 0) then --> combate atual
child.text:SetText (Loc ["STRING_CURRENT"])
else --> alguma tabela do histórico
child.text:SetText (Loc ["STRING_FIGHTNUMBER"]..child.instance.segmento)
end
end
end
end
--> Create Plugin Frames (must have)
function PSegment:CreateChildObject (instance)
local myframe = _detalhes.StatusBar:CreateChildFrame (instance, "DetailsPSegmentInstance" .. instance:GetInstanceId(), DEFAULT_CHILD_WIDTH, DEFAULT_CHILD_HEIGHT)
local new_child = _detalhes.StatusBar:CreateChildTable (instance, PSegment, myframe)
return new_child
end
--> Install
local install = _detalhes:InstallPlugin ("STATUSBAR", Loc ["STRING_PLUGIN_PSEGMENTNAME"], "Interface\\Icons\\inv_misc_enchantedscroll", PSegment, "DETAILS_STATUSBAR_PLUGIN_PSEGMENT")
if (type (install) == "table" and install.error) then
print (install.errortext)
return
end
--> Register needed events
_detalhes:RegisterEvent (PSegment, "DETAILS_INSTANCE_CHANGESEGMENT", PSegment.Change)
end
---------> BUILT-IN ATTRIBUTE PLUGIN ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
do
--> Create the plugin Object
local PAttribute = _detalhes:NewPluginObject ("Details_Attribute", DETAILSPLUGIN_ALWAYSENABLED, "STATUSBAR")
--> Handle events (must have)
function PAttribute:OnDetailsEvent (event)
return
end
function PAttribute:Change (instance, attribute, subAttribute)
if (not instance) then
instance, attribute, subAttribute = self.instance, self.instance.atributo, self.instance.sub_atributo
end
for index, child in _ipairs (PAttribute.childs) do
if (child.instance == instance and child.enabled and child.instance:IsEnabled()) then
local sName = _detalhes:GetSubAttributeName (attribute, subAttribute)
child.text:SetText (sName)
end
end
end
function PAttribute:OnEnable()
self:Change()
end
--> Create Plugin Frames (must have)
function PAttribute:CreateChildObject (instance)
local myframe = _detalhes.StatusBar:CreateChildFrame (instance, "DetailsPAttributeInstance" .. instance:GetInstanceId(), DEFAULT_CHILD_WIDTH, DEFAULT_CHILD_HEIGHT)
local new_child = _detalhes.StatusBar:CreateChildTable (instance, PAttribute, myframe)
return new_child
end
--> Install
local install = _detalhes:InstallPlugin ("STATUSBAR", Loc ["STRING_PLUGIN_PATTRIBUTENAME"], "Interface\\Icons\\inv_misc_emberclothbolt", PAttribute, "DETAILS_STATUSBAR_PLUGIN_PATTRIBUTE")
if (type (install) == "table" and install.error) then
print (install.errortext)
return
end
--> Register needed events
_detalhes:RegisterEvent (PAttribute, "DETAILS_INSTANCE_CHANGEATTRIBUTE", PAttribute.Change)
end
---------> BUILT-IN CLOCK PLUGIN ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
do
--> Create the plugin Object
local Clock = _detalhes:NewPluginObject ("Details_Clock", DETAILSPLUGIN_ALWAYSENABLED, "STATUSBAR")
--> Handle events --must have this function
function Clock:OnDetailsEvent (event)
return
end
--enter combat
function Clock:PlayerEnterCombat()
Clock.tick = _detalhes:ScheduleRepeatingTimer ("ClockPluginTick", 1)
end
--leave combat
function Clock:PlayerLeaveCombat()
_detalhes:CancelTimer (Clock.tick)
end
--1 sec tick
function _detalhes:ClockPluginTick()
for index, child in _ipairs (Clock.childs) do
local instance = child.instance
if (child.enabled and instance:IsEnabled()) then
if (instance.showing) then
local timeType = child.options.timeType
if (timeType == 1) then
local combatTime = instance.showing:GetCombatTime()
local minutos, segundos = _math_floor (combatTime/60), _math_floor (combatTime%60)
child.text:SetText (minutos .. "m " .. segundos .. "s")
elseif (timeType == 2) then
local combatTime = instance.showing:GetCombatTime()
child.text:SetText (combatTime .. "s")
elseif (timeType == 3) then
local getSegment = instance.segmento
if (getSegment < 1) then
getSegment = 1
elseif (getSegment > _detalhes.segments_amount) then
getSegment = _detalhes.segments_amount
else
getSegment = getSegment+1
end
local lastFight = _detalhes:GetCombat (getSegment)
local currentCombatTime = instance.showing:GetCombatTime()
if (lastFight) then
child.text:SetText (currentCombatTime - lastFight:GetCombatTime() .. "s")
else
child.text:SetText (currentCombatTime .. "s")
end
end
end
end
end
end
--on reset
function Clock:DataReset()
for index, child in _ipairs (Clock.childs) do
if (child.enabled and child.instance:IsEnabled()) then
child.text:SetText ("0m 0s")
end
end
end
--> this is a fixed member, put all your widgets for custom options inside this function
--> if ExtraOptions isn't preset, secondary options box will be hided and only default options will be show
function Clock:ExtraOptions()
--> all widgets need to be placed on a table
local widgets = {}
--> reference of extra window for custom options
local window = _G.DetailsStatusBarOptions2.MyObject
--> build all your widgets -----------------------------------------------------------------------------------------------------------------------------
_detalhes.gump:NewLabel (window, _, "$parentClockTypeLabel", "ClockTypeLabel", Loc ["STRING_PLUGIN_CLOCKTYPE"])
window.ClockTypeLabel:SetPoint (10, -15)
local onSelectClockType = function (_, child, thistype)
child.options.timeType = thistype
_detalhes:ClockPluginTick()
end
local clockTypes = {{value = 1, label = Loc ["STRING_PLUGIN_MINSEC"], onclick = onSelectClockType},
{value = 2, label = Loc ["STRING_PLUGIN_SECONLY"], onclick = onSelectClockType},
{value = 3, label = Loc ["STRING_PLUGIN_TIMEDIFF"], onclick = onSelectClockType}}
_detalhes.gump:NewDropDown (window, _, "$parentClockTypeDropdown", "ClockTypeDropdown", 200, 20, function() return clockTypes end, 1) -- func, default
window.ClockTypeDropdown:SetPoint ("left", window.ClockTypeLabel, "right", 2)
-----------------------------------------------------------------------------------------------------------------------------
--> now we insert all widgets created on widgets table
table.insert (widgets, window.ClockTypeLabel)
table.insert (widgets, window.ClockTypeDropdown)
--> after first call we replace this function with widgets table
Clock.ExtraOptions = widgets
end
--> ExtraOptionsOnOpen is called when options are opened and plugin have custom options
--> here we setup options widgets for get the values of clicked child and also for tell options window what child we are configuring
function Clock:ExtraOptionsOnOpen (child)
_G.DetailsStatusBarOptions2ClockTypeDropdown.MyObject:SetFixedParameter (child)
_G.DetailsStatusBarOptions2ClockTypeDropdown.MyObject:Select (child.options.timeType, true)
end
--> Create Plugin Frames
function Clock:CreateChildObject (instance)
local myframe = _detalhes.StatusBar:CreateChildFrame (instance, "DetailsClockInstance"..instance:GetInstanceId(), DEFAULT_CHILD_WIDTH, DEFAULT_CHILD_HEIGHT)
--> we place custom frame, widgets inside this function
local texture = myframe:CreateTexture (nil, "overlay")
texture:SetTexture ("Interface\\AddOns\\Details\\images\\clock")
texture:SetPoint ("right", myframe.text.widget, "left")
local new_child = _detalhes.StatusBar:CreateChildTable (instance, Clock, myframe)
--> default text
new_child.text:SetText ("0m 0s")
--> some changes from default options
if (new_child.options.textXMod == 0) then
new_child.options.textXMod = 6
end
--> here we are adding a new option member
new_child.options.timeType = new_child.options.timeType or 1
return new_child
end
--> Install
local install = _detalhes:InstallPlugin ("STATUSBAR", Loc ["STRING_PLUGIN_CLOCKNAME"], "Interface\\Icons\\Achievement_BG_grab_cap_flagunderXseconds", Clock, "DETAILS_STATUSBAR_PLUGIN_CLOCK")
if (type (install) == "table" and install.error) then
print (install.errortext)
return
end
--> Register needed events
_detalhes:RegisterEvent (Clock, "COMBAT_PLAYER_ENTER", Clock.PlayerEnterCombat)
_detalhes:RegisterEvent (Clock, "COMBAT_PLAYER_LEAVE", Clock.PlayerLeaveCombat)
_detalhes:RegisterEvent (Clock, "DETAILS_INSTANCE_CHANGESEGMENT", _detalhes.ClockPluginTick)
_detalhes:RegisterEvent (Clock, "DETAILS_DATA_SEGMENTREMOVED", _detalhes.ClockPluginTick)
_detalhes:RegisterEvent (Clock, "DETAILS_DATA_RESET", Clock.DataReset)
end
---------> BUILT-IN THREAT PLUGIN ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
do
local _UnitDetailedThreatSituation = UnitDetailedThreatSituation --> wow api
local _cstr = string.format --> lua api
local _math_abs = math.abs --> lua api
--> Create the plugin Object
local Threat = _detalhes:NewPluginObject ("Details_TargetThreat", DETAILSPLUGIN_ALWAYSENABLED, "STATUSBAR")
--> Handle events
function Threat:OnDetailsEvent (event)
return
end
Threat.isTank = nil
function Threat:PlayerEnterCombat()
local role = UnitGroupRolesAssigned ("player")
if (role == "TANK") then
Threat.isTank = true
else
Threat.isTank = nil
end
Threat.tick = _detalhes:ScheduleRepeatingTimer ("ThreatPluginTick", 1)
end
function Threat:PlayerLeaveCombat()
_detalhes:CancelTimer (Threat.tick)
end
function _detalhes:ThreatPluginTick()
for index, child in _ipairs (Threat.childs) do
local instance = child.instance
if (child.enabled and instance:IsEnabled()) then
-- atualiza a threat
local isTanking, status, threatpct, rawthreatpct, threatvalue = _UnitDetailedThreatSituation ("player", "target")
if (threatpct) then
child.text:SetText (_math_floor (threatpct).."%")
if (Threat.isTank) then
child.text:SetTextColor (_math_abs (threatpct-100)*0.01, threatpct*0.01, 0, 1)
else
child.text:SetTextColor (threatpct*0.01, _math_abs (threatpct-100)*0.01, 0, 1)
end
else
child.text:SetText ("0%")
child.text:SetTextColor (1, 1, 1, 1)
end
end
end
end
--> Create Plugin Frames
function Threat:CreateChildObject (instance)
local myframe = _detalhes.StatusBar:CreateChildFrame (instance, "DetailsThreatInstance"..instance:GetInstanceId(), DEFAULT_CHILD_WIDTH, DEFAULT_CHILD_HEIGHT)
local new_child = _detalhes.StatusBar:CreateChildTable (instance, Threat, myframe)
myframe.widget:RegisterEvent ("PLAYER_TARGET_CHANGED")
myframe.widget:SetScript ("OnEvent", function()
_detalhes:ThreatPluginTick()
end)
return new_child
end
--> Install
local install = _detalhes:InstallPlugin ("STATUSBAR", Loc ["STRING_PLUGIN_THREATNAME"], "Interface\\Icons\\Ability_Hunter_ResistanceIsFutile", Threat, "DETAILS_STATUSBAR_PLUGIN_THREAT")
if (type (install) == "table" and install.error) then
print (install.errortext)
return
end
--> Register needed events
_detalhes:RegisterEvent (Threat, "COMBAT_PLAYER_ENTER", Threat.PlayerEnterCombat)
_detalhes:RegisterEvent (Threat, "COMBAT_PLAYER_LEAVE", Threat.PlayerLeaveCombat)
end
---------> default options panel ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
local window = _detalhes.gump:NewPanel (UIParent, nil, "DetailsStatusBarOptions", nil, 300, 160)
tinsert (UISpecialFrames, "DetailsStatusBarOptions")
window:SetPoint ("center", UIParent, "center")
window.locked = false
window.close_with_right = true
window.child = nil
window.instance = nil
local extraWindow = _detalhes.gump:NewPanel (window, nil, "DetailsStatusBarOptions2", "extra", 300, 160)
extraWindow:SetPoint ("left", window, "right")
extraWindow.close_with_right = true
extraWindow.locked = false
extraWindow:SetHook ("OnHide", function()
window:Hide()
end)
--> text style
_detalhes.gump:NewLabel (window, _, "$parentTextStyleLabel", "textstyle", Loc ["STRING_PLUGINOPTIONS_TEXTSTYLE"])
window.textstyle:SetPoint (10, -15)
local onSelectTextStyle = function (_, child, style)
child.options.textStyle = style
if (child.Refresh and type (child.Refresh) == "function") then
child:Refresh (child)
end
end
local textStyle = {{value = 1, label = Loc ["STRING_PLUGINOPTIONS_ABBREVIATE"] .. " (105.5K)", onclick = onSelectTextStyle},
{value = 2, label = Loc ["STRING_PLUGINOPTIONS_COMMA"] .. " (105.500)", onclick = onSelectTextStyle},
{value = 3, label = Loc ["STRING_PLUGINOPTIONS_NOFORMAT"] .. " (105500)", onclick = onSelectTextStyle}}
_detalhes.gump:NewDropDown (window, _, "$parentTextStyleDropdown", "textstyleDropdown", 200, 20, function() return textStyle end, 1) -- func, default
window.textstyleDropdown:SetPoint ("left", window.textstyle, "right", 2)
--> text color
_detalhes.gump:NewLabel (window, _, "$parentTextColorLabel", "textcolor", Loc ["STRING_PLUGINOPTIONS_TEXTCOLOR"])
window.textcolor:SetPoint (10, -35)
local selectedColor = function()
local r, g, b, a = ColorPickerFrame:GetColorRGB()
window.textcolortexture:SetTexture (r, g, b, a)
_detalhes.StatusBar:ApplyOptions (window.child, "textcolor", {r, g, b, a})
end
local canceledColor = function()
window.textcolortexture:SetTexture (unpack (ColorPickerFrame.previousValues))
_detalhes.StatusBar:ApplyOptions (window.child, "textcolor", {r, g, b, a})
end
local colorpick = function()
ColorPickerFrame:SetColorRGB (unpack (window.child.options.textColor))
ColorPickerFrame.hasOpacity = false
ColorPickerFrame.previousValues = window.child.options.textColor
ColorPickerFrame.func = selectedColor
ColorPickerFrame.cancelFunc = canceledColor
ColorPickerFrame:Show()
end
_detalhes.gump:NewImage (window, _, "$parentTextColorTexture", "textcolortexture", 200, 16)
window.textcolortexture:SetPoint ("left", window.textcolor, "right", 2)
window.textcolortexture:SetTexture (1, 1, 1)
_detalhes.gump:NewButton (window, _, "$parentTextColorButton", "textcolorbutton", 200, 20, colorpick)
window.textcolorbutton:SetPoint ("left", window.textcolor, "right", 2)
--> text size
_detalhes.gump:NewLabel (window, _, "$parentFontSizeLabel", "fonsizeLabel", Loc ["STRING_PLUGINOPTIONS_TEXTSIZE"])
window.fonsizeLabel:SetPoint (10, -55)
--
_detalhes.gump:NewSlider (window, _, "$parentSliderFontSize", "fonsizeSlider", 170, 20, 9, 15, .5, 1)
window.fonsizeSlider:SetPoint ("left", window.fonsizeLabel, "right", 2)
window.fonsizeSlider:SetThumbSize (50)
window.fonsizeSlider.useDecimals = true
window.fonsizeSlider:SetHook ("OnValueChange", function (self, child, amount)
_detalhes.StatusBar:ApplyOptions (child, "textsize", amount)
end)
--> align
_detalhes.gump:NewLabel (window, _, "$parentTextAlignLabel", "textalign", Loc ["STRING_PLUGINOPTIONS_TEXTALIGN"])
window.textalign:SetPoint (10, -95)
--
_detalhes.gump:NewSlider (window, _, "$parentSliderAlign", "alignSlider", 180, 20, 0, 3, 1)
window.alignSlider:SetPoint ("left", window.textalign, "right")
window.alignSlider:SetThumbSize (75)
window.alignSlider:SetHook ("OnValueChange", function (self, child, side)
child.options.textAlign = side
if (side == 0) then
window.alignSlider.amt:SetText (Loc ["STRING_AUTO"])
elseif (side == 1) then
window.alignSlider.amt:SetText (Loc ["STRING_LEFT"])
elseif (side == 2) then
window.alignSlider.amt:SetText (Loc ["STRING_CENTER"])
elseif (side == 3) then
window.alignSlider.amt:SetText (Loc ["STRING_RIGHT"])
end
_detalhes.StatusBar:ReloadAnchors (child.instance)
return true
end)
--> text font
local onSelectFont = function (_, child, fontName)
_detalhes.StatusBar:ApplyOptions (child, "textface", fontName)
end
local fontObjects = SharedMedia:HashTable ("font")
local fontTable = {}
for name, fontPath in pairs (fontObjects) do
fontTable[#fontTable+1] = {value = name, label = name, onclick = onSelectFont, font = fontPath}
end
local buildFontMenu = function() return fontTable end
_detalhes.gump:NewLabel (window, _, "$parentFontFaceLabel", "fontfaceLabel", Loc ["STRING_PLUGINOPTIONS_FONTFACE"])
window.fontfaceLabel:SetPoint (10, -75)
--
_detalhes.gump:NewDropDown (window, _, "$parentFontDropdown", "fontDropdown", 170, 20, buildFontMenu, nil)
window.fontDropdown:SetPoint ("left", window.fontfaceLabel, "right", 2)
window:Hide()
--> align mod X
_detalhes.gump:NewLabel (window, _, "$parentAlignXLabel", "alignXLabel", Loc ["STRING_PLUGINOPTIONS_TEXTALIGN_X"])
window.alignXLabel:SetPoint (10, -115)
--
_detalhes.gump:NewSlider (window, _, "$parentSliderAlignX", "alignXSlider", 160, 20, -20, 20, 1, 0)
window.alignXSlider:SetPoint ("left", window.alignXLabel, "right", 2)
window.alignXSlider:SetThumbSize (40)
window.alignXSlider:SetHook ("OnValueChange", function (self, child, amount)
_detalhes.StatusBar:ApplyOptions (child, "textxmod", amount)
end)
--> align modY
_detalhes.gump:NewLabel (window, _, "$parentAlignYLabel", "alignYLabel", Loc ["STRING_PLUGINOPTIONS_TEXTALIGN_Y"])
window.alignYLabel:SetPoint (10, -135)
--
_detalhes.gump:NewSlider (window, _, "$parentSliderAlignY", "alignYSlider", 160, 20, -10, 10, 1, 0)
window.alignYSlider:SetPoint ("left", window.alignYLabel, "right", 2)
window.alignYSlider:SetThumbSize (40)
window.alignYSlider:SetHook ("OnValueChange", function (self, child, amount)
_detalhes.StatusBar:ApplyOptions (child, "textymod", amount)
end)
--> open options
function _detalhes.StatusBar:OpenOptionsForChild (child)
window.child = child
window.instance = child.instance
_G.DetailsStatusBarOptionsTextStyleDropdown.MyObject:SetFixedParameter (child)
_G.DetailsStatusBarOptionsTextColorTexture:SetTexture (child.options.textColor[1], child.options.textColor[2], child.options.textColor[3], child.options.textColor[4])
_G.DetailsStatusBarOptionsSliderFontSize.MyObject:SetFixedParameter (child)
_G.DetailsStatusBarOptionsSliderFontSize.MyObject:SetValue (child.options.textSize)
_G.DetailsStatusBarOptionsSliderAlign.MyObject:SetFixedParameter (child)
_G.DetailsStatusBarOptionsSliderAlign.MyObject:SetValue (child.options.textAlign)
_G.DetailsStatusBarOptionsFontDropdown.MyObject:SetFixedParameter (child)
_G.DetailsStatusBarOptionsFontDropdown.MyObject:Select (child.options.textFace)
_G.DetailsStatusBarOptionsSliderAlignX.MyObject:SetFixedParameter (child)
_G.DetailsStatusBarOptionsSliderAlignX.MyObject:SetValue (child.options.textXMod)
_G.DetailsStatusBarOptionsSliderAlignY.MyObject:SetFixedParameter (child)
_G.DetailsStatusBarOptionsSliderAlignY.MyObject:SetValue (child.options.textYMod)
_G.DetailsStatusBarOptions:Show()
if (child.ExtraOptions) then
if (type (child.ExtraOptions) == "function") then
child.ExtraOptions()
end
extraWindow:HideWidgets()
for _, widget in pairs (child.ExtraOptions) do
widget:Show()
end
child:ExtraOptionsOnOpen (child)
extraWindow:Show()
else
extraWindow:Hide()
end
end
+194
View File
@@ -0,0 +1,194 @@
--File Revision: 1
--Last Modification: 27/07/2013
-- Change Log:
-- 27/07/2013: Finished alpha version.
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
local _detalhes = _G._detalhes
local Loc = LibStub ("AceLocale-3.0"):GetLocale ( "Details" )
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> local pointers
-- none
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> details api functions
--> create a button which will be displayed on tooltip
function _detalhes.ToolBar:NewPluginToolbarButton (func, icon, tooltip, w, h, name)
--> random name if nameless
if (not name) then
name = "DetailsToolbarButton" .. math.random (1, 100000)
end
--> create button from template
local button = CreateFrame ("button", name, _detalhes.listener, "DetailsToolbarButton")
--> sizes
if (w) then
button:SetWidth (w)
end
if (h) then
button:SetHeight (h)
end
--> tooltip and function on click
button.tooltip = tooltip
button:SetScript ("OnClick", func)
--> textures
button:SetNormalTexture (icon)
button:SetPushedTexture (icon)
button:SetDisabledTexture (icon)
button:SetHighlightTexture (icon, "ADD")
--> blizzard built-in animation
local FourCornerAnimeFrame = CreateFrame ("frame", name.."Blink", button, "IconIntroAnimTemplate")
FourCornerAnimeFrame:SetPoint ("center", button)
FourCornerAnimeFrame:SetWidth (w or 14)
FourCornerAnimeFrame:SetHeight (w or 14)
FourCornerAnimeFrame.glow:SetScript ("OnFinished", nil)
button.blink = FourCornerAnimeFrame
return button
end
--> show your plugin icon on tooltip
function _detalhes:ShowToolbarIcon (Button, Effect)
local LastIcon
--> get the lower number instance
local lower_instance = _detalhes:GetLowerInstanceNumber()
if (not lower_instance) then
return
end
local instance = _detalhes:GetInstance (lower_instance)
if (#_detalhes.ToolBar.Shown > 0) then
--> already shown
if (_detalhes:tableIN (_detalhes.ToolBar.Shown, Button)) then
return
end
LastIcon = _detalhes.ToolBar.Shown [#_detalhes.ToolBar.Shown]
else
LastIcon = instance.baseframe.cabecalho.report
end
local x = 0
if (instance.consolidate) then
LastIcon = instance.consolidateButtonTexture
x = x - 3
end
_detalhes.ToolBar.Shown [#_detalhes.ToolBar.Shown+1] = Button
Button:SetPoint ("left", LastIcon, "right", Button.x + x, Button.y)
Button:Show()
if (Effect) then
if (type (Effect) == "string") then
if (Effect == "blink") then
Button.blink.glow:Play()
elseif (Effect == "star") then
Button.StarAnim:Play()
end
elseif (Effect) then
Button.blink.glow:Play()
end
end
return true
end
--> hide your plugin icon from toolbar
function _detalhes:HideToolbarIcon (Button)
local index = _detalhes:tableIN (_detalhes.ToolBar.Shown, Button)
if (not index) then
--> current not shown
return
end
Button:Hide()
table.remove (_detalhes.ToolBar.Shown, index)
--> reorganize icons
_detalhes.ToolBar:ReorganizeIcons()
end
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> internal functions
function DetailsToolbarButtonOnEnter (button)
if (button.tooltip) then
GameCooltip:Reset()
GameCooltip:AddLine (button.tooltip)
GameCooltip:ShowCooltip (button, "tooltip")
end
end
function DetailsToolbarButtonOnLeave (button)
if (button.tooltip) then
_detalhes.popup:ShowMe (false)
end
end
_detalhes:RegisterEvent (_detalhes.ToolBar, "DETAILS_INSTANCE_OPEN", "OnInstanceOpen")
_detalhes:RegisterEvent (_detalhes.ToolBar, "DETAILS_INSTANCE_CLOSE", "OnInstanceClose")
_detalhes.ToolBar.Enabled = true --> must have this member or will not receive the event
function _detalhes.ToolBar:OnInstanceOpen()
_detalhes.ToolBar:ReorganizeIcons()
end
function _detalhes.ToolBar:OnInstanceClose()
_detalhes.ToolBar:ReorganizeIcons()
end
function _detalhes.ToolBar:ReorganizeIcons (lastIcon)
--> get the lower number instance
local lower_instance = _detalhes:GetLowerInstanceNumber()
if (not lower_instance) then
for _, ThisButton in ipairs (_detalhes.ToolBar.Shown) do
ThisButton:Hide()
end
return
end
local instance = _detalhes:GetInstance (lower_instance)
_detalhes:ResetButtonSnapTo (instance)
_detalhes.ResetButtonInstance = lower_instance
if (#_detalhes.ToolBar.Shown > 0) then
local LastIcon
local x = 0
if (instance.consolidate) then
LastIcon = instance.consolidateButtonTexture
x = -3
else
LastIcon = instance.lastIcon or instance.baseframe.cabecalho.report
end
for _, ThisButton in ipairs (_detalhes.ToolBar.Shown) do
ThisButton:SetPoint ("left", LastIcon, "right", ThisButton.x + x, ThisButton.y)
ThisButton:Show()
LastIcon = ThisButton
end
end
for _, instancia in pairs (_detalhes.tabela_instancias) do
if (instancia.baseframe and instancia:IsAtiva()) then
instancia:ReajustaGump()
end
end
return true
end
+205
View File
@@ -0,0 +1,205 @@
--File Revision: 1
--Last Modification: 27/07/2013
-- Change Log:
-- 27/07/2013: Finished alpha version.
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
local _detalhes = _G._detalhes
local Loc = LibStub ("AceLocale-3.0"):GetLocale ( "Details" )
local _tempo = time()
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> local pointers
local _table_insert = table.insert --lua local
local _ipairs = ipairs --lua local
local _pairs = pairs --lua local
local _time = time --lua local
local timeMachine = _detalhes.timeMachine --details local
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> constants
local _tempo = _time()
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> core
timeMachine.ligada = false
function timeMachine:Core()
_tempo = _time()
_detalhes._tempo = _tempo
_detalhes:UpdateGears()
for tipo, tabela in _pairs (self.tabelas) do
for nome, jogador in _ipairs (tabela) do
if (jogador) then
--print (jogador) --> jogador é a referência da tabela classe_damage
local ultima_acao = jogador:UltimaAcao()+3
if (ultima_acao > _tempo) then --> okey o jogador esta dando dps
if (jogador.on_hold) then --> o dps estava pausado, retornar a ativa
jogador:HoldOn (false)
end
else
if (not jogador.on_hold) then --> não ta pausado, precisa por em pausa
--> verifica se esta castando alguma coisa que leve + que 3 segundos
jogador:HoldOn (true)
end
end
end
end
end
end
function timeMachine:Ligar()
self.atualizador = self:ScheduleRepeatingTimer ("Core", 1)
self.ligada = true
self.tabelas = {{}, {}} --> 1 dano 2 cura
local danos = _detalhes.tabela_vigente[1]._ActorTable
for _, jogador in _ipairs (danos) do
if (jogador.dps_started) then
jogador:RegistrarNaTimeMachine()
end
end
end
function timeMachine:Desligar()
self.ligada = false
self.tabelas = nil
if (self.atualizador) then
self:CancelTimer (self.atualizador)
self.atualizador = nil
end
end
function timeMachine:Reiniciar()
self.tabelas = {{}, {}} --> 1 dano 2 cura
end
function _detalhes:DesregistrarNaTimeMachine()
if (not timeMachine.ligada) then
return
end
local esta_tabela = timeMachine.tabelas [self.tipo]
esta_tabela [self.timeMachine] = nil
self.timeMachine = nil
end
function _detalhes:RegistrarNaTimeMachine()
if (not timeMachine.ligada) then
return
end
--if (self.tipo == 3) then
-- print (debugstack())
-- return
--end
local esta_tabela = timeMachine.tabelas [self.tipo]
_table_insert (esta_tabela, self)
self.timeMachine = #esta_tabela
end
function _detalhes:ManutencaoTimeMachine()
for tipo, tabela in _ipairs (timeMachine.tabelas) do
local t = {}
for index, jogador in _ipairs (tabela) do
if (jogador) then
t [#t+1] = jogador
jogador.timeMachine = #t
end
end
timeMachine.tabelas [tipo] = t
end
end
function _detalhes:Tempo()
if (self.end_time) then --> o tempo do jogador esta trancado
return self.end_time - self.start_time
elseif (self.on_hold) then --> o tempo esta em pausa
return self.delay - self.start_time
else
return _tempo - self.start_time
end
end
function _detalhes:IniciarTempo (tempo, shadow)
-- inicia o tempo no objeto atual
--------------------------------------------------------------------------------
if (self.start_time > 0) then
print ("DEBUG: "..self.name.." ja tinha start_time...")
else
self.start_time = tempo
end
-- inicia o tempo no shadow do objeto
--------------------------------------------------------------------------------
-- eu nao sei se a shadow esta iniciando agora sou esta apenas reabrindo
-- tbm nao sei se a shadow esta reabrindo normalmente ou se esta reabrindo devido a combate menor de 4 segundos
-- verificar se a shadow esta com TEMPO FINALIZADO
-- SE ESTIVER significa que a shadow esta sendo reaberta
if (shadow.end_time) then
-- reabrir o tempo da shadow
-- eu tenho o tempo da abertura do combate atual, e o inicio e fim do tempo da shadow
-- tempo do inicio da shadow = tempo de abertura ATUAL menos tempo de combate da shadow
local subs = shadow.end_time - shadow.start_time
shadow.start_time = tempo - subs
shadow.end_time = nil -- o tempo foi aberto retirando o end_time
else -- pela minha logica se nao tiver end_time significa que precisa apenas gravar o tempo de inicio
-- a shadow foi recém criada e esta abrindo o tempo pela primeira vez
if (shadow.start_time == 0) then --> ja esta em um combate
shadow.start_time = tempo
end
end
end
function _detalhes:TerminarTempo (subs)
if (self.end_time) then
return
end
subs = subs or 0
if (self.on_hold) then
self.end_time = self.delay - subs -- isso ta certo? por que self.delay carrega o tempo quando o jogador parou o dps
self.on_hold = false
self.delay = nil
else
self.end_time = _tempo - subs
end
if (self.shadow) then
return self.shadow:TerminarTempo (subs)
end
end
--> diz se o dps deste jogador esta em pausa
function _detalhes:HoldOn (pausa)
if (pausa == nil) then
return self.on_hold --retorna se o dps esta aberto ou fechado para este jogador
elseif (pausa) then --> true
self.delay = _tempo
self.on_hold = true
else --> false
self.start_time = self.start_time + (_tempo-self.delay)
self.on_hold = false
end
end
--controla quando foi a ultima vez que este jogador deu dano
function _detalhes:UltimaAcao (tempo)
if (not tempo) then
return self.last_event
else
self.last_event = tempo
end
end
+564
View File
@@ -0,0 +1,564 @@
--File Revision: 1
--Last Modification: 27/07/2013
-- Change Log:
-- 27/07/2013: Finished alpha version.
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
local _detalhes = _G._detalhes
local Loc = LibStub ("AceLocale-3.0"):GetLocale ( "Details" )
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> local pointers
local _table_insert = table.insert --lua local
local _upper = string.upper --lua local
local _ipairs = ipairs --lua local
local _pairs = pairs --lua local
local _string_format = string.format --lua local
local _math_floor = math.floor --lua local
local _math_max = math.max --lua local
local _type = type --lua local
local _string_match = string.match --lua local
local _UnitClass = UnitClass --wow api local
local _IsInRaid = IsInRaid --wow api local
local _IsInGroup = IsInGroup --wow api local
local _GetNumGroupMembers = GetNumGroupMembers --wow api local
local _UnitAffectingCombat = UnitAffectingCombat --wow api local
local _GameTooltip = GameTooltip --wow api local
local _UIFrameFadeIn = UIFrameFadeIn --wow api local
local _UIFrameFadeOut = UIFrameFadeOut --wow api local
local _InCombatLockdown = InCombatLockdown --wow api local
local gump = _detalhes.gump --details local
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> details api functions
--> set all table keys to lower
local temptable = {}
function _detalhes:LowerizeKeys (_table)
for key, value in _pairs (_table) do
temptable [string.lower (key)] = value
end
temptable, _table = table.wipe (_table), temptable
return _table
end
--> short numbers
function _detalhes:ToK (numero)
if (numero > 1000000) then
return _string_format ("%.2f", numero/1000000) .."M"
elseif (numero > 1000) then
return _string_format ("%.1f", numero/1000) .."K"
end
return _string_format ("%.1f", numero)
end
--> short numbers no numbers after comma
function _detalhes:ToK0 (numero)
if (numero > 1000000) then
return _string_format ("%.0f", numero/1000000) .."M"
elseif (numero > 1000) then
return _string_format ("%.0f", numero/1000) .."K"
end
return _string_format ("%.0f", numero)
end
--> remove a index from a hash table
function _detalhes:tableRemove (tabela, indexName)
local newtable = {}
for hash, value in _pairs (tabela) do
if (hash ~= indexName) then
newtable [hash] = value
end
end
return newtable
end
--> return if the numeric table have an object
function _detalhes:tableIN (tabela, objeto)
for index, valor in _ipairs (tabela) do
if (valor == objeto) then
return index
end
end
return false
end
--> unpack more than 1 table
-- thanks http://www.dzone.com/snippets/lua-unpack-multiple-tables
function _detalhes:unpacks (...)
local values = {}
for i = 1, select ('#', ...) do
for _, value in _ipairs (select (i, ...)) do
values[ #values + 1] = value
end
end
return unpack (values)
end
--> put points in numbers
-- thanks http://richard.warburton.it
function _detalhes:comma_value(n)
local left,num,right = _string_match (n,'^([^%d]*%d)(%d*)(.-)$')
return left..(num:reverse():gsub('(%d%d%d)','%1,'):reverse())..right
end
--> trim thanks from http://lua-users.org/wiki/StringTrim
function _detalhes:trim (s)
local from = s:match"^%s*()"
return from > #s and "" or s:match(".*%S", from)
end
--> scale
function _detalhes:Scale (rangeMin, rangeMax, scaleMin, scaleMax, x)
return 1 + (x-rangeMin)*(scaleMax-scaleMin)/(rangeMax-rangeMin)
end
--> font size
function _detalhes:SetFontSize (fontString, ...)
local fonte, _, flags = fontString:GetFont()
fontString:SetFont (fonte, _math_max (...), flags)
end
function _detalhes:GetFontSize (fontString)
local _, size = fontString:GetFont()
return size
end
--> font face
function _detalhes:SetFontFace (fontString, fontface)
local _, size, flags = fontString:GetFont()
fontString:SetFont (fontface, size, flags)
end
function _detalhes:GetFontFace (fontString)
local fontface = fontString:GetFont()
return fontface
end
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> internal functions
local LastDamage = 0
local LastDamageRecord = 0
--> record raid/party/player damage every second
function _detalhes:LogDps()
LastDamageRecord = LastDamageRecord + 1
if (LastDamageRecord > 1) then
LastDamageRecord = 0
local NowDamage = (_detalhes.tabela_vigente.totals_grupo[1] - LastDamage) /2
_table_insert (_detalhes.tabela_vigente.DpsGraphic, NowDamage)
if (NowDamage > _detalhes.tabela_vigente.DpsGraphic.max) then
_detalhes.tabela_vigente.DpsGraphic.max = NowDamage
end
LastDamage = _detalhes.tabela_vigente.totals_grupo[1]
end
end
--> is in combat yet?
function _detalhes:EstaEmCombate()
_detalhes.tabela_vigente.TimeData:Record()
if (_detalhes.zone_type == "pvp" or _InCombatLockdown()) then
return true
elseif (_UnitAffectingCombat("player")) then
return true
elseif (_IsInRaid()) then
for i = 1, _GetNumGroupMembers(), 1 do
if (_UnitAffectingCombat ("raid"..i)) then
return true
end
end
elseif (_IsInGroup()) then
for i = 1, _GetNumGroupMembers()-1, 1 do
if (_UnitAffectingCombat ("party"..i)) then
return true
end
end
end
LastDps = 0
_detalhes:SairDoCombate()
end
--> Armazena uma label recém criada - Store a new label on the pool
function _detalhes.font_pool:add (_fontstring)
self [#self+1] = _fontstring
end
function gump:UpdateTooltip (qual_barra, esta_barra, instancia)
_GameTooltip:Hide()
_GameTooltip:SetOwner (esta_barra, "ANCHOR_TOPRIGHT")
instancia:MontaTooltip (qual_barra)
_GameTooltip:Show()
end
local function frame_task (self, elapsed)
self.FrameTime = self.FrameTime + elapsed
if (self.HaveGradientEffect) then
local done = false
for index, ThisGradient in _ipairs (self.gradientes) do
if (self.FrameTime >= ThisGradient.NextStepAt and not ThisGradient.done) then
--> effects
if (ThisGradient.ObjectType == "frame") then
local r, g, b, a = ThisGradient.Object:GetBackdropColor()
ThisGradient.Object:SetBackdropColor (r + ThisGradient.Colors.Red, g + ThisGradient.Colors.Green, b + ThisGradient.Colors.Blue, a + ThisGradient.Colors.Alpha)
elseif (ThisGradient.ObjectType == "texture") then
local r, g, b, a = ThisGradient.Object:GetVertexColor()
ThisGradient.Object:SetVertexColor (r + ThisGradient.Colors.Red, g + ThisGradient.Colors.Green, b + ThisGradient.Colors.Blue, a + ThisGradient.Colors.Alpha)
end
ThisGradient.OnStep = ThisGradient.OnStep + 1
if (ThisGradient.FinishStep == ThisGradient.OnStep) then
if (ThisGradient.Func) then
if (type (ThisGradient.Func) == "string") then
local f = loadstring (ThisGradient.Func)
f()
else
ThisGradient.Func()
end
end
ThisGradient.done = true
done = true
else
ThisGradient.NextStepAt = self.FrameTime + ThisGradient.SleepTime
end
end
end
if (done) then
local _iter = {index = 1, data = self.gradientes [1]}
while (_iter.data) do
if (_iter.data.done) then
_iter.data.Object.HaveGradientEffect = false
table.remove (self.gradientes, _iter.index)
_iter.data = self.gradientes [_iter.index]
else
_iter.index = _iter.index + 1
_iter.data = self.gradientes [_iter.index]
end
end
if (#self.gradientes < 1) then
self.HaveGradientEffect = false
end
end
end
if (not self.HaveGradientEffect) then
self:SetScript ("OnUpdate", nil)
end
end
--[[ test grayscale ]]
function _detalhes:teste_grayscale()
local instancia = _detalhes.tabela_instancias[1]
for i = 1, instancia.barrasInfo.criadas, 1 do
local barra = instancia.barras[i]
local red, green, blue, alpha = barra.textura:GetVertexColor()
local grayscale = (red*0.03+green+blue) / 3 --> grayscale lightness method
gump:GradientEffect ( barra.textura, "texture", red, green, blue, alpha, grayscale, grayscale, grayscale, alpha, 1)
end
end
function gump:GradientEffect ( Object, ObjectType, StartRed, StartGreen, StartBlue, StartAlpha, EndRed, EndGreen, EndBlue, EndAlpha, Duration, EndFunction)
if (type (StartRed) == "table" and type (StartGreen) == "table") then
Duration, EndFunction = StartBlue, StartAlpha
EndRed, EndGreen, EndBlue, EndAlpha = unpack (StartGreen)
StartRed, StartGreen, StartBlue, StartAlpha = unpack (StartRed)
elseif (type (StartRed) == "table") then
EndRed, EndGreen, EndBlue, EndAlpha, Duration, EndFunction = StartGreen, StartBlue, StartAlpha, EndRed, EndGreen, EndBlue
StartRed, StartGreen, StartBlue, StartAlpha = unpack (StartRed)
elseif (type (EndRed) == "table") then
Duration, EndFunction = EndGreen, EndBlue
EndRed, EndGreen, EndBlue, EndAlpha = unpack (EndRed)
end
if (not EndAlpha) then
EndAlpha = 1.0
end
if (not StartAlpha) then
StartAlpha = 1.0
end
if (EndRed > 1.0) then
EndRed = 1.0
end
if (EndGreen > 1.0) then
EndGreen = 1.0
end
if (EndBlue > 1.0) then
EndBlue = 1.0
end
local GradientFrameControl = _detalhes.listener
GradientFrameControl.gradientes = GradientFrameControl.gradientes or {}
for index = 1, #GradientFrameControl.gradientes do
if (GradientFrameControl.gradientes[index].Object == Object) then
GradientFrameControl.gradientes[index].done = true
end
end
local MinFramesPerSecond = 10 --> at least 10 frames will be necessary
local ExecTime = Duration * 1000 --> value in miliseconds
local SleepTime = 100 --> 100 miliseconds
local FrameAmount = _math_floor (ExecTime/100) --> amount of frames
if (FrameAmount < MinFramesPerSecond) then
FrameAmount = MinFramesPerSecond
SleepTime = ExecTime/FrameAmount
end
local ColorStep = {}
ColorStep.Red = (EndRed - StartRed) / FrameAmount
ColorStep.Green = (EndGreen - StartGreen) / FrameAmount
ColorStep.Blue = (EndBlue - StartBlue) / FrameAmount
ColorStep.Alpha = (EndAlpha - StartAlpha) / FrameAmount
GradientFrameControl.gradientes [#GradientFrameControl.gradientes+1] = {
OnStep = 1,
FinishStep = FrameAmount,
SleepTime = SleepTime/1000,
NextStepAt = GradientFrameControl.FrameTime + (SleepTime/1000),
Object = Object,
ObjectType = string.lower (ObjectType),
Colors = ColorStep,
Func = EndFunction}
Object.HaveGradientEffect = true
GradientFrameControl.HaveGradientEffect = true
if (not GradientFrameControl:GetScript ("OnUpdate")) then
GradientFrameControl:SetScript ("OnUpdate", frame_task)
end
end
function gump:Fade (frame, tipo, velocidade, parametros)
if (_type (frame) == "table" and frame.meu_id) then --> ups, é uma instância
if (parametros == "barras") then --> hida todas as barras da instância
if (velocidade) then
for i = 1, frame.barrasInfo.criadas, 1 do
gump:Fade (frame.barras[i], tipo, velocidade)
end
return
else
velocidade = velocidade or 0.3
for i = 1, frame.barrasInfo.criadas, 1 do
gump:Fade (frame.barras[i], tipo, 0.3+(i/10))
end
return
end
elseif (parametros == "hide_barras") then --> hida todas as barras da instância
for i = 1, frame.barrasInfo.criadas, 1 do
local esta_barra = frame.barras[i]
if (esta_barra.fading_in or esta_barra.fading_out) then
esta_barra.fadeInfo.finishedFunc = nil
_UIFrameFadeIn (esta_barra, 0.01, esta_barra:GetAlpha(), esta_barra:GetAlpha())
end
esta_barra.hidden = true
esta_barra.faded = true
esta_barra.fading_in = false
esta_barra.fading_out = false
esta_barra:Hide()
esta_barra:SetAlpha(0)
end
return
end
end
velocidade = velocidade or 0.3
--> esse ALL aqui pode dar merda com as instâncias não ativadas
if (frame == "all") then --> todas as instâncias
for _, instancia in _ipairs (_detalhes.tabela_instancias) do
if (parametros == "barras") then --> hida todas as barras da instância
for i = 1, instancia.barrasInfo.criadas, 1 do
gump:Fade (instancia.barras[i], tipo, velocidade+(i/10))
end
end
end
elseif (_upper (tipo) == "IN") then
if (frame:GetAlpha() == 0 and frame.hidden and not frame.fading_out) then --> ja esta escondida
return
elseif (frame.fading_in) then --> ja esta com uma animação, se for true
return
end
if (frame.fading_out) then --> se tiver uma animação de aparecer em andamento se for true
frame.fading_out = false
end
_UIFrameFadeIn (frame, velocidade, frame:GetAlpha(), 0)
frame.fading_in = true
frame.fadeInfo.finishedFunc =
function()
frame.hidden = true
frame.faded = true
frame.fading_in = false
frame:Hide()
end
elseif (_upper (tipo) == "OUT") then --> aparecer
if (frame:GetAlpha() == 1 and not frame.hidden and not frame.fading_in) then --> ja esta na tela
return
elseif (frame.fading_out) then --> já ta com fading out
return
end
if (frame.fading_in) then --> se tiver uma animação de hidar em andamento se for true
frame.fading_in = false
end
frame:Show()
_UIFrameFadeOut (frame, velocidade, frame:GetAlpha(), 1.0)
frame.fading_out = true
frame.fadeInfo.finishedFunc =
function()
frame.hidden = false
frame.faded = false
frame.fading_out = false
end
elseif (tipo == 0) then --> força o frame a ser mostrado
frame.hidden = false
frame.faded = false
frame.fading_out = false
frame.fading_in = false
frame:Show()
frame:SetAlpha(1)
if (frame.fadeInfo) then --> limpa a função de fade se tiver alguma
frame.fadeInfo.finishedFunc = nil
end
elseif (tipo == 1) then --> força o frame a ser hidado
frame.hidden = true
frame.faded = true
frame.fading_out = false
frame.fading_in = false
frame:Hide()
frame:SetAlpha(0)
if (frame.fadeInfo) then --> limpa a função de fade se tiver alguma
frame.fadeInfo.finishedFunc = nil
end
elseif (tipo == -1) then --> apenas da fade sem hidar
if (frame:GetAlpha() == 0 and frame.hidden and not frame.fading_out) then --> ja esta escondida
return
elseif (frame.fading_in) then --> ja esta com uma animação, se for true
return
end
if (frame.fading_out) then --> se tiver uma animação de aparecer em andamento se for true
frame.fading_out = false
end
_UIFrameFadeIn (frame, velocidade, frame:GetAlpha(), 0)
frame.fading_in = true
frame.fadeInfo.finishedFunc =
function()
frame.hidden = false
frame.faded = true
frame.fading_in = false
end
elseif (_upper (tipo) == "ALPHAANIM") then
local value = velocidade
local currentApha = frame:GetAlpha()
frame:Show()
if (currentApha < value) then
if (frame.fading_in) then --> se tiver uma animação de hidar em andamento se for true
frame.fading_in = false
frame.fadeInfo.finishedFunc = nil
end
UIFrameFadeOut (frame, 0.3, currentApha, value)
frame.fading_out = true
frame.fadeInfo.finishedFunc =
function()
frame.fading_out = false
end
else
if (frame.fading_out) then --> se tiver uma animação de hidar em andamento se for true
frame.fading_out = false
frame.fadeInfo.finishedFunc = nil
end
UIFrameFadeIn (frame, 0.3, currentApha, value)
frame.fading_in = true
frame.fadeInfo.finishedFunc =
function()
frame.fading_in = false
end
end
elseif (_upper (tipo) == "ALPHA") then --> setando um alpha determinado
if (frame.fading_in or frame.fading_out) then
frame.fadeInfo.finishedFunc = nil
_UIFrameFadeIn (frame, velocidade, frame:GetAlpha(), frame:GetAlpha())
end
frame.hidden = false
frame.faded = false
frame.fading_in = false
frame.fading_out = false
frame:Show()
frame:SetAlpha (velocidade)
end
end
function _detalhes:name_space (barra)
--if (barra.icone_secundario_ativo) then
-- local tamanho = barra:GetWidth()-barra.texto_direita:GetStringWidth()-16-barra:GetHeight()
-- barra.texto_esquerdo:SetSize (tamanho-2, 15)
--else
barra.texto_esquerdo:SetSize (barra:GetWidth()-barra.texto_direita:GetStringWidth()-18, 15)
--end
end
function _detalhes:name_space_info (barra)
if (barra.icone_secundario_ativo) then
local tamanho = barra:GetWidth()-barra.texto_direita:GetStringWidth()-16-barra:GetHeight()
barra.texto_esquerdo:SetSize (tamanho-10, 15)
else
local tamanho = barra:GetWidth()-barra.texto_direita:GetStringWidth()-16
barra.texto_esquerdo:SetSize (tamanho-10, 15)
end
end
function _detalhes:name_space_generic (barra, separador)
local texto_direita_tamanho = barra.texto_direita:GetStringWidth()
local tamanho = barra:GetWidth()-texto_direita_tamanho-16
if (separador) then
barra.texto_esquerdo:SetSize (tamanho+separador, 10)
barra.texto_direita:SetSize (texto_direita_tamanho+15, 10)
else
barra.texto_esquerdo:SetSize (tamanho-10, 15)
barra.texto_direita:SetSize (texto_direita_tamanho+5, 15)
end
end
+565
View File
@@ -0,0 +1,565 @@
--File Revision: 1
--Last Modification: 27/07/2013
-- Change Log:
-- 27/07/2013: Finished alpha version.
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
local _detalhes = _G._detalhes
local Loc = LibStub ("AceLocale-3.0"):GetLocale ( "Details" )
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> local pointers
local _math_floor = math.floor --lua local
local _type = type --lua local
local _math_abs = math.abs --lua local
local _ipairs = ipairs --lua local
local _GetScreenWidth = GetScreenWidth --wow api local
local _GetScreenHeight = GetScreenHeight --wow api local
local _UIParent = UIParent --wow api local
local gump = _detalhes.gump --details local
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> core
function _detalhes:AnimarSplit (barra, goal)
barra.inicio = barra.split.barra:GetValue()
barra.fim = goal
barra.proximo_update = 0
barra.tem_animacao = 1
barra:SetScript ("OnUpdate", self.FazerAnimacaoSplit)
end
function _detalhes:FazerAnimacaoSplit (elapsed)
--[[
local velocidade = 0.1
local distancia = self.inicio - self.fim
if (distancia > 40 or distancia < -40) then
velocidade = 0.8
elseif (distancia > 20 or distancia < -20) then
velocidade = 0.4
end
--]]
local velocidade = 0.8
if (self.fim > self.inicio) then
self.inicio = self.inicio+velocidade
self.split.barra:SetValue (self.inicio)
self.split.div:SetPoint ("left", self.split.barra, "left", self.split.barra:GetValue()* (self.split.barra:GetWidth()/100) - 4, 0)
if (self.inicio+1 >= self.fim) then
self.tem_animacao = 0
self:SetScript ("OnUpdate", nil)
end
else
self.inicio = self.inicio-velocidade
self.split.barra:SetValue (self.inicio)
self.split.div:SetPoint ("left", self.split.barra, "left", self.split.barra:GetValue()* (self.split.barra:GetWidth()/100) - 4, 0)
if (self.inicio-1 <= self.fim) then
self.tem_animacao = 0
self:SetScript ("OnUpdate", nil)
end
end
self.proximo_update = 0
end
function _detalhes:AnimarBarra (esta_barra, fim)
esta_barra.inicio = esta_barra.statusbar:GetValue()
esta_barra.fim = fim
esta_barra.proximo_update = 0
esta_barra.tem_animacao = 1
esta_barra:SetScript ("OnUpdate", self.FazerAnimacao)
end
function _detalhes:FazerAnimacao (elapsed)
local velocidade = 0.8
--[[
local velocidade = 0.1
local distancia = self.inicio - self.fim
if (distancia > 40 or distancia < -40) then
velocidade = 0.8
elseif (distancia > 20 or distancia < -20) then
velocidade = 0.4
end
--]]
if (self.fim > self.inicio) then
self.inicio = self.inicio+velocidade
self.statusbar:SetValue (self.inicio)
if (self.inicio+1 >= self.fim) then
self.tem_animacao = 0
self:SetScript ("OnUpdate", nil)
end
else
self.inicio = self.inicio-velocidade
self.statusbar:SetValue (self.inicio)
if (self.inicio-1 <= self.fim) then
self.tem_animacao = 0
self:SetScript ("OnUpdate", nil)
end
end
self.proximo_update = 0
end
function _detalhes:AtualizaPontos()
local xOfs, yOfs = self.baseframe:GetCenter()
if (not xOfs) then
return
end
-- credits to ckknight (http://www.curseforge.com/profiles/ckknight/)
local _scale = self.baseframe:GetEffectiveScale()
local _UIscale = _UIParent:GetScale()
xOfs = xOfs*_scale - _GetScreenWidth()*_UIscale/2
yOfs = yOfs*_scale - _GetScreenHeight()*_UIscale/2
local _x = xOfs/_UIscale
local _y = yOfs/_UIscale
local _w = self.baseframe:GetWidth()
local _h = self.baseframe:GetHeight()
local metade_largura = _w/2
local metade_altura = _h/2
self.ponto1 = {x = _x - metade_largura, y = _y + metade_altura}
self.ponto2 = {x = _x - metade_largura, y = _y - metade_altura}
self.ponto3 = {x = _x + metade_largura, y = _y - metade_altura}
self.ponto4 = {x = _x + metade_largura, y = _y + metade_altura}
end
function _detalhes:SaveMainWindowPosition (instance)
if (instance) then
self = instance
end
local xOfs, yOfs = self.baseframe:GetCenter()
if (not xOfs) then
--> this is a small and unknow bug when resizing all windows throgh crtl key (all) the last window of a horizontal row can't 'GetCenter'.
--> so, the trick is we start a timer to save pos later.
return _detalhes:ScheduleTimer ("SaveMainWindowPosition", 1, self)
end
-- credits to ckknight (http://www.curseforge.com/profiles/ckknight/)
local _scale = self.baseframe:GetEffectiveScale()
local _UIscale = _UIParent:GetScale()
local mostrando = self.mostrando
xOfs = xOfs*_scale - _GetScreenWidth()*_UIscale/2
yOfs = yOfs*_scale - _GetScreenHeight()*_UIscale/2
local _w = self.baseframe:GetWidth()
local _h = self.baseframe:GetHeight()
local _x = xOfs/_UIscale
local _y = yOfs/_UIscale
self.posicao[mostrando].x = _x
self.posicao[mostrando].y = _y
self.posicao[mostrando].w = _w
self.posicao[mostrando].h = _h
local metade_largura = _w/2
local metade_altura = _h/2
self.ponto1 = {x = _x - metade_largura, y = _y + metade_altura}
self.ponto2 = {x = _x - metade_largura, y = _y - metade_altura}
self.ponto3 = {x = _x + metade_largura, y = _y - metade_altura}
self.ponto4 = {x = _x + metade_largura, y = _y + metade_altura}
self.baseframe.BoxBarrasAltura = self.baseframe:GetHeight()-4 --> isso aqui não sei o que esta fazendo aqui
return {altura = self.baseframe:GetHeight(), largura = self.baseframe:GetWidth(), x = xOfs/_UIscale, y = yOfs/_UIscale}
end
function _detalhes:RestoreMainWindowPosition (pre_defined)
-- credits to ckknight (http://www.curseforge.com/profiles/ckknight/)
local _scale = self.baseframe:GetEffectiveScale()
local _UIscale = _UIParent:GetScale()
local novo_x = self.posicao[self.mostrando].x*_UIscale/_scale
local novo_y = self.posicao[self.mostrando].y*_UIscale/_scale
if (pre_defined) then --> overwrite
novo_x = pre_defined.x*_UIscale/_scale
novo_y = pre_defined.y*_UIscale/_scale
self.posicao[self.mostrando].w = pre_defined.largura
self.posicao[self.mostrando].h = pre_defined.altura
end
self.baseframe:ClearAllPoints()
self.baseframe:SetPoint ("CENTER", _UIParent, "CENTER", novo_x, novo_y)
self.baseframe:SetWidth (self.posicao[self.mostrando].w) --slider frame
self.baseframe:SetHeight (self.posicao[self.mostrando].h)
self.baseframe.BoxBarrasAltura = self.baseframe:GetHeight()-4 --> ?????
end
function _detalhes:RestoreMainWindowPositionNoResize (pre_defined, x, y)
x = x or 0
y = y or 0
-- credits to ckknight (http://www.curseforge.com/profiles/ckknight/)
local _scale = self.baseframe:GetEffectiveScale()
local _UIscale = _UIParent:GetScale()
local novo_x = self.posicao[self.mostrando].x*_UIscale/_scale
local novo_y = self.posicao[self.mostrando].y*_UIscale/_scale
if (pre_defined) then --> overwrite
novo_x = pre_defined.x*_UIscale/_scale
novo_y = pre_defined.y*_UIscale/_scale
self.posicao[self.mostrando].w = pre_defined.largura
self.posicao[self.mostrando].h = pre_defined.altura
end
self.baseframe:ClearAllPoints()
self.baseframe:SetPoint ("CENTER", _UIParent, "CENTER", novo_x + x, novo_y + y)
self.baseframe.BoxBarrasAltura = self.baseframe:GetHeight()-4 --> ?????
end
function _detalhes:ResetaGump (instancia, tipo, segmento)
if (not instancia or _type (instancia) == "boolean") then
segmento = tipo
tipo = instancia
instancia = self
end
if (tipo and tipo == 0x1) then --> entrando em combate
if (instancia.segmento == -1) then --> esta mostrando a tabela overall
return
end
end
if (segmento and instancia.segmento ~= segmento) then
return
end
instancia.barraS = {nil, nil} --> zera o iterator
instancia.barrasInfo.mostrando = 0 --> resetou, então não esta mostranho nenhuma barra
for i = 1, instancia.barrasInfo.criadas, 1 do --> limpa a referência do que estava sendo mostrado na barra
local esta_barra= instancia.barras[i]
esta_barra.minha_tabela = nil
end
if (instancia.rolagem) then
instancia:EsconderScrollBar() --> hida a scrollbar
end
instancia.need_rolagem = false
instancia.bar_mod = nil
end
function _detalhes:ReajustaGump()
if (self.mostrando == "normal") then --> somente alterar o tamanho das barras se tiver mostrando o gump normal
if (self.meu_id == _detalhes.ResetButtonInstance) then
if (self.baseframe:GetWidth() < 215) then
gump:Fade (_detalhes.ResetButton, 1)
gump:Fade (_detalhes.ResetButton2, 0)
_detalhes.ResetButtonMode = 2
else
gump:Fade (_detalhes.ResetButton, 0)
gump:Fade (_detalhes.ResetButton2, 1)
_detalhes.ResetButtonMode = 1
end
end
if (not self.baseframe.isStretching and self.stretchToo and #self.stretchToo > 0) then
if (self.eh_horizontal or self.eh_tudo or (self.verticalSnap and not self.eh_vertical)) then
for _, instancia in _ipairs (self.stretchToo) do
instancia.baseframe:SetWidth (self.baseframe:GetWidth())
local mod = (self.baseframe:GetWidth() - instancia.baseframe._place.largura) / 2
instancia:RestoreMainWindowPositionNoResize (instancia.baseframe._place, mod, nil)
instancia:BaseFrameSnap()
end
end
if ( (self.eh_vertical or self.eh_tudo or not self.eh_horizontal) and (not self.verticalSnap or self.eh_vertical)) then
for _, instancia in _ipairs (self.stretchToo) do
if (instancia.baseframe) then --> esta criada
instancia.baseframe:SetHeight (self.baseframe:GetHeight())
local mod
if (self.eh_vertical) then
mod = (self.baseframe:GetHeight() - instancia.baseframe._place.altura) / 2
else
mod = - (self.baseframe:GetHeight() - instancia.baseframe._place.altura) / 2
end
instancia:RestoreMainWindowPositionNoResize (instancia.baseframe._place, nil, mod)
instancia:BaseFrameSnap()
end
end
end
elseif (self.baseframe.isStretching and self.stretchToo and #self.stretchToo > 0) then
for _, instancia in _ipairs (self.stretchToo) do
instancia.baseframe:SetHeight (self.baseframe:GetHeight())
local mod = (self.baseframe:GetHeight() - instancia.baseframe._place.altura) / 2
instancia:RestoreMainWindowPositionNoResize (instancia.baseframe._place, nil, mod)
end
end
if (_detalhes.lower_instance == self.meu_id or self.consolidate) then
if (not self.consolidate) then
if (self.baseframe:GetWidth() < 180) then
--> consolidate menus
self:ConsolidateIcons()
end
else
if (self.baseframe:GetWidth() > 180 or _detalhes.lower_instance ~= self.meu_id) then
--> un consolidade menus
self:UnConsolidateIcons()
end
end
end
-- -4 difere a precisão de quando a barra será adicionada ou apagada da barra
self.baseframe.BoxBarrasAltura = self.baseframe:GetHeight()-4
local T = self.barrasInfo.cabem
if (not T) then --> primeira vez que o gump esta sendo reajustado
T = _math_floor (self.baseframe.BoxBarrasAltura / self.barrasInfo.alturaReal)
-- o que mais precisa por aqui?
end
--> reajustar o local do relógio
local meio = self.baseframe:GetWidth() / 2
local novo_local = meio - 25
self.barrasInfo.cabem = _math_floor ( self.baseframe.BoxBarrasAltura / self.barrasInfo.alturaReal)
if (self.barrasInfo.cabem > #self.barras) then--> verifica se precisa criar mais barras
for i = #self.barras+1, self.barrasInfo.cabem, 1 do
local nova_barra = gump:CriaNovaBarra (self, i, 30) --> cria nova barra
nova_barra.texto_esquerdo:SetText (Loc ["STRING_NEWROW"]) --seta o texto da esqueda
nova_barra.statusbar:SetValue (100)
self.barras [i] = nova_barra
end
self.barrasInfo.criadas = #self.barras
end
--> seta a largura das barras
if (self.bar_mod and self.bar_mod ~= 0) then
for index = 1, self.barrasInfo.cabem do
self.barras [index]:SetWidth (self.baseframe:GetWidth()+self.bar_mod)
end
else
for index = 1, self.barrasInfo.cabem do
self.barras [index]:SetWidth (self.baseframe:GetWidth()+self.barrasInfo.espaco.direita)
end
end
local A = self.barraS[1]
if (not A) then --> primeira vez que o resize esta sendo usado, no caso no startup do addon ou ao criar uma nova instância
--> hida as barras não usadas
for i = 1, self.barrasInfo.criadas, 1 do
gump:Fade (self.barras [i], 1)
self.barras [i].on = false
end
return
end
local X = self.barrasInfo.mostrando
local C = self.barrasInfo.cabem
--> novo iterator
local barras_diff = C - T --> aqui pega a quantidade de barras, se aumentou ou diminuiu
if (barras_diff > 0) then --> ganhou barras_diff novas barras
local fim_iterator = self.barraS[2] --> posição atual
fim_iterator = fim_iterator+barras_diff --> nova posição
local excedeu_iterator = fim_iterator - X --> total que ta sendo mostrado - fim do iterator
if (excedeu_iterator > 0) then --> extrapolou
fim_iterator = X --> seta o fim do iterator pra ser na ultima barra
self.barraS[2] = fim_iterator --> fim do iterator setado
local inicio_iterator = self.barraS[1]
if (inicio_iterator-excedeu_iterator > 0) then --> se as barras que sobraram preenchem o inicio do iterator
inicio_iterator = inicio_iterator-excedeu_iterator --> pega o novo valor do iterator
self.barraS[1] = inicio_iterator
else
self.barraS[1] = 1 --> se ganhou mais barras pra cima, ignorar elas e mover o iterator para a pocição inicial
end
else
--> se não extrapolou esta okey e esta mostrando a quantidade de barras correta
self.barraS[2] = fim_iterator
end
for index = T+1, C do
if (index <= X) then
gump:Fade (self.barras[index], "out")
else
--gump:Fade (self.barras[index], "in")
if (self.baseframe.isStretching or self.auto_resize) then
gump:Fade (self.barras[index], 1)
else
gump:Fade (self.barras[index], "in", 0.1)
end
end
end
elseif (barras_diff < 0) then --> perdeu barras_diff barras
local fim_iterator = self.barraS[2] --> posição atual
if (not (fim_iterator == X and fim_iterator < C)) then --> calcula primeiro as barras que foram perdidas são barras que não estavam sendo usadas
--> perdi X barras, diminui X posições no iterator
local perdeu = _math_abs (barras_diff)
if (fim_iterator == X) then --> se o iterator tiver na ultima posição
perdeu = perdeu - (C - X)
end
fim_iterator = fim_iterator - perdeu
if (fim_iterator < C) then
fim_iterator = C
end
self.barraS[2] = fim_iterator
for index = T, C+1, -1 do
--gump:Fade (self.barras[index], "in")
if (self.baseframe.isStretching or self.auto_resize) then
gump:Fade (self.barras[index], 1)
else
gump:Fade (self.barras[index], "in", 0.1)
end
end
end
end
if (X <= C) then --> desligar a rolagem
if (self.rolagem and not self.baseframe.isStretching) then
self:EsconderScrollBar()
end
self.need_rolagem = false
else --> ligar ou atualizar a rolagem
if (not self.rolagem and not self.baseframe.isStretching) then
self:MostrarScrollBar()
end
self.need_rolagem = true
end
--> verificar o tamanho dos nomes
local qual_barra = 1
for i = self.barraS[1], self.barraS[2], 1 do
local esta_barra = self.barras [qual_barra]
local tabela = esta_barra.minha_tabela
if (tabela) then --> a barra esta mostrando alguma coisa
if (tabela._custom) then
tabela (esta_barra, self)
else
tabela:RefreshBarra (esta_barra, self)
end
if (esta_barra.minha_tabela.enemy) then
--if (i == 1) then
--print (esta_barra.texto_esquerdo:GetWrappedWidth())
--end
--esta_barra.texto_esquerdo:SetText (esta_barra.colocacao.."."..esta_barra.minha_tabela.nome.." |TInterface\\PVPFrame\\PVP-Currency-Horde:14:14|t") --seta o texto da esqueda
--local texto_len = esta_barra.texto_esquerdo:GetStringWidth()
--if (esta_barra.texto_esquerdo:IsTruncated()) then
--local tamanho = esta_barra:GetWidth()-esta_barra.texto_direita:GetStringWidth()-16-esta_barra:GetHeight()
--esta_barra.icone_secundario:SetPoint ("left", esta_barra.texto_esquerdo, "left", tamanho-2, 0)
--print ("aqui")
--else
--print ("aqui")
--if (i == 1) then
--print (esta_barra.texto_esquerdo:GetStringWidth()) --debug
--print (esta_barra.texto_esquerdo:GetText())
--end
--local fonte, size, flags = esta_barra.texto_esquerdo:GetFont()
--print (fonte, size, flags)
--esta_barra.icone_secundario:SetPoint ("left", esta_barra.texto_esquerdo, "left", esta_barra.texto_esquerdo:GetStringWidth()+3, 0)
--esta_barra.texto_esquerdo:SetText (esta_barra.colocacao.."."..esta_barra.minha_tabela.nome.." |TInterface\\PVPFrame\\PVP-Currency-Horde:14:14|t") --seta o texto da esqueda
--end
end
end
qual_barra = qual_barra+1
end
--> força o próximo refresh
self.showing[self.atributo].need_refresh = true
end
end
--> cria o frame de wait for plugin
do
local WaitForPluginFrame = CreateFrame ("frame", "DetailsWaitForPluginFrame", UIParent)
local WaitTexture = WaitForPluginFrame:CreateTexture (nil, "overlay")
WaitTexture:SetTexture ("Interface\\UNITPOWERBARALT\\Mechanical_Circular_Frame")
WaitTexture:SetPoint ("center", WaitForPluginFrame)
WaitTexture:SetWidth (180)
WaitTexture:SetHeight (180)
WaitForPluginFrame.wheel = WaitTexture
local RotateAnimGroup = WaitForPluginFrame:CreateAnimationGroup()
local rotate = RotateAnimGroup:CreateAnimation ("Rotation")
rotate:SetDegrees (360)
rotate:SetDuration (60)
RotateAnimGroup:SetLooping ("repeat")
local bgpanel = gump:NewPanel (UIParent, UIParent, "DetailsWaitFrameBG", nil, 120, 30, false, false, false)
bgpanel:SetPoint ("center", WaitForPluginFrame, "center")
bgpanel:SetBackdrop ({bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background"})
bgpanel:SetBackdropColor (.2, .2, .2, 1)
local label = gump:NewLabel (UIParent, UIParent, nil, nil, Loc ["STRING_WAITPLUGIN"]) --> localize-me
label.color = "silver"
label:SetPoint ("center", WaitForPluginFrame, "center")
label:SetJustifyH ("center")
label:Hide()
WaitForPluginFrame:Hide()
function _detalhes:WaitForSoloPlugin (instancia)
if (WaitForPluginFrame:IsShown() and WaitForPluginFrame:GetParent() == instancia.baseframe) then
return _detalhes:ScheduleTimer ("ExecDelayedPlugin", 5, instancia)
end
WaitForPluginFrame:SetParent (instancia.baseframe)
WaitForPluginFrame:SetAllPoints (instancia.baseframe)
local size = math.max (instancia.baseframe:GetHeight()* 0.35, 100)
WaitForPluginFrame.wheel:SetWidth (size)
WaitForPluginFrame.wheel:SetHeight (size)
WaitForPluginFrame:Show()
label:Show()
bgpanel:Show()
RotateAnimGroup:Play()
return _detalhes:ScheduleTimer ("ExecDelayedPlugin", 5, instancia)
end
function _detalhes:CancelWaitForPlugin()
RotateAnimGroup:Stop()
WaitForPluginFrame:Hide()
label:Hide()
bgpanel:Hide()
end
function _detalhes:ExecDelayedPlugin (instancia)
RotateAnimGroup:Stop()
WaitForPluginFrame:Hide()
label:Hide()
bgpanel:Hide()
if (instancia.meu_id == _detalhes.solo) then
_detalhes.SoloTables:switch (_, _detalhes.SoloTables.Mode)
elseif (instancia.meu_id == _detalhes.raid) then
_detalhes.RaidTables:switch (_, _detalhes.RaidTables.Mode)
end
end
end
+11
View File
@@ -0,0 +1,11 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/..\FrameXML\UI.xsd">
<Script file="Libs\LibStub\LibStub.lua"/>
<Include file="Libs\CallbackHandler-1.0\CallbackHandler-1.0.xml" />
<Include file="Libs\AceLocale-3.0\AceLocale-3.0.xml" />
<Include file="Libs\AceAddon-3.0\AceAddon-3.0.xml" />
<Include file="Libs\AceComm-3.0\AceComm-3.0.xml" />
<Include file="Libs\AceSerializer-3.0\AceSerializer-3.0.xml" />
<Include file="Libs\AceTimer-3.0\AceTimer-3.0.xml" />
<Include file="Libs\LibSharedMedia-3.0\lib.xml"/>
<Script file="Libs\LibGraph-2.0\LibGraph-2.0.lua"/>
</Ui>
+665
View File
@@ -0,0 +1,665 @@
--> details main objects
local _detalhes = _G._detalhes
local gump = _detalhes.gump
local _rawset = rawset --> lua local
local _rawget = rawget --> lua local
local _setmetatable = setmetatable --> lua local
local _unpack = unpack --> lua local
local _type = type --> lua local
local _math_floor = math.floor --> lua local
local loadstring = loadstring --> lua local
local cleanfunction = function() end
local APIButtonFunctions = false
local ButtonMetaFunctions = {}
------------------------------------------------------------------------------------------------------------
--> metatables
ButtonMetaFunctions.__call = function (_table, value, ...)
return self.func (_table.param1, _table.param2, value, ...)
end
------------------------------------------------------------------------------------------------------------
--> members
--> tooltip
local gmember_tooltip = function (_object)
return _object:GetTooltip()
end
--> shown
local gmember_shown = function (_object)
return _object:IsShown()
end
--> frame width
local gmember_width = function (_object)
return _object.button:GetWidth()
end
--> frame height
local gmember_height = function (_object)
return _object.button:GetHeight()
end
--> text
local gmember_text = function (_object)
return _object.button.text:GetText()
end
--> function
local gmember_function = function (_object)
return _rawget (_object, "func")
end
--> text color
local gmember_textcolor = function (_object)
return _object.button.text:GetTextColor()
end
--> text font
local gmember_textfont = function (_object)
local fontface = _object.button.text:GetFont()
return fontface
end
--> text size
local gmember_textsize = function (_object)
local _, fontsize = _object.button.text:GetFont()
return fontsize
end
--> texture
local gmember_texture = function (_object)
return {_object.button:GetNormalTexture(), _object.button:GetHighlightTexture(), _object.button:GetPushedTexture(), _object.button:GetDisabledTexture()}
end
--> locked
local gmember_locked = function (_object)
return _rawget (_object, "is_locked")
end
local get_members_function_index = {
["tooltip"] = gmember_tooltip,
["shown"] = gmember_shown,
["width"] = gmember_width,
["height"] = gmember_height,
["text"] = gmember_text,
["clickfunction"] = gmember_function,
["texture"] = gmember_texture,
["locked"] = gmember_locked,
["fontcolor"] = gmember_textcolor,
["fontface"] = gmember_textfont,
["fontsize"] = gmember_textsize,
["textcolor"] = gmember_textcolor, --alias
["textfont"] = gmember_textfont, --alias
["textsize"] = gmember_textsize --alias
}
ButtonMetaFunctions.__index = function (_table, _member_requested)
local func = get_members_function_index [_member_requested]
if (func) then
return func (_table, _member_requested)
end
local fromMe = _rawget (_table, _member_requested)
if (fromMe) then
return fromMe
end
return ButtonMetaFunctions [_member_requested]
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> tooltip
local smember_tooltip = function (_object, _value)
return _object:SetTooltip (_value)
end
--> show
local smember_show = function (_object, _value)
if (_value) then
return _object:Show()
else
return _object:Hide()
end
end
--> hide
local smember_hide = function (_object, _value)
if (not _value) then
return _object:Show()
else
return _object:Hide()
end
end
--> frame width
local smember_width = function (_object, _value)
return _object.button:SetWidth (_value)
end
--> frame height
local smember_height = function (_object, _value)
return _object.button:SetHeight (_value)
end
--> text
local smember_text = function (_object, _value)
return _object.button.text:SetText (_value)
end
--> function
local smember_function = function (_object, _value)
return _rawset (_object, "func", _value)
end
--> text color
local smember_textcolor = function (_object, _value)
local _value1, _value2, _value3, _value4 = gump:ParseColors (_value)
return _object.button.text:SetTextColor (_value1, _value2, _value3, _value4)
end
--> text font
local smember_textfont = function (_object, _value)
return _detalhes:SetFontFace (_object.button.text, _value)
end
--> text size
local smember_textsize = function (_object, _value)
return _detalhes:SetFontSize (_object.button.text, _value)
end
--> texture
local smember_texture = function (_object, _value)
if (_type (_value) == "table") then
local _value1, _value2, _value3, _value4 = unpack (_value)
if (_value1) then
_object.button:SetNormalTexture (_value1)
end
if (_value2) then
_object.button:SetHighlightTexture (_value2, "ADD")
end
if (_value3) then
_object.button:SetPushedTexture (_value3)
end
if (_value4) then
_object.button:SetDisabledTexture (_value4)
end
else
_object.button:SetNormalTexture (_value)
_object.button:SetHighlightTexture (_value, "ADD")
_object.button:SetPushedTexture (_value)
_object.button:SetDisabledTexture (_value)
end
return
end
--> locked
local smember_locked = function (_object, _value)
if (_value) then
_object.button:SetMovable (false)
return _rawset (_object, "is_locked", true)
else
_object.button:SetMovable (true)
_rawset (_object, "is_locked", false)
return
end
end
local set_members_function_index = {
["tooltip"] = smember_tooltip,
["show"] = smember_show,
["hide"] = smember_hide,
["width"] = smember_width,
["height"] = smember_height,
["text"] = smember_text,
["clickfunction"] = smember_function,
["textcolor"] = smember_textcolor,
["textfont"] = smember_textfont,
["textsize"] = smember_textsize,
["texture"] = smember_texture,
["locked"] = smember_locked,
}
ButtonMetaFunctions.__newindex = function (_table, _key, _value)
local func = set_members_function_index [_key]
if (func) then
return func (_table, _value)
else
return _rawset (_table, _key, _value)
end
end
------------------------------------------------------------------------------------------------------------
--> methods
--> show & hide
function ButtonMetaFunctions:IsShown()
return self.button:IsShown()
end
function ButtonMetaFunctions:Show()
return self.button:Show()
end
function ButtonMetaFunctions:Hide()
return self.button:Hide()
end
-- setpoint
function ButtonMetaFunctions:SetPoint (v1, v2, v3, v4, v5)
v1, v2, v3, v4, v5 = gump:CheckPoints (v1, v2, v3, v4, v5, self)
if (not v1) then
print ("Invalid parameter for SetPoint")
return
end
return self.widget:SetPoint (v1, v2, v3, v4, v5)
end
-- sizes
function ButtonMetaFunctions:SetSize (w, h)
if (w) then
self.button:SetWidth (w)
end
if (h) then
return self.button:SetHeight (h)
end
end
-- tooltip
function ButtonMetaFunctions:SetTooltip (tooltip)
if (tooltip) then
return _rawset (self, "have_tooltip", tooltip)
else
return _rawset (self, "have_tooltip", nil)
end
end
function ButtonMetaFunctions:GetTooltip()
return _rawget (self, "have_tooltip")
end
-- functions
function ButtonMetaFunctions:SetClickFunction (func, param1, param2, clicktype)
if (not clicktype or string.find (string.lower (clicktype), "left")) then
if (func) then
_rawset (self, "func", func)
else
_rawset (self, "func", cleanfunction)
end
if (param1) then
_rawset (self, "param1", param1)
end
if (param2) then
_rawset (self, "param2", param2)
end
elseif (clicktype or string.find (string.lower (clicktype), "right")) then
if (func) then
_rawset (self, "funcright", func)
else
_rawset (self, "funcright", cleanfunction)
end
end
end
-- text
function ButtonMetaFunctions:SetText (text)
if (text) then
self.button.text:SetText (text)
else
self.button.text:SetText (nil)
end
end
-- textcolor
function ButtonMetaFunctions:SetTextColor (color)
local _value1, _value2, _value3, _value4 = gump:ParseColors (color)
return self.button.text:SetTextColor (_value1, _value2, _value3, _value4)
end
-- textsize
function ButtonMetaFunctions:SetTextSize (size)
return _detalhes:SetFontSize (self.button.text, _value)
end
-- textfont
function ButtonMetaFunctions:SetTextFont (font)
return _detalhes:SetFontFace (_object.button.text, _value)
end
-- textures
function ButtonMetaFunctions:SetTexture (normal, highlight, pressed, disabled)
if (normal) then
self.button:SetNormalTexture (normal)
elseif (_type (normal) ~= "boolean") then
self.button:SetNormalTexture (nil)
end
if (_type (highlight) == "boolean") then
if (highlight and normal and _type (normal) ~= "boolean") then
self.button:SetHighlightTexture (normal, "ADD")
end
elseif (highlight == nil) then
self.button:SetHighlightTexture (nil)
else
self.button:SetHighlightTexture (highlight, "ADD")
end
if (_type (pressed) == "boolean") then
if (pressed and normal and _type (normal) ~= "boolean") then
self.button:SetPushedTexture (normal)
end
elseif (pressed == nil) then
self.button:SetPushedTexture (nil)
else
self.button:SetPushedTexture (pressed, "ADD")
end
if (_type (disabled) == "boolean") then
if (disabled and normal and _type (normal) ~= "boolean") then
self.button:SetDisabledTexture (normal)
end
elseif (disabled == nil) then
self.button:SetDisabledTexture (nil)
else
self.button:SetDisabledTexture (disabled, "ADD")
end
end
-- frame levels
function ButtonMetaFunctions:GetFrameLevel()
return self.button:GetFrameLevel()
end
function ButtonMetaFunctions:SetFrameLevel (level, frame)
if (not frame) then
return self.button:SetFrameLevel (level)
else
local framelevel = frame:GetFrameLevel (frame) + level
return self.button:SetFrameLevel (framelevel)
end
end
-- frame stratas
function ButtonMetaFunctions:SetFrameStrata()
return self.button:GetFrameStrata()
end
function ButtonMetaFunctions:SetFrameStrata (strata)
if (_type (strata) == "table") then
self.button:SetFrameStrata (strata:GetFrameStrata())
else
self.button:SetFrameStrata (strata)
end
end
-- enabled
function ButtonMetaFunctions:IsEnabled()
return self.button:IsEnabled()
end
function ButtonMetaFunctions:Enable()
return self.button:Enable()
end
function ButtonMetaFunctions:Disable()
return self.button:Disable()
end
-- exec
function ButtonMetaFunctions:Exec()
return self.func (self.param1, self.param2)
end
function ButtonMetaFunctions:Click()
return self.func (self.param1, self.param2)
end
function ButtonMetaFunctions:RightClick()
return self.funcright()
end
--> hooks
function ButtonMetaFunctions:SetHook (hookType, func)
if (func) then
_rawset (self, hookType.."Hook", func)
else
_rawset (self, hookType.."Hook", nil)
end
end
--> custom textures
function ButtonMetaFunctions:InstallCustomTexture (texture, rect)
self.button:SetNormalTexture (nil)
self.button:SetPushedTexture (nil)
self.button:SetDisabledTexture (nil)
self.button:SetHighlightTexture (nil)
texture = texture or "Interface\\AddOns\\Details\\images\\default_button"
self.button.texture = self.button:CreateTexture (nil, "background")
if (not rect) then
self.button.texture:SetAllPoints (self.button)
else
self.button.texture:SetPoint ("topleft", self.button, "topleft", rect.x1, rect.y1)
self.button.texture:SetPoint ("bottomright", self.button, "bottomright", rect.x2, rect.y2)
end
self.button.texture:SetTexCoord (0, 1, 0, 0.24609375)
self.button.texture:SetTexture (texture)
end
------------------------------------------------------------------------------------------------------------
--> scripts
local OnEnter = function (button)
if (button.MyObject.OnEnterHook) then
local interrupt = button.MyObject.OnEnterHook (button)
if (interrupt) then
return
end
end
if (button.texture) then
button.texture:SetTexCoord (0, 1, 0.25+(0.0078125/2), 0.5+(0.0078125/2))
end
if (button.MyObject.have_tooltip) then
GameCooltip:Reset()
GameCooltip:AddLine (button.MyObject.have_tooltip)
GameCooltip:ShowCooltip (button, "tooltip")
end
local parent = button:GetParent().MyObject
if (parent and parent.type == "panel") then
if (parent.GradientEnabled) then
parent:RunGradient()
end
end
end
local OnLeave = function (button)
if (button.MyObject.OnLeaveHook) then
local interrupt = button.MyObject.OnLeaveHook (button)
if (interrupt) then
return
end
end
if (button.texture) then
button.texture:SetTexCoord (0, 1, 0, 0.24609375)
end
if (button.MyObject.have_tooltip) then
_detalhes.popup:ShowMe (false)
end
local parent = button:GetParent().MyObject
if (parent and parent.type == "panel") then
if (parent.GradientEnabled) then
parent:RunGradient (false)
end
end
end
local OnHide = function (button)
if (button.MyObject.OnHideHook) then
local interrupt = button.MyObject.OnHideHook (button)
if (interrupt) then
return
end
end
end
local OnShow = function (button)
if (button.MyObject.OnShowHook) then
local interrupt = button.MyObject.OnShowHook (button)
if (interrupt) then
return
end
end
end
local OnMouseDown = function (button, buttontype)
if (not button:IsEnabled()) then
return
end
if (button.MyObject.OnMouseDownHook) then
local interrupt = button.MyObject.OnMouseDownHook (button, buttontype)
if (interrupt) then
return
end
end
button.text:SetPoint ("center", button,"center", 1, -1)
button.mouse_down = GetTime()
local x, y = GetCursorPosition()
button.x = _math_floor (x)
button.y = _math_floor (y)
if (not button.MyObject.container.isLocked and button.MyObject.container:IsMovable()) then
if (not button.isLocked and button:IsMovable()) then
button.MyObject.container.isMoving = true
button.MyObject.container:StartMoving()
end
end
if (button.MyObject.options.OnGrab) then
if (_type (button.MyObject.options.OnGrab) == "string" and button.MyObject.options.OnGrab == "PassClick") then
if (buttontype == "LeftButton") then
button.MyObject.func (button.MyObject.param1, button.MyObject.param2)
else
button.MyObject.funcright (button.MyObject.param1, button.MyObject.param2)
end
end
end
end
local OnMouseUp = function (button, buttontype)
if (not button:IsEnabled()) then
return
end
if (button.MyObject.OnMouseUpHook) then
local interrupt = button.MyObject.OnMouseUpHook (button, buttontype)
if (interrupt) then
return
end
end
button.text:SetPoint ("center", button,"center", 0, 0)
if (button.MyObject.container.isMoving) then
button.MyObject.container:StopMovingOrSizing()
button.MyObject.container.isMoving = false
end
local x, y = GetCursorPosition()
x = _math_floor (x)
y = _math_floor (y)
if ((button.mouse_down+0.4 > GetTime() and (x == button.x and y == button.y)) or (x == button.x and y == button.y)) then
if (buttontype == "LeftButton") then
button.MyObject.func (button.MyObject.param1, button.MyObject.param2, button)
else
button.MyObject.funcright (button.MyObject.param1, button.MyObject.param2, button)
end
end
end
------------------------------------------------------------------------------------------------------------
--> object constructor
function gump:NewButton (parent, container, name, member, w, h, func, param1, param2, texture, text)
if (not name) then
return nil
elseif (not parent) then
return nil
end
if (not container) then
container = parent
end
if (name:find ("$parent")) then
name = name:gsub ("$parent", parent:GetName())
end
local ButtonObject = {type = "button", dframework = true}
if (member) then
parent [member] = ButtonObject
end
if (parent.dframework) then
parent = parent.widget
end
if (container.dframework) then
container = container.widget
end
--> default members:
--> hooks
ButtonObject.OnEnterHook = nil
ButtonObject.OnLeaveHook = nil
ButtonObject.OnHideHook = nil
ButtonObject.OnShowHook = nil
ButtonObject.OnMouseDownHook = nil
ButtonObject.OnMouseUpHook = nil
--> misc
ButtonObject.is_locked = true
ButtonObject.container = container
ButtonObject.have_tooltip = nil
ButtonObject.options = {OnGrab = false}
ButtonObject.button = CreateFrame ("button", name, parent, "DetailsButtonTemplate")
ButtonObject.widget = ButtonObject.button
if (not APIButtonFunctions) then
APIButtonFunctions = true
local idx = getmetatable (ButtonObject.button).__index
for funcName, funcAddress in pairs (idx) do
if (not ButtonMetaFunctions [funcName]) then
ButtonMetaFunctions [funcName] = function (object, ...)
local x = loadstring ( "return _G."..object.button:GetName()..":"..funcName.."(...)")
return x (...)
end
end
end
end
ButtonObject.button:SetWidth (w or 100)
ButtonObject.button:SetHeight (h or 20)
ButtonObject.button.MyObject = ButtonObject
ButtonObject.text_overlay = _G [name .. "_Text"]
ButtonObject.disabled_overlay = _G [name .. "_TextureDisabled"]
ButtonObject.button:SetNormalTexture (texture)
ButtonObject.button:SetPushedTexture (texture)
ButtonObject.button:SetDisabledTexture (texture)
ButtonObject.button:SetHighlightTexture (texture, "ADD")
ButtonObject.button.text:SetText (text)
ButtonObject.func = func or cleanfunction
ButtonObject.funcright = cleanfunction
ButtonObject.param1 = param1
ButtonObject.param2 = param2
--> hooks
ButtonObject.button:SetScript ("OnEnter", OnEnter)
ButtonObject.button:SetScript ("OnLeave", OnLeave)
ButtonObject.button:SetScript ("OnHide", OnHide)
ButtonObject.button:SetScript ("OnShow", OnShow)
ButtonObject.button:SetScript ("OnMouseDown", OnMouseDown)
ButtonObject.button:SetScript ("OnMouseUp", OnMouseUp)
_setmetatable (ButtonObject, ButtonMetaFunctions)
return ButtonObject
end
+40
View File
@@ -0,0 +1,40 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/ .. \FrameXML\UI.xsd">
<Script file="button.lua"/>
<Button name="DetailsButtonTemplate" virtual="true">
<Size x="100" y="20"/>
<Layers>
<Layer level="ARTWORK">
<!-- text -->
<FontString name="$parent_Text" parentKey="text" inherits="GameFontNormal" justifyH="CENTER" nonspacewrap="false">
<FontHeight val="10.5"/>
<Anchors>
<Anchor point="CENTER" relativeTo="$parent" relativePoint="CENTER" x="0" y="0"/>
</Anchors>
</FontString>
</Layer>
<Layer level="OVERLAY">
<Texture name="$parent_TextureDisabled" setAllPoints="true" hidden="true" parentKey="texture_disabled" file = "Interface\AddOns\Details\images\button_disable_overlay"/>
</Layer>
</Layers>
<Scripts>
<OnDisable>
self.texture_disabled:Show()
</OnDisable>
<OnEnable>
self.texture_disabled:Hide()
</OnEnable>
</Scripts>
</Button>
</Ui>
+150
View File
@@ -0,0 +1,150 @@
do
local _detalhes = _G._detalhes
local gump = _detalhes.gump
gump.alias_text_colors = {
["aliceblue"] = {0.941176, 0.972549, 1, 1},
["antiquewhite"] = {0.980392, 0.921569, 0.843137, 1},
["aqua"] = {0, 1, 1, 1},
["aquamarine"] = {0.498039, 1, 0.831373, 1},
["azure"] = {0.941176, 1, 1, 1},
["beige"] = {0.960784, 0.960784, 0.862745, 1},
["bisque"] = {1, 0.894118, 0.768627, 1},
["black"] = {0, 0, 0, 1},
["blanchedalmond"] = {1, 0.921569, 0.803922, 1},
["blue"] = {0, 0, 1, 1},
["blueviolet"] = {0.541176, 0.168627, 0.886275, 1},
["brown"] = {0.647059, 0.164706, 0.164706, 1},
["burlywood"] = {0.870588, 0.721569, 0.529412, 1},
["cadetblue"] = {0.372549, 0.619608, 0.627451, 1},
["chartreuse"] = {0.498039, 1, 0, 1},
["chocolate"] = {0.823529, 0.411765, 0.117647, 1},
["coral"] = {1, 0.498039, 0.313725, 1},
["cornflowerblue"] = {0.392157, 0.584314, 0.929412, 1},
["cornsilk"] = {1, 0.972549, 0.862745, 1},
["crimson"] = {0.862745, 0.0784314, 0.235294, 1},
["cyan"] = {0, 1, 1, 1},
["darkblue"] = {0, 0, 0.545098, 1},
["darkcyan"] = {0, 0.545098, 0.545098, 1},
["darkgoldenrod"] = {0.721569, 0.52549, 0.0431373, 1},
["darkgray"] = {0.662745, 0.662745, 0.662745, 1},
["darkgreen"] = {0, 0.392157, 0, 1},
["darkkhaki"] = {0.741176, 0.717647, 0.419608, 1},
["darkmagenta"] = {0.545098, 0, 0.545098, 1},
["darkolivegreen"] = {0.333333, 0.419608, 0.184314, 1},
["darkorange"] = {1, 0.54902, 0, 1},
["darkorchid"] = {0.6, 0.196078, 0.8, 1},
["darkred"] = {0.545098, 0, 0, 1},
["darksalmon"] = {0.913725, 0.588235, 0.478431, 1},
["darkseagreen"] = {0.560784, 0.737255, 0.560784, 1},
["darkslateblue"] = {0.282353, 0.239216, 0.545098, 1},
["darkslategray"] = {0.184314, 0.309804, 0.309804, 1},
["darkturquoise"] = {0, 0.807843, 0.819608, 1},
["darkviolet"] = {0.580392, 0, 0.827451, 1},
["deeppink"] = {1, 0.0784314, 0.576471, 1},
["deepskyblue"] = {0, 0.74902, 1, 1},
["dimgray"] = {0.411765, 0.411765, 0.411765, 1},
["dimgrey"] = {0.411765, 0.411765, 0.411765, 1},
["dodgerblue"] = {0.117647, 0.564706, 1, 1},
["firebrick"] = {0.698039, 0.133333, 0.133333, 1},
["floralwhite"] = {1, 0.980392, 0.941176, 1},
["forestgreen"] = {0.133333, 0.545098, 0.133333, 1},
["fuchsia"] = {1, 0, 1, 1},
["gainsboro"] = {0.862745, 0.862745, 0.862745, 1},
["ghostwhite"] = {0.972549, 0.972549, 1, 1},
["gold"] = {1, 0.843137, 0, 1},
["goldenrod"] = {0.854902, 0.647059, 0.12549, 1},
["gray"] = {0.501961, 0.501961, 0.501961, 1},
["green"] = {0, 0.501961, 0, 1},
["greenyellow"] = {0.678431, 1, 0.184314, 1},
["honeydew"] = {0.941176, 1, 0.941176, 1},
["hotpink"] = {1, 0.411765, 0.705882, 1},
["indianred"] = {0.803922, 0.360784, 0.360784, 1},
["indigo"] = {0.294118, 0, 0.509804, 1},
["ivory"] = {1, 1, 0.941176, 1},
["khaki"] = {0.941176, 0.901961, 0.54902, 1},
["lavender"] = {0.901961, 0.901961, 0.980392, 1},
["lavenderblush"] = {1, 0.941176, 0.960784, 1},
["lawngreen"] = {0.486275, 0.988235, 0, 1},
["lemonchiffon"] = {1, 0.980392, 0.803922, 1},
["lightblue"] = {0.678431, 0.847059, 0.901961, 1},
["lightcoral"] = {0.941176, 0.501961, 0.501961, 1},
["lightcyan"] = {0.878431, 1, 1, 1},
["lightgoldenrodyellow"] = {0.980392, 0.980392, 0.823529, 1},
["lightgray"] = {0.827451, 0.827451, 0.827451, 1},
["lightgreen"] = {0.564706, 0.933333, 0.564706, 1},
["lightpink"] = {1, 0.713725, 0.756863, 1},
["lightsalmon"] = {1, 0.627451, 0.478431, 1},
["lightseagreen"] = {0.12549, 0.698039, 0.666667, 1},
["lightskyblue"] = {0.529412, 0.807843, 0.980392, 1},
["lightslategray"] = {0.466667, 0.533333, 0.6, 1},
["lightsteelblue"] = {0.690196, 0.768627, 0.870588, 1},
["lightyellow"] = {1, 1, 0.878431, 1},
["lime"] = {0, 1, 0, 1},
["limegreen"] = {0.196078, 0.803922, 0.196078, 1},
["linen"] = {0.980392, 0.941176, 0.901961, 1},
["magenta"] = {1, 0, 1, 1},
["maroon"] = {0.501961, 0, 0, 1},
["mediumaquamarine"] = {0.4, 0.803922, 0.666667, 1},
["mediumblue"] = {0, 0, 0.803922, 1},
["mediumorchid"] = {0.729412, 0.333333, 0.827451, 1},
["mediumpurple"] = {0.576471, 0.439216, 0.858824, 1},
["mediumseagreen"] = {0.235294, 0.701961, 0.443137, 1},
["mediumslateblue"] = {0.482353, 0.407843, 0.933333, 1},
["mediumspringgreen"] = {0, 0.980392, 0.603922, 1},
["mediumturquoise"] = {0.282353, 0.819608, 0.8, 1},
["mediumvioletred"] = {0.780392, 0.0823529, 0.521569, 1},
["midnightblue"] = {0.0980392, 0.0980392, 0.439216, 1},
["mintcream"] = {0.960784, 1, 0.980392, 1},
["mistyrose"] = {1, 0.894118, 0.882353, 1},
["moccasin"] = {1, 0.894118, 0.709804, 1},
["navajowhite"] = {1, 0.870588, 0.678431, 1},
["navy"] = {0, 0, 0.501961, 1},
["none"] ={0, 0, 0, 0},
["oldlace"] = {0.992157, 0.960784, 0.901961, 1},
["olive"] = {0.501961, 0.501961, 0, 1},
["olivedrab"] = {0.419608, 0.556863, 0.137255, 1},
["orange"] = {1, 0.647059, 0, 1},
["orangered"] = {1, 0.270588, 0, 1},
["orchid"] = {0.854902, 0.439216, 0.839216, 1},
["palegoldenrod"] = {0.933333, 0.909804, 0.666667, 1},
["palegreen"] = {0.596078, 0.984314, 0.596078, 1},
["paleturquoise"] = {0.686275, 0.933333, 0.933333, 1},
["palevioletred"] = {0.858824, 0.439216, 0.576471, 1},
["papayawhip"] = {1, 0.937255, 0.835294, 1},
["peachpuff"] = {1, 0.854902, 0.72549, 1},
["peru"] = {0.803922, 0.521569, 0.247059, 1},
["pink"] = {1, 0.752941, 0.796078, 1},
["plum"] = {0.866667, 0.627451, 0.866667, 1},
["powderblue"] = {0.690196, 0.878431, 0.901961, 1},
["purple"] = {0.501961, 0, 0.501961, 1},
["red"] = {1, 0, 0, 1},
["rosybrown"] = {0.737255, 0.560784, 0.560784, 1},
["royalblue"] = {0.254902, 0.411765, 0.882353, 1},
["saddlebrown"] = {0.545098, 0.270588, 0.0745098, 1},
["salmon"] = {0.980392, 0.501961, 0.447059, 1},
["sandybrown"] = {0.956863, 0.643137, 0.376471, 1},
["seagreen"] = {0.180392, 0.545098, 0.341176, 1},
["seashell"] = {1, 0.960784, 0.933333, 1},
["sienna"] = {0.627451, 0.321569, 0.176471, 1},
["silver"] = {0.752941, 0.752941, 0.752941, 1},
["skyblue"] = {0.529412, 0.807843, 0.921569, 1},
["slateblue"] = {0.415686, 0.352941, 0.803922, 1},
["slategray"] = {0.439216, 0.501961, 0.564706, 1},
["snow"] = {1, 0.980392, 0.980392, 1},
["springgreen"] = {0, 1, 0.498039, 1},
["steelblue"] = {0.27451, 0.509804, 0.705882, 1},
["tan"] = {0.823529, 0.705882, 0.54902, 1},
["teal"] = {0, 0.501961, 0.501961, 1},
["thistle"] = {0.847059, 0.74902, 0.847059, 1},
["tomato"] = {1, 0.388235, 0.278431, 1},
["transparent"] ={0, 0, 0, 0},
["turquoise"] = {0.25098, 0.878431, 0.815686, 1},
["violet"] = {0.933333, 0.509804, 0.933333, 1},
["wheat"] = {0.960784, 0.870588, 0.701961, 1},
["white"] = {1, 1, 1, 1},
["whitesmoke"] = {0.960784, 0.960784, 0.960784, 1},
["yellow"] = {1, 1, 0, 1},
["yellowgreen"] = {0.603922, 0.803922, 0.196078, 1}
}
end
File diff suppressed because it is too large Load Diff
+194
View File
@@ -0,0 +1,194 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/ .. \FrameXML\UI.xsd">
<Script file="cooltip.lua"/>
<Frame name="CooltipMainFrameTemplate" virtual="true" frameStrata="TOOLTIP">
<Size x="1" y="1"/>
<Anchors>
<Anchor point="CENTER" relativeTo="$parent" relativePoint="CENTER" x="0" y="0"/>
</Anchors>
<Backdrop bgFile="Interface\DialogFrame\UI-DialogBox-Background-Dark" edgeFile="Interface\Tooltips\UI-Tooltip-Border" tile="true">
<EdgeSize>
<AbsValue val="16"/>
</EdgeSize>
<TileSize>
<AbsValue val="16"/>
</TileSize>
<BackgroundInsets>
<AbsInset left="5" right="5" top="5" bottom="5"/>
</BackgroundInsets>
</Backdrop>
<Scripts>
<OnLoad>
self:SetBackdropColor (0.09019, 0.09019, 0.18823, 1)
self:SetBackdropBorderColor (1, 1, 1, 1)
</OnLoad>
</Scripts>
<Layers>
<Layer level="BORDER">
<!-- frame background -->
<Texture name="$parent_FrameBackground" parentKey="framebackground" file = "Interface\AddOns\Details\images\cooltip_selected">
<Color a = "1" r = "0" g = "1" b = "0" />
<Anchors>
<Anchor point="TOP" relativeTo="$parent" relativePoint="TOP" x="0" y="-5"/>
<Anchor point="BOTTOM" relativeTo="$parent" relativePoint="BOTTOM" x="0" y="5"/>
<Anchor point="LEFT" relativeTo="$parent" relativePoint="LEFT" x="3" y="0"/>
<Anchor point="RIGHT" relativeTo="$parent" relativePoint="RIGHT" x="-3" y="0"/>
</Anchors>
</Texture>
</Layer>
<Layer level="ARTWORK">
<!-- selected bar -->
<Texture name="$parent_Selected" parentKey="selected" file = "Interface\AddOns\Details\images\cooltip_selected">
<Size y="20"/>
<Anchors>
<Anchor point="LEFT" relativeTo="$parent" relativePoint="LEFT" x="3" y="0"/>
<Anchor point="RIGHT" relativeTo="$parent" relativePoint="RIGHT" x="-3" y="0"/>
</Anchors>
</Texture>
</Layer>
<Layer level="OVERLAY">
<!-- title icon -->
<Texture name="$parent_TitleIcon" hidden="true" parentKey="titleIcon" file = "Interface\AddOns\Details\images\cooltip_selected">
<Anchors>
<Anchor point="TOP" relativeTo="$parent" relativePoint="TOP" x="0" y="0"/>
<Anchor point="LEFT" relativeTo="$parent" relativePoint="LEFT" x="0" y="0"/>
</Anchors>
</Texture>
<!-- title text -->
<FontString name="$parent_TitleText" parentKey="titleText" inherits="GameFontHighlightSmall" justifyH="LEFT" nonspacewrap="true">
<FontHeight val="10.5"/>
<Anchors>
<Anchor point="LEFT" relativeTo="$parent_Selected" relativePoint="RIGHT" x="0" y="0"/>
</Anchors>
</FontString>
</Layer>
</Layers>
</Frame>
<Button name="CooltipButtonTemplate" virtual="true">
<Size x="1" y="20"/>
<Frames>
<StatusBar name="$Parent_StatusBar" parentKey="statusbar">
<Anchors>
<Anchor point="LEFT" relativeTo="$parent" relativePoint="LEFT" x="10" y="0"/>
<Anchor point="RIGHT" relativeTo="$parent" relativePoint="RIGHT" x="-10" y="0"/>
<Anchor point="TOP" relativeTo="$parent" relativePoint="TOP" x="0" y="0"/>
<Anchor point="BOTTOM" relativeTo="$parent" relativePoint="BOTTOM" x="0" y="0"/>
</Anchors>
<Size y="20" />
<Layers>
<Layer level="BACKGROUND">
<!-- statusbar texture -->
<Texture name="$parent_Texture" hidden="false" parentKey="texture" file = "Interface\PaperDollInfoFrame\UI-Character-Skills-Bar" horizTile="false" vertTile="false">
<Size x="300" y="14" />
<Color a = "1" r = "1" g = "1" b = "1" />
</Texture>
<!-- spark -->
<Texture name="$parent_Spark" hidden="true" parentKey="spark" file = "Interface\AddOns\Details\images\bar_detalhes2_end">
<Size>
<AbsDimension x="8" y="18"/>
</Size>
<Anchors>
<Anchor point="LEFT" relativeTo="$parent" relativePoint="RIGHT" x="-16" y="-1"/>
</Anchors>
</Texture>
</Layer>
<Layer level="ARTWORK">
<!-- background texture -->
<Texture name="$parent_Background" hidden="true" parentKey="background" file = "Interface\FriendsFrame\UI-FriendsFrame-HighlightBar" horizTile="false" vertTile="false">
<Anchors>
<Anchor point="LEFT" relativeTo="$parent" relativePoint="LEFT" x="-6" y="0"/>
<Anchor point="RIGHT" relativeTo="$parent" relativePoint="RIGHT" x="6" y="0"/>
<Anchor point="TOP" relativeTo="$parent" relativePoint="TOP" x="0" y="0"/>
<Anchor point="BOTTOM" relativeTo="$parent" relativePoint="BOTTOM" x="0" y="0"/>
</Anchors>
</Texture>
</Layer>
<Layer level="OVERLAY">
<!-- left icon texture -->
<Texture name="$parent_LeftIcon" parentKey="leftIcon">
<Size x="16" y="16" />
<Anchors>
<Anchor point="LEFT" relativeTo="$parent" relativePoint="LEFT" x="0" y="0"/>
</Anchors>
</Texture>
<!-- right icon texture -->
<Texture name="$parent_RightIcon" parentKey="rightIcon">
<Size x="16" y="16" />
<Anchors>
<Anchor point="RIGHT" relativeTo="$parent" relativePoint="RIGHT" x="0" y="0"/>
</Anchors>
</Texture>
<!-- left text -->
<FontString name="$parent_LeftText" parentKey="leftText" inherits="GameFontHighlight" justifyH="LEFT" nonspacewrap="false">
<FontHeight val="10.5"/>
<Anchors>
<Anchor point="CENTER" relativeTo="$parent_LeftIcon" relativePoint="CENTER" x="0" y="0"/>
<Anchor point="LEFT" relativeTo="$parent_LeftIcon" relativePoint="RIGHT" x="3" y="0"/>
</Anchors>
</FontString>
<!-- right text -->
<FontString name="$parent_TextRight" parentKey="rightText" inherits="GameFontHighlight" justifyH="RIGHT" nonspacewrap="false">
<FontHeight val="10.5"/>
<Anchors>
<Anchor point="CENTER" relativeTo="$parent_RightIcon" relativePoint="CENTER" x="0" y="0"/>
<Anchor point="RIGHT" relativeTo="$parent_RightIcon" relativePoint="LEFT" x="-3" y="0"/>
</Anchors>
</FontString>
</Layer>
</Layers>
<Scripts>
<OnLoad>
self:SetStatusBarTexture (self.texture);
<!-- note to my self, never forget statusbar MinMaxValues -->
self:SetMinMaxValues (0, 100);
self:GetParent().background = self.background
</OnLoad>
</Scripts>
</StatusBar>
</Frames>
<Scripts>
<OnLoad>
self:RegisterForClicks ("LeftButtonDown")
self.leftIcon = self.statusbar.leftIcon
self.rightIcon = self.statusbar.rightIcon
self.texture = self.statusbar.texture
self.spark = self.statusbar.spark
self.leftText = self.statusbar.leftText
self.rightText = self.statusbar.rightText
</OnLoad>
<OnMouseDown>
GameCooltipButtonMouseDown (self);
</OnMouseDown>
<OnMouseUp>
GameCooltipButtonMouseUp (self);
</OnMouseUp>
</Scripts>
</Button>
</Ui>
+770
View File
@@ -0,0 +1,770 @@
--> details main objects
local _detalhes = _G._detalhes
local gump = _detalhes.gump
local _rawset = rawset --> lua local
local _rawget = rawget --> lua local
local _setmetatable = setmetatable --> lua local
local _unpack = unpack --> lua local
local _type = type --> lua local
local _math_floor = math.floor --> lua local
local loadstring = loadstring --> lua local
local _string_len = string.len --> lua local
local cleanfunction = function() end
local APIDropDownFunctions = false
local DropDownMetaFunctions = {}
------------------------------------------------------------------------------------------------------------
--> metatables
DropDownMetaFunctions.__call = function (_table, value)
--> unknow
end
------------------------------------------------------------------------------------------------------------
--> members
--> selected value
local gmember_value = function (_object)
return _object:GetValue()
end
--> tooltip
local gmember_tooltip = function (_object)
return _object:GetTooltip()
end
--> shown
local gmember_shown = function (_object)
return _object:IsShown()
end
--> frame width
local gmember_width = function (_object)
return _object.button:GetWidth()
end
--> frame height
local gmember_height = function (_object)
return _object.button:GetHeight()
end
--> current text
local gmember_text = function (_object)
return _object.label:GetText()
end
--> menu creation function
local gmember_function = function (_object)
return _object:GetFunction()
end
--> menu width
local gmember_menuwidth = function (_object)
return _rawget (self, "realsizeW")
end
--> menu height
local gmember_menuheight = function (_object)
return _rawget (self, "realsizeH")
end
local get_members_function_index = {
["value"] = gmember_value,
["text"] = gmember_text,
["shown"] = gmember_shown,
["width"] = gmember_width,
["menuwidth"] = gmember_menuwidth,
["height"] = gmember_height,
["menuheight"] = gmember_menuheight,
["tooltip"] = gmember_tooltip,
["func"] = gmember_function,
}
DropDownMetaFunctions.__index = function (_table, _member_requested)
local func = get_members_function_index [_member_requested]
if (func) then
return func (_table, _member_requested)
end
local fromMe = _rawget (_table, _member_requested)
if (fromMe) then
return fromMe
end
return DropDownMetaFunctions [_member_requested]
end
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> tooltip
local smember_tooltip = function (_object, _value)
return _object:SetTooltip (_value)
end
--> show
local smember_show = function (_object, _value)
if (_value) then
return _object:Show()
else
return _object:Hide()
end
end
--> hide
local smember_hide = function (_object, _value)
if (not _value) then
return _object:Show()
else
return _object:Hide()
end
end
--> frame width
local smember_width = function (_object, _value)
return _object.dropdown:SetWidth (_value)
end
--> frame height
local smember_height = function (_object, _value)
return _object.dropdown:SetHeight (_value)
end
--> menu creation function
local smember_function = function (_object, _value)
return _object:SetFunction (_value)
end
--> menu width
local smember_menuwidth = function (_object, _value)
_object:SetMenuSize (_value, nil)
end
--> menu height
local smember_menuheight = function (_object, _value)
_object:SetMenuSize (nil, _value)
end
local set_members_function_index = {
["tooltip"] = smember_tooltip,
["show"] = smember_show,
["hide"] = smember_hide,
["width"] = smember_width,
["menuwidth"] = smember_menuwidth,
["height"] = smember_height,
["menuheight"] = smember_menuheight,
["func"] = smember_function,
}
DropDownMetaFunctions.__newindex = function (_table, _key, _value)
local func = set_members_function_index [_key]
if (func) then
return func (_table, _value)
else
return _rawset (_table, _key, _value)
end
end
------------------------------------------------------------------------------------------------------------
--> methods
function DropDownMetaFunctions:IsShown()
return self.dropdown:IsShown()
end
function DropDownMetaFunctions:Show()
return self.dropdown:Show()
end
function DropDownMetaFunctions:Hide()
return self.dropdown:Hide()
end
--> menu width and height
function DropDownMetaFunctions:SetMenuSize (w, h)
if (w) then
return _rawset (self, "realsizeW", w)
end
if (h) then
return _rawset (self, "realsizeH", h)
end
end
function DropDownMetaFunctions:GetMenuSize()
return _rawget (self, "realsizeW"), _rawget (self, "realsizeH")
end
--> function
function DropDownMetaFunctions:SetFunction (func)
return _rawset (self, "func", func)
end
function DropDownMetaFunctions:GetFunction()
return _rawget (self, "func")
end
--> value
function DropDownMetaFunctions:GetValue()
return _rawget (self, "myvalue")
end
function DropDownMetaFunctions:SetValue (value)
return _rawset (self, "myvalue", value)
end
--> setpoint
function DropDownMetaFunctions:SetPoint (v1, v2, v3, v4, v5)
v1, v2, v3, v4, v5 = gump:CheckPoints (v1, v2, v3, v4, v5, self)
if (not v1) then
print ("Invalid parameter for SetPoint")
return
end
return self.widget:SetPoint (v1, v2, v3, v4, v5)
end
--> sizes
function DropDownMetaFunctions:SetSize (w, h)
if (w) then
self.dropdown:SetWidth (w)
end
if (h) then
return self.dropdown:SetHeight (h)
end
end
--> tooltip
function DropDownMetaFunctions:SetTooltip (tooltip)
if (tooltip) then
return _rawset (self, "have_tooltip", tooltip)
else
return _rawset (self, "have_tooltip", nil)
end
end
function DropDownMetaFunctions:GetTooltip()
return _rawget (self, "have_tooltip")
end
--> frame levels
function DropDownMetaFunctions:GetFrameLevel()
return self.dropdown:GetFrameLevel()
end
function DropDownMetaFunctions:SetFrameLevel (level, frame)
if (not frame) then
return self.dropdown:SetFrameLevel (level)
else
local framelevel = frame:GetFrameLevel (frame) + level
return self.dropdown:SetFrameLevel (framelevel)
end
end
--> frame stratas
function DropDownMetaFunctions:SetFrameStrata()
return self.dropdown:GetFrameStrata()
end
function DropDownMetaFunctions:SetFrameStrata (strata)
if (_type (strata) == "table") then
self.dropdown:SetFrameStrata (strata:GetFrameStrata())
else
self.dropdown:SetFrameStrata (strata)
end
end
--> enabled
function DropDownMetaFunctions:IsEnabled()
return self.dropdown:IsEnabled()
end
function DropDownMetaFunctions:Enable()
return self.dropdown:Enable()
end
function DropDownMetaFunctions:Disable()
return self.dropdown:Disable()
end
--> fixed value
function DropDownMetaFunctions:SetFixedParameter (value)
_rawset (self, "FixedValue", value)
end
--> hooks
function DropDownMetaFunctions:SetHook (hookType, func)
if (func) then
_rawset (self, hookType.."Hook", func)
else
_rawset (self, hookType.."Hook", nil)
end
end
------------------------------------------------------------------------------------------------------------
--> scripts
local function isOptionVisible (thisOption)
if (_type (thisOption.shown) == "boolean" or _type (thisOption.shown) == "function") then
if (not thisOption.shown) then
return false
elseif (not thisOption.shown()) then
return false
end
end
return true
end
function DropDownMetaFunctions:Select (optionName, byOptionNumber)
local menu = self.func()
if (byOptionNumber and type (optionName) == "number") then
return self:Selected (menu [optionName])
end
for _, thisMenu in ipairs (menu) do
if (thisMenu.label == optionName and isOptionVisible (thisMenu)) then
return self:Selected (thisMenu)
end
end
end
function DropDownMetaFunctions:Selected (_table)
self.label:SetText (_table.label)
self.icon:SetTexture (_table.icon)
if (_table.icon) then
self.label:SetPoint ("left", self.icon, "right", 2, 0)
if (_table.texcoord) then
self.icon:SetTexCoord (unpack (_table.texcoord))
else
self.icon:SetTexCoord (0, 1, 0, 1)
end
else
self.label:SetPoint ("left", self.label:GetParent(), "left", 4, 0)
end
self.statusbar:SetTexture (_table.statusbar)
if (_table.color) then
local _value1, _value2, _value3, _value4 = gump:ParseColors (_table.color)
self.label:SetTextColor (_value1, _value2, _value3, _value4)
else
self.label:SetTextColor (1, 1, 1, 1)
end
if (_table.font) then
self.label:SetFont (_table.font, 10.5)
else
self.label:SetFont ("GameFontHighlightSmall", 10.5)
end
self:SetValue (_table.value)
end
function DetailsDropDownOptionClick (button)
--> update name and icon on main frame
button.object:Selected (button.table)
--> close menu frame
button.object:Close()
--> exec function if any
if (button.table.onclick) then
button.table.onclick (button:GetParent():GetParent():GetParent().MyObject, button.object.FixedValue, button.table.value)
end
--> set the value of selected option in main object
button.object.myvalue = button.table.value
end
function DropDownMetaFunctions:Open()
self.dropdown.dropdownframe:Show()
self.dropdown.dropdownborder:Show()
self.dropdown.arrowTexture:SetTexture ("Interface\\Buttons\\UI-ScrollBar-ScrollDownButton-Down")
self.opened = true
end
function DropDownMetaFunctions:Close()
--> when menu is being close, just hide the border and the script will call back this again
if (self.dropdown.dropdownborder:IsShown()) then
self.dropdown.dropdownborder:Hide()
return
end
self.dropdown.dropdownframe:Hide()
self.dropdown.arrowTexture:SetTexture ("Interface\\Buttons\\UI-ScrollBar-ScrollDownButton-Up")
local selectedTexture = _G [self:GetName() .. "_ScrollFrame_ScrollChild_SelectedTexture"]
selectedTexture:Hide()
self.opened = false
end
--> close by escape key
function DetailsDropDownOptionsFrameOnHide (frame)
frame:GetParent().MyObject:Close()
end
function DetailsDropDownOptionOnEnter (frame)
if (frame.table.desc) then
GameCooltip:Reset()
GameCooltip:SetType ("tooltip")
GameCooltip:SetColor ("main", "transparent")
GameCooltip:AddLine (frame.table.desc)
GameCooltip:SetOwner (frame:GetParent():GetParent():GetParent())
GameCooltip:ShowCooltip()
frame.tooltip = true
end
frame:GetParent().mouseover:SetPoint ("left", frame)
frame:GetParent().mouseover:Show()
end
function DetailsDropDownOptionOnLeave (frame)
if (frame.table.desc) then
_detalhes.popup:ShowMe (false)
end
frame:GetParent().mouseover:Hide()
end
function DetailsDropDownOnMouseDown (button)
local object = button.MyObject
if (not object.opened) then --> click to open
local menu = object:func()
local frame_witdh = object.realsizeW
if (menu [1]) then
--> build menu
local scrollFrame = _G [button:GetName() .. "_ScrollFrame"]
local scrollChild = _G [button:GetName() .. "_ScrollFrame_ScrollChild"]
local scrollBorder = _G [button:GetName() .. "_Border"]
local selectedTexture = _G [button:GetName() .. "_ScrollFrame_ScrollChild_SelectedTexture"]
local mouseOverTexture = _G [button:GetName() .. "_ScrollFrame_ScrollChild_MouseOverTexture"]
local i = 1
local showing = 0
local currentText = button.text:GetText() or ""
if (object.OnMouseDownHook) then
local interrupt = object.OnMouseDownHook (button, buttontype, menu, scrollFrame, scrollChild, selectedTexture)
if (interrupt) then
return
end
end
for _, _table in ipairs (menu) do
local show = isOptionVisible (_table)
if (show) then
local _this_row = object.menus [i]
showing = showing + 1
if (not _this_row) then
local name = button:GetName() .. "Row" .. i
local parent = scrollChild
_this_row = CreateFrame ("Button", name, parent, "DetailsDropDownOptionTemplate")
local anchor_i = i-1
_this_row:SetPoint ("topleft", parent, "topleft", 5, (-anchor_i*20)-5)
_this_row:SetPoint ("topright", parent, "topright", -5, (-anchor_i*20)-5)
_this_row.object = object
object.menus [i] = _this_row
end
_this_row.icon:SetTexture (_table.icon)
if (_table.icon) then
_this_row.label:SetPoint ("left", _this_row.icon, "right", 5, 0)
if (_table.texcoord) then
_this_row.icon:SetTexCoord (unpack (_table.texcoord))
else
_this_row.icon:SetTexCoord (0, 1, 0, 1)
end
else
_this_row.label:SetPoint ("left", _this_row.statusbar, "left", 2, 0)
end
if (_table.font) then
_this_row.label:SetFont (_table.font, 10.5)
else
_this_row.label:SetFont ("GameFontHighlightSmall", 10.5)
end
_this_row.statusbar:SetTexture (_table.statusbar)
_this_row.label:SetText (_table.label)
if (currentText and currentText == _table.label) then
if (_table.icon) then
selectedTexture:SetPoint ("left", _this_row.icon, "right", -5, -2)
else
selectedTexture:SetPoint ("left", _this_row.statusbar, "left", 0, 0)
end
selectedTexture:Show()
selectedTexture:SetVertexColor (1, 1, 1, .3);
currentText = nil
end
if (_table.color) then
local _value1, _value2, _value3, _value4 = gump:ParseColors (_table.color)
_this_row.label:SetTextColor (_value1, _value2, _value3, _value4)
else
_this_row.label:SetTextColor (1, 1, 1, 1)
end
_this_row.table = _table
local labelwitdh = _this_row.label:GetStringWidth()
if (labelwitdh+40 > frame_witdh) then
frame_witdh = labelwitdh+40
end
_this_row:Show()
i = i + 1
end
end
if (currentText) then
selectedTexture:Hide()
else
selectedTexture:SetWidth (frame_witdh-20)
end
for i = showing+1, #object.menus do
object.menus [i]:Hide()
end
local size = object.realsizeH
if (showing*20 > size) then
--show scrollbar and setup scroll
object:ShowScroll()
scrollFrame:EnableMouseWheel (true)
object.scroll:Altura (size-35)
object.scroll:SetMinMaxValues (0, (showing*20) - size + 20)
--width
scrollBorder:SetWidth (frame_witdh+20)
scrollFrame:SetWidth (frame_witdh+20)
scrollChild:SetWidth (frame_witdh+20)
--height
scrollBorder:SetHeight (size+20)
scrollFrame:SetHeight (size)
scrollChild:SetHeight ((showing*20)+20)
--mouse over texture
mouseOverTexture:SetWidth (frame_witdh-7)
for index, row in ipairs (object.menus) do
row:SetPoint ("topright", scrollChild, "topright", -22, ((-index-1)*20)-5)
end
else
--hide scrollbar and disable wheel
object:HideScroll()
scrollFrame:EnableMouseWheel (false)
--width
scrollBorder:SetWidth (frame_witdh)
scrollFrame:SetWidth (frame_witdh)
scrollChild:SetWidth (frame_witdh)
--height
scrollBorder:SetHeight ((showing*20) + 25)
scrollFrame:SetHeight ((showing*20) + 25)
--mouse over texture
mouseOverTexture:SetWidth (frame_witdh-10)
for index, row in ipairs (object.menus) do
row:SetPoint ("topright", scrollChild, "topright", -5, ((-index-1)*20)-5)
end
end
object:Open()
else
--> clear menu
end
else --> click to close
object:Close()
end
end
function DetailsDropDownOnEnter (self)
if (self.MyObject.OnEnterHook) then
local interrupt = self.MyObject.OnEnterHook (self)
if (interrupt) then
return
end
end
self:SetBackdropColor (.2, .2, .2, .2)
self.arrowTexture2:Show()
if (self.MyObject.have_tooltip) then
GameCooltip:Reset()
GameCooltip:SetType ("tooltip")
GameCooltip:SetColor ("main", "transparent")
GameCooltip:AddLine (self.MyObject.have_tooltip)
GameCooltip:SetOwner (self)
GameCooltip:ShowCooltip()
end
local parent = self:GetParent().MyObject
if (parent and parent.type == "panel") then
if (parent.GradientEnabled) then
parent:RunGradient()
end
end
end
function DetailsDropDownOnLeave (self)
self:SetBackdropColor (1, 1, 1, .5)
self.arrowTexture2:Hide()
if (self.MyObject.OnLeaveHook) then
local interrupt = self.MyObject.OnLeaveHook (self)
if (interrupt) then
return
end
end
if (self.MyObject.have_tooltip) then
_detalhes.popup:ShowMe (false)
end
local parent = self:GetParent().MyObject
if (parent and parent.type == "panel") then
if (parent.GradientEnabled) then
parent:RunGradient (false)
end
end
end
function DetailsDropDownOnSizeChanged (self, w, h)
self.MyObject.label:SetSize (self:GetWidth()-40, 10)
end
function DetailsDropDownOnShow (self)
if (self.MyObject and self.MyObject.OnShowHook) then
local interrupt = self.MyObject.OnShowHook (self)
if (interrupt) then
return
end
end
end
function DetailsDropDownOnHide (self)
if (self.MyObject and self.MyObject.OnHideHook) then
local interrupt = self.MyObject.OnHideHook (self)
if (interrupt) then
return
end
end
self.MyObject:Close()
end
------------------------------------------------------------------------------------------------------------
--> object constructor
function gump:NewDropDown (parent, container, name, member, w, h, func, default)
if (not name) then
return nil
elseif (not parent) then
return nil
end
if (not container) then
container = parent
end
if (name:find ("$parent")) then
name = name:gsub ("$parent", parent:GetName())
end
local DropDownObject = {type = "dropdown", dframework = true}
if (member) then
parent [member] = DropDownObject
end
if (parent.dframework) then
parent = parent.widget
end
if (container.dframework) then
container = container.widget
end
default = default or 1
--> default members:
--> hooks
DropDownObject.OnEnterHook = nil
DropDownObject.OnLeaveHook = nil
DropDownObject.OnHideHook = nil
DropDownObject.OnShowHook = nil
DropDownObject.OnMouseDownHook = nil
--> misc
DropDownObject.container = container
DropDownObject.have_tooltip = nil
DropDownObject.dropdown = CreateFrame ("Button", name, parent, "DetailsDropDownTemplate")
DropDownObject.widget = DropDownObject.dropdown
--_G [name] = DropDownObject
if (not APIDropDownFunctions) then
APIDropDownFunctions = true
local idx = getmetatable (DropDownObject.dropdown).__index
for funcName, funcAddress in pairs (idx) do
if (not DropDownMetaFunctions [funcName]) then
DropDownMetaFunctions [funcName] = function (object, ...)
local x = loadstring ( "return _G."..object.dropdown:GetName()..":"..funcName.."(...)")
return x (...)
end
end
end
end
DropDownObject.dropdown.MyObject = DropDownObject
DropDownObject.dropdown:SetWidth (w)
DropDownObject.dropdown:SetHeight (h)
DropDownObject.func = func
DropDownObject.realsizeW = 150
DropDownObject.realsizeH = 150
DropDownObject.FixedValue = nil
DropDownObject.opened = false
DropDownObject.menus = {}
DropDownObject.myvalue = nil
DropDownObject.label = _G [name .. "_Text"]
DropDownObject.icon = _G [name .. "_IconTexture"]
DropDownObject.statusbar = _G [name .. "_StatusBarTexture"]
DropDownObject.select = _G [name .. "_SelectedTexture"]
local scroll = _G [DropDownObject.dropdown:GetName() .. "_ScrollFrame"]
DropDownObject.scroll = gump:NewScrollBar (scroll, _G [DropDownObject.dropdown:GetName() .. "_ScrollFrame".."_ScrollChild"], -20, -18)
function DropDownObject:HideScroll()
scroll.baixo:Hide()
scroll.cima:Hide()
scroll.slider:Hide()
end
function DropDownObject:ShowScroll()
scroll.baixo:Show()
scroll.cima:Show()
scroll.slider:Show()
end
DropDownObject:HideScroll()
DropDownObject.label:SetSize (DropDownObject.dropdown:GetWidth()-40, 10)
--> setup class
_setmetatable (DropDownObject, DropDownMetaFunctions)
--> initialize first menu selected
local menu = func()
for i = default, #menu do
local _table = menu [i]
if (not _table) then
break
end
if (isOptionVisible (_table)) then
DropDownObject:Selected (_table)
break
end
end
return DropDownObject
end
+238
View File
@@ -0,0 +1,238 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/ .. \FrameXML\UI.xsd">
<Script file="dropdown.lua"/>
<Button name="DetailsDropDownTemplate" virtual="true">
<Size x="150" y="20"/>
<Backdrop bgFile="Interface\DialogFrame\UI-DialogBox-Background" edgeFile="Interface\DialogFrame\UI-DialogBox-Border" tile="true">
<EdgeSize>
<AbsValue val="10"/>
</EdgeSize>
<TileSize>
<AbsValue val="16"/>
</TileSize>
<BackgroundInsets>
<AbsInset left="1" right="1" top="0" bottom="1"/>
</BackgroundInsets>
</Backdrop>
<Layers>
<Layer level="BACKGROUND">
<!-- statusbar texture -->
<Texture name="$parent_StatusBarTexture" parentKey="statusbar">
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$parent" relativePoint="TOPLEFT" x="3" y="-3"/>
<Anchor point="BOTTOMRIGHT" relativeTo="$parent" relativePoint="BOTTOMRIGHT" x="-3" y="3"/>
</Anchors>
</Texture>
</Layer>
<Layer level="ARTWORK">
<!-- icon texture -->
<Texture name="$parent_IconTexture" parentKey="icon" file = "Interface\ICONS\Spell_ChargePositive">
<Size x="20" y="20" />
<Anchors>
<Anchor point="LEFT" relativeTo="$parent" relativePoint="LEFT" x="2" y="0"/>
</Anchors>
</Texture>
<!-- text -->
<FontString name="$parent_Text" parentKey="text" inherits="GameFontHighlightSmall" justifyH="LEFT" nonspacewrap="true">
<FontHeight val="10.5"/>
<Anchors>
<Anchor point="LEFT" relativeTo="$parent_IconTexture" relativePoint="RIGHT" x="5" y="0"/>
</Anchors>
</FontString>
<!-- <Texture name="$parent_ArrowTextureDisabled" parentKey="textureDisabled" file = "Interface\Buttons\UI-ScrollBar-UI-ScrollBar-ScrollDownButton-Disabled">
<Size x="32" y="32" />
</Texture> -->
</Layer>
<Layer level="OVERLAY">
<Texture name="$parent_ArrowTexture2" alphaMode="ADD" parentKey="arrowTexture2" file = "Interface\Buttons\UI-ScrollBar-ScrollDownButton-Highlight" hidden="true">
<Size x="32" y="28"/>
<Anchors>
<Anchor point="RIGHT" relativeTo="$parent" relativePoint="RIGHT" x="5" y="-1"/>
</Anchors>
</Texture>
<!-- button textures -->
<Texture name="$parent_ArrowTexture" parentKey="arrowTexture" file = "Interface\Buttons\UI-ScrollBar-ScrollDownButton-Up">
<Size x="32" y="28"/>
<Anchors>
<Anchor point="RIGHT" relativeTo="$parent" relativePoint="RIGHT" x="5" y="-1"/>
</Anchors>
</Texture>
</Layer>
</Layers>
<Frames>
<Frame name="$Parent_Border" parentKey="dropdownborder" hidden="true">
<Size x="150" y="170"/>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$Parent" relativePoint="BOTTOMLEFT"/>
</Anchors>
<Backdrop bgFile="Interface\DialogFrame\UI-DialogBox-Background-Dark" edgeFile="Interface\Buttons\UI-SliderBar-Border" tile="true">
<EdgeSize>
<AbsValue val="10"/>
</EdgeSize>
<TileSize>
<AbsValue val="256"/>
</TileSize>
<BackgroundInsets>
<AbsInset left="0" right="0" top="5" bottom="5"/>
</BackgroundInsets>
</Backdrop>
<Scripts>
<OnHide>
DetailsDropDownOptionsFrameOnHide (self);
</OnHide>
<OnLoad>
self:SetBackdropColor (1, 1, 1, 1);
</OnLoad>
</Scripts>
</Frame>
<ScrollFrame name="$Parent_ScrollFrame" parentKey="dropdownframe" hidden="true">
<Size x="150" y="150"/>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$Parent" relativePoint="BOTTOMLEFT" x="0" y="-10" />
</Anchors>
<ScrollChild>
<Frame name="$Parent_ScrollChild">
<Size x="150" y="150"/>
<Anchors>
<Anchor point="TOPLEFT" relativeTo="$Parent" relativePoint="TOPLEFT" x="0" y="0" />
</Anchors>
<Layers>
<Layer level="BACKGROUND">
<!-- selected texture -->
<Texture name="$parent_SelectedTexture" parentKey="selected" hidden="true" file="Interface\SPELLBOOK\Spellbook-Parts">
<Size x="150" y="35" />
<TexCoords left="0.31250000" right="0.78515625" top="0.00390625" bottom="0.36328125"/>
<Anchors>
<Anchor point="LEFT" relativeTo="$parent" relativePoint="LEFT" x="2" y="0"/>
</Anchors>
</Texture>
</Layer>
<Layer level="ARTWORK">
<!-- mouse over texture -->
<Texture name="$parent_MouseOverTexture" alphaMode="ADD" parentKey="mouseover" hidden="true" file="Interface\Buttons\UI-Listbox-Highlight">
<Size x="150" y="15" />
<Anchors>
<Anchor point="LEFT" relativeTo="$parent" relativePoint="LEFT" x="2" y="0"/>
</Anchors>
</Texture>
</Layer>
</Layers>
</Frame>
</ScrollChild>
</ScrollFrame>
</Frames>
<Scripts>
<OnLoad>
self:SetBackdropColor (1, 1, 1, .5);
self.arrowTexture:SetDrawLayer ("OVERLAY", 1);
self.arrowTexture2:SetDrawLayer ("OVERLAY", 2);
tinsert (UISpecialFrames, self.dropdownborder:GetName());
tinsert (UISpecialFrames, self.dropdownframe:GetName());
</OnLoad>
<OnShow>
DetailsDropDownOnShow (self);
</OnShow>
<OnHide>
DetailsDropDownOnHide (self);
</OnHide>
<OnEnter>
DetailsDropDownOnEnter (self);
</OnEnter>
<OnLeave>
DetailsDropDownOnLeave (self);
</OnLeave>
<OnSizeChanged>
DetailsDropDownOnSizeChanged (self);
</OnSizeChanged>
<OnMouseDown>
DetailsDropDownOnMouseDown (self);
</OnMouseDown>
</Scripts>
</Button>
<Button name="DetailsDropDownOptionTemplate" virtual="true">
<Size x="150" y="20" />
<Layers>
<Layer level="ARTWORK">
<!-- statusbar texture -->
<Texture name="$parent_StatusBarTexture" parentKey="statusbar">
<Size x="150" y="20" />
<Anchors>
<Anchor point="LEFT" relativeTo="$parent" relativePoint="LEFT" x="0" y="0"/>
<Anchor point="RIGHT" relativeTo="$parent" relativePoint="RIGHT" x="0" y="0"/>
</Anchors>
</Texture>
</Layer>
<Layer level="OVERLAY">
<!-- icon texture -->
<Texture name="$parent_IconTexture" parentKey="icon" file = "Interface\ICONS\Spell_ChargePositive">
<Size x="20" y="20" />
<Anchors>
<Anchor point="LEFT" relativeTo="$parent" relativePoint="LEFT" x="2" y="0"/>
</Anchors>
</Texture>
<!-- text -->
<FontString name="$parent_Text" parentKey="label" inherits="GameFontHighlightSmall" justifyH="LEFT" nonspacewrap="false">
<FontHeight val="10.5"/>
<Anchors>
<Anchor point="LEFT" relativeTo="$parent_IconTexture" relativePoint="RIGHT" x="5" y="0"/>
</Anchors>
</FontString>
</Layer>
</Layers>
<Scripts>
<OnMouseDown>
DetailsDropDownOptionClick (self);
</OnMouseDown>
<OnEnter>
DetailsDropDownOptionOnEnter (self);
</OnEnter>
<OnLeave>
DetailsDropDownOptionOnLeave (self);
</OnLeave>
</Scripts>
</Button>
</Ui>
+111
View File
@@ -0,0 +1,111 @@
--> details main objects
local _detalhes = _G._detalhes
local gump = _detalhes.gump
local _type = type
local _unpack = unpack
gump.LabelNameCounter = 1
gump.PictureNameCounter = 1
gump.debug = false
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> points
function gump:CheckPoints (v1, v2, v3, v4, v5, object)
--bg_esq:SetPoint ("topleft", DmgRankFrame, 10, -215)
if (not v1 and not v2) then
return "topleft", object.widget:GetParent(), "topleft", 0, 0
end
if (_type (v1) == "string") then
local frameGlobal = _G [v1]
if (frameGlobal and frameGlobal.GetObjectType) then
return gump:CheckPoints (frameGlobal, v2, v3, v4, v5, object)
end
elseif (_type (v2) == "string") then
local frameGlobal = _G [v2]
if (frameGlobal and frameGlobal.GetObjectType) then
return gump:CheckPoints (v1, frameGlobal, v3, v4, v5, object)
end
end
if (_type (v1) == "string" and _type (v2) == "table") then --> :setpoint ("left", frame, _, _, _)
if (not v3 or _type (v3) == "number") then --> :setpoint ("left", frame, 10, 10)
v1, v2, v3, v4, v5 = v1, v2, v1, v3, v4
--else
--> :setpoint ("left", frame, "left", 10, 10)
end
elseif (_type (v1) == "string" and _type (v2) == "number") then --> :setpoint ("topleft", x, y)
v1, v2, v3, v4, v5 = v1, object.widget:GetParent(), v1, v2, v3
elseif (_type (v1) == "number") then --> :setpoint (x, y)
v1, v2, v3, v4, v5 = "topleft", object.widget:GetParent(), "topleft", v1, v2
elseif (_type (v1) == "table") then --> :setpoint (frame, x, y)
v1, v2, v3, v4, v5 = "topleft", v1, "topleft", v2, v3
end
if (not v2) then
v2 = object.widget:GetParent()
elseif (v2.dframework) then
v2 = v2.widget
end
return v1 or "topleft", v2, v3 or "topleft", v4 or 0, v5 or 0
end
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> color scheme
function gump:NewColor (_colorname, _colortable, _green, _blue, _alpha)
if (_type (_colorname) ~= "string") then
return _detalhes:NewError ("color name must be a string.")
end
if (gump.alias_text_colors [_colorname]) then
return _detalhes:NewError (_colorname .. " already exists.")
end
if (_type (_colortable) == "table") then
if (_colortable[1] and _colortable[2] and _colortable[3]) then
_colortable[4] = _colortable[4] or 1
gump.alias_text_colors [_colorname] = _colortable
else
return _detalhes:NewError ("invalid color table.")
end
elseif (_colortable and _green and _blue) then
_alpha = _alpha or 1
gump.alias_text_colors [_colorname] = {_colortable, _green, _blue, _alpha}
else
return _detalhes:NewError ("invalid parameter.")
end
return true
end
function gump:ParseColors (_arg1, _arg2, _arg3, _arg4)
if (_type (_arg1) == "table") then
_arg1, _arg2, _arg3, _arg4 = _unpack (_arg1)
elseif (_type (_arg1) == "string") then
local color = gump.alias_text_colors [_arg1]
if (color) then
_arg1, _arg2, _arg3, _arg4 = _unpack (color)
else
_arg1, _arg2, _arg3, _arg4 = _unpack (gump.alias_text_colors.none)
end
end
if (not _arg4) then
_arg4 = 1
end
return _arg1, _arg2, _arg3, _arg4
end
+259
View File
@@ -0,0 +1,259 @@
--> details main objects
local _detalhes = _G._detalhes
local gump = _detalhes.gump
local _rawset = rawset --> lua local
local _rawget = rawget --> lua local
local _setmetatable = setmetatable --> lua local
local _unpack = unpack --> lua local
local _type = type --> lua local
local _math_floor = math.floor --> lua local
local loadstring = loadstring --> lua local
local cleanfunction = function() end
local APILabelFunctions = false
local LabelMetaFunctions = {}
------------------------------------------------------------------------------------------------------------
--> metatables
LabelMetaFunctions.__call = function (_table, value)
return self.label:SetText (value)
end
------------------------------------------------------------------------------------------------------------
--> members
--> shown
local gmember_shown = function (_object)
return _object:IsShown()
end
--> frame width
local gmember_width = function (_object)
return _object.label:GetStringWidth()
end
--> frame height
local gmember_height = function (_object)
return _object.label:GetStringHeight()
end
--> text
local gmember_text = function (_object)
return _object.label:GetText()
end
--> text color
local gmember_textcolor = function (_object)
return _object.label:GetTextColor()
end
--> text font
local gmember_textfont = function (_object)
local fontface = _object.label:GetFont()
return fontface
end
--> text size
local gmember_textsize = function (_object)
local _, fontsize = _object.label:GetFont()
return fontsize
end
local get_members_function_index = {
["shown"] = gmember_shown,
["width"] = gmember_width,
["height"] = gmember_height,
["text"] = gmember_text,
["fontcolor"] = gmember_textcolor,
["fontface"] = gmember_textfont,
["fontsize"] = gmember_textsize,
["textcolor"] = gmember_textcolor, --alias
["textfont"] = gmember_textfont, --alias
["textsize"] = gmember_textsize --alias
}
LabelMetaFunctions.__index = function (_table, _member_requested)
local func = get_members_function_index [_member_requested]
if (func) then
return func (_table, _member_requested)
end
local fromMe = _rawget (_table, _member_requested)
if (fromMe) then
return fromMe
end
return LabelMetaFunctions [_member_requested]
end
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> show
local smember_show = function (_object, _value)
if (_value) then
return _object:Show()
else
return _object:Hide()
end
end
--> hide
local smember_hide = function (_object, _value)
if (not _value) then
return _object:Show()
else
return _object:Hide()
end
end
--> text
local smember_text = function (_object, _value)
return _object.label:SetText (_value)
end
--> text color
local smember_textcolor = function (_object, _value)
local _value1, _value2, _value3, _value4 = gump:ParseColors (_value)
return _object.label:SetTextColor (_value1, _value2, _value3, _value4)
end
--> text font
local smember_textfont = function (_object, _value)
return _detalhes:SetFontFace (_object.label, _value)
end
--> text size
local smember_textsize = function (_object, _value)
return _detalhes:SetFontSize (_object.label, _value)
end
--> text align
local smember_textalign = function (_object, _value)
if (_value == "<") then
_value = "left"
elseif (_value == ">") then
_value = "right"
elseif (_value == "|") then
_value = "center"
end
return _object.label:SetJustifyH (_value)
end
--> field size width
local smember_width = function (_object, _value)
return _object.label:SetWidth (_value)
end
--> field size height
local smember_height = function (_object, _value)
return _object.label:SetHeight (_value)
end
local set_members_function_index = {
["show"] = smember_show,
["hide"] = smember_hide,
["align"] = smember_textalign,
["text"] = smember_text,
["width"] = smember_width,
["height"] = smember_height,
["fontcolor"] = smember_textcolor,
["color"] = smember_textcolor,
["fontface"] = smember_textfont,
["fontsize"] = smember_textsize,
["textcolor"] = smember_textcolor,
["textfont"] = smember_textfont,
["textsize"] = smember_textsize
}
LabelMetaFunctions.__newindex = function (_table, _key, _value)
local func = set_members_function_index [_key]
if (func) then
return func (_table, _value)
else
return _rawset (_table, _key, _value)
end
end
------------------------------------------------------------------------------------------------------------
--> methods
--> show & hide
function LabelMetaFunctions:IsShown()
return self.label:IsShown()
end
function LabelMetaFunctions:Show()
return self.label:Show()
end
function LabelMetaFunctions:Hide()
return self.label:Hide()
end
-- setpoint
function LabelMetaFunctions:SetPoint (v1, v2, v3, v4, v5)
v1, v2, v3, v4, v5 = gump:CheckPoints (v1, v2, v3, v4, v5, self)
if (not v1) then
print ("Invalid parameter for SetPoint")
return
end
return self.widget:SetPoint (v1, v2, v3, v4, v5)
end
------------------------------------------------------------------------------------------------------------
--> object constructor
function gump:NewLabel (parent, container, name, member, text, font, size, color)
if (not parent) then
return nil
end
if (not container) then
container = parent
end
if (not name) then
name = "DetailsLabelNumber" .. gump.LabelNameCounter
gump.LabelNameCounter = gump.LabelNameCounter + 1
end
if (name:find ("$parent")) then
name = name:gsub ("$parent", parent:GetName())
end
local LabelObject = {type = "label", dframework = true}
if (member) then
parent [member] = LabelObject
--container [member] = LabelObject.label
end
if (parent.dframework) then
parent = parent.widget
end
if (container.dframework) then
container = container.widget
end
font = font or "GameFontHighlightSmall"
LabelObject.label = parent:CreateFontString (name, "OVERLAY", font)
LabelObject.widget = LabelObject.label
if (not APILabelFunctions) then
APILabelFunctions = true
local idx = getmetatable (LabelObject.label).__index
for funcName, funcAddress in pairs (idx) do
if (not LabelMetaFunctions [funcName]) then
LabelMetaFunctions [funcName] = function (object, ...)
local x = loadstring ( "return _G."..object.label:GetName()..":"..funcName.."(...)")
return x (...)
end
end
end
end
LabelObject.label:SetText (text)
if (size) then
_detalhes:SetFontSize (LabelObject.label, size)
end
if (color) then
LabelObject.label:SetTextColor (unpack (color))
end
LabelObject.label:SetJustifyH ("LEFT")
setmetatable (LabelObject, LabelMetaFunctions)
return LabelObject
end
+702
View File
@@ -0,0 +1,702 @@
--> details main objects
local _detalhes = _G._detalhes
local gump = _detalhes.gump
local _rawset = rawset --> lua locals
local _rawget = rawget --> lua locals
local _setmetatable = setmetatable --> lua locals
local _unpack = unpack --> lua locals
local _type = type --> lua locals
local _math_floor = math.floor --> lua locals
local cleanfunction = function() end
local BarMetaFunctions = {}
local APIBarFunctions
------------------------------------------------------------------------------------------------------------
--> metatables
BarMetaFunctions.__call = function (_table, value)
if (not value) then
return _table.statusbar:GetValue()
else
return _table.statusbar:SetValue (value)
end
end
BarMetaFunctions.__add = function (v1, v2)
if (_type (v1) == "table") then
local v = v1.statusbar:GetValue()
v = v + v2
v1.statusbar:SetValue (v)
else
local v = v2.statusbar:GetValue()
v = v + v1
v2.statusbar:SetValue (v)
end
end
BarMetaFunctions.__sub = function (v1, v2)
if (_type (v1) == "table") then
local v = v1.statusbar:GetValue()
v = v - v2
v1.statusbar:SetValue (v)
else
local v = v2.statusbar:GetValue()
v = v - v1
v2.statusbar:SetValue (v)
end
end
------------------------------------------------------------------------------------------------------------
--> members
--> tooltip
local function gmember_tooltip (_object)
return _object:GetTooltip()
end
--> shown
local gmember_shown = function (_object)
return _object.statusbar:IsShown()
end
--> frame width
local gmember_width = function (_object)
return _object.statusbar:GetWidth()
end
--> frame height
local gmember_height = function (_object)
return _object.statusbar:GetHeight()
end
--> value
local gmember_value = function (_object)
return _object.statusbar:GetValue()
end
--> right text
local gmember_rtext = function (_object)
return _object.textright:GetText()
end
--> left text
local gmember_ltext = function (_object)
return _object.textleft:GetText()
end
--> left color
local gmember_color = function (_object)
return _object.texture.original_colors
end
--> icon
local gmember_icon = function (_object)
return _object.icon:GetTexture()
end
--> texture
local gmember_texture = function (_object)
return _object.texture:GetTexture()
end
--> font size
local gmember_textsize = function (_object)
local _, fontsize = _object.textleft:GetFont()
return fontsize
end
--> font face
local gmember_textfont = function (_object)
local fontface = _object.textleft:GetFont()
return fontface
end
--> font color
local gmember_textcolor = function (_object)
return _object.textleft:GetTextColor()
end
local get_members_function_index = {
["tooltip"] = gmember_tooltip,
["shown"] = gmember_shown,
["width"] = gmember_width,
["height"] = gmember_height,
["value"] = gmember_value,
["lefttext"] = gmember_ltext,
["righttext"] = gmember_rtext,
["color"] = gmember_color,
["icon"] = gmember_icon,
["texture"] = gmember_texture,
["fontsize"] = gmember_textsize,
["fontface"] = gmember_textfont,
["fontcolor"] = gmember_textcolor,
["textsize"] = gmember_textsize, --alias
["textfont"] = gmember_textfont, --alias
["textcolor"] = gmember_textcolor --alias
}
BarMetaFunctions.__index = function (_table, _member_requested)
local func = get_members_function_index [_member_requested]
if (func) then
return func (_table, _member_requested)
end
local fromMe = _rawget (_table, _member_requested)
if (fromMe) then
return fromMe
end
return BarMetaFunctions [_member_requested]
end
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> tooltip
local smember_tooltip = function (_object, _value)
return _object:SetTooltip (_value)
end
--> show
local smember_shown = function (_object, _value)
if (_value) then
return _object:Show()
else
return _object:Hide()
end
end
--> hide
local smember_hide = function (_object, _value)
if (_value) then
return _object:Hide()
else
return _object:Show()
end
end
--> width
local smember_width = function (_object, _value)
return _object.statusbar:SetWidth (_value)
end
--> height
local smember_height = function (_object, _value)
return _object.statusbar:SetHeight (_value)
end
--> statusbar value
local smember_value = function (_object, _value)
_object.statusbar:SetValue (_value)
return _object.div:SetPoint ("left", _object.statusbar, "left", _value * (_object.statusbar:GetWidth()/100) - 16, 0)
end
--> right text
local smember_rtext = function (_object, _value)
return _object.textright:SetText (_value)
end
--> left text
local smember_ltext = function (_object, _value)
return _object.textleft:SetText (_value)
end
--> color
local smember_color = function (_object, _value)
local _value1, _value2, _value3, _value4 = gump:ParseColors (_value)
_object.statusbar:SetStatusBarColor (_value1, _value2, _value3, _value4)
_object.texture.original_colors = {_value1, _value2, _value3, _value4}
return _object.texture:SetVertexColor (_value1, _value2, _value3, _value4)
end
--> icon
local smember_icon = function (_object, _value)
if (type (_value) == "table") then
local _value1, _value2 = _unpack (_value)
_object.icon:SetTexture (_value1)
if (_value2) then
_object.icon:SetTexCoord (_unpack (_value2))
end
else
_object.icon:SetTexture (_value)
end
return
end
--> texture
local smember_texture = function (_object, _value)
if (type (_value) == "table") then
local _value1, _value2 = _unpack (_value)
_object.texture:SetTexture (_value1)
if (_value2) then
_object.texture:SetTexCoord (_unpack (_value2))
end
else
_object.texture:SetTexture (_value)
end
return
end
--> font face
local smember_textfont = function (_object, _value)
_detalhes:SetFontFace (_object.textleft, _value)
return _detalhes:SetFontFace (_object.textright, _value)
end
--> font size
local smember_textsize = function (_object, _value)
_detalhes:SetFontSize (_object.textleft, _value)
return _detalhes:SetFontSize (_object.textright, _value)
end
--> font color
local smember_textcolor = function (_object, _value)
local _value1, _value2, _value3, _value4 = gump:ParseColors (_value)
_object.textleft:SetTextColor (_value1, _value2, _value3, _value4)
return _object.textright:SetTextColor (_value1, _value2, _value3, _value4)
end
local set_members_function_index = {
["tooltip"] = smember_tooltip,
["shown"] = smember_shown,
["width"] = smember_width,
["height"] = smember_height,
["value"] = smember_value,
["righttext"] = smember_rtext,
["lefttext"] = smember_ltext,
["color"] = smember_color,
["icon"] = smember_icon,
["texture"] = smember_texture,
["fontsize"] = smember_textsize,
["fontface"] = smember_textfont,
["fontcolor"] = smember_textcolor,
["textsize"] = smember_textsize, --alias
["textfont"] = smember_textfont, --alias
["textcolor"] = smember_textcolor --alias
}
BarMetaFunctions.__newindex = function (_table, _key, _value)
local func = set_members_function_index [_key]
if (func) then
return func (_table, _value)
else
return _rawset (_table, _key, _value)
end
end
------------------------------------------------------------------------------------------------------------
--> methods
--> show & hide
function BarMetaFunctions:Show()
self.statusbar:Show()
end
function BarMetaFunctions:Hide()
self.statusbar:Hide()
end
--> set value (status bar)
function BarMetaFunctions:SetValue (value)
if (not value) then
value = 0
end
self.statusbar:SetValue (value)
self.div:SetPoint ("left", self.statusbar, "left", value * (self.statusbar:GetWidth()/100) - 16, 0)
end
--> set point
function BarMetaFunctions:SetPoint (v1, v2, v3, v4, v5)
v1, v2, v3, v4, v5 = gump:CheckPoints (v1, v2, v3, v4, v5, self)
if (not v1) then
print ("Invalid parameter for SetPoint")
return
end
return self.widget:SetPoint (v1, v2, v3, v4, v5)
end
--> set sizes
function BarMetaFunctions:SetSize (w, h)
if (w) then
self.statusbar:SetWidth (w)
end
if (h) then
self.statusbar:SetHeight (h)
end
end
--> set texture
function BarMetaFunctions:SetTexture (texture)
self.texture:SetTexture (texture)
end
--> set texts
function BarMetaFunctions:SetLeftText (text)
self.textleft:SetText (text)
end
function BarMetaFunctions:SetRightText (text)
self.textright:SetText (text)
end
--> set color
function BarMetaFunctions:SetColor (r, g, b, a)
r, g, b, a = gump:ParseColors (r, g, b, a)
self.texture:SetVertexColor (r, g, b, a)
self.statusbar:SetStatusBarColor (r, g, b, a)
self.texture.original_colors = {r, g, b, a}
end
--> set icons
function BarMetaFunctions:SetIcon (texture, ...)
self.icon:SetTexture (texture)
if (...) then
local L, R, U, D = _unpack (...)
self.icon:SetTexCoord (L, R, U, D)
end
end
--> show div
function BarMetaFunctions:ShowDiv (bool)
if (bool) then
self.div:Show()
else
self.div:Hide()
end
end
-- tooltip
function BarMetaFunctions:SetTooltip (tooltip)
if (tooltip) then
return _rawset (self, "have_tooltip", tooltip)
else
return _rawset (self, "have_tooltip", nil)
end
end
function BarMetaFunctions:GetTooltip()
return _rawget (self, "have_tooltip")
end
-- frame levels
function BarMetaFunctions:GetFrameLevel()
return self.statusbar:GetFrameLevel()
end
function BarMetaFunctions:SetFrameLevel (level, frame)
if (not frame) then
return self.statusbar:SetFrameLevel (level)
else
local framelevel = frame:GetFrameLevel (frame) + level
return self.statusbar:SetFrameLevel (framelevel)
end
end
-- frame stratas
function BarMetaFunctions:SetFrameStrata()
return self.statusbar:GetFrameStrata()
end
function BarMetaFunctions:SetFrameStrata (strata)
if (_type (strata) == "table") then
self.statusbar:SetFrameStrata (strata:GetFrameStrata())
else
self.statusbar:SetFrameStrata (strata)
end
end
--> container
function BarMetaFunctions:SetContainer (container)
self.container = container
end
--> hooks
function BarMetaFunctions:SetHook (hookType, func)
if (func) then
if (hookType == "OnEnterHook") then
self.OnEnterHook = func
return true
elseif (hookType == "OnLeaveHook") then
self.OnLeaveHook = func
return true
elseif (hookType == "OnHideHook") then
self.OnHideHook = func
return true
elseif (hookType == "OnShowHook") then
self.OnShowHook = func
return true
elseif (hookType == "OnMouseDownHook") then
self.OnMouseDownHook = func
return true
elseif (hookType == "OnMouseUpHook") then
self.OnMouseUpHook = func
return true
end
else
if (hookType == "OnEnterHook") then
self.OnEnterHook = nil
return true
elseif (hookType == "OnLeaveHook") then
self.OnLeaveHook = nil
return true
elseif (hookType == "OnHideHook") then
self.OnHideHook = nil
return true
elseif (hookType == "OnShowHook") then
self.OnShowHook = nil
return true
elseif (hookType == "OnMouseDownHook") then
self.OnMouseDownHook = nil
return true
elseif (hookType == "OnMouseUpHook") then
self.OnMouseUpHook = nil
return true
end
end
return false
end
------------------------------------------------------------------------------------------------------------
--> scripts
local OnEnter = function (frame)
if (frame.MyObject.OnEnterHook) then
local interrupt = frame.MyObject.OnEnterHook (frame)
if (interrupt) then
return
end
end
if (not frame.MyObject.timer) then
local oc = frame.MyObject.texture.original_colors --original colors
gump:GradientEffect ( frame.MyObject.texture, "texture", oc[1], oc[2], oc[3], oc[4], oc[1]+0.2, oc[2]+0.2, oc[3]+0.2, oc[4], .2)
frame.MyObject.div:Show()
frame.MyObject.div:SetPoint ("left", frame, "left", frame:GetValue() * (frame:GetWidth()/100) - 16, 0)
else
local oc = frame.MyObject.texture.original_colors --original colors
gump:GradientEffect ( frame.MyObject.texture, "texture", oc[1], oc[2], oc[3], oc[4], oc[1]-0.2, oc[2]-0.2, oc[3]-0.2, oc[4]+.2, .2)
end
frame.MyObject.background:Show()
if (frame.MyObject.have_tooltip) then
GameCooltip:Reset()
GameCooltip:AddLine (frame.MyObject.have_tooltip)
GameCooltip:ShowCooltip (frame, "tooltip")
end
local parent = frame:GetParent().MyObject
if (parent and parent.type == "panel") then
if (parent.GradientEnabled) then
parent:RunGradient()
end
end
end
local OnLeave = function (frame)
if (frame.MyObject.OnLeaveHook) then
local interrupt = frame.MyObject.OnLeaveHook (frame)
if (interrupt) then
return
end
end
if (not frame.MyObject.timer) then
local oc = frame.MyObject.texture.original_colors --original colors
local r, g, b, a = frame.MyObject.texture:GetVertexColor()
gump:GradientEffect ( frame.MyObject.texture, "texture", r, g, b, a, oc[1], oc[2], oc[3], oc[4], .2)
frame.MyObject.div:Hide()
frame.MyObject.background:Hide()
else
local oc = frame.MyObject.background.original_colors --original colors
local r, g, b, a = frame.MyObject.background:GetVertexColor()
gump:GradientEffect ( frame.MyObject.background, "texture", r, g, b, a, oc[1], oc[2], oc[3], oc[4], .2)
end
if (frame.MyObject.have_tooltip) then
_detalhes.popup:ShowMe (false)
end
local parent = frame:GetParent().MyObject
if (parent and parent.type == "panel") then
if (parent.GradientEnabled) then
parent:RunGradient (false)
end
end
end
local OnHide = function (frame)
if (frame.MyObject.OnHideHook) then
local interrupt = frame.MyObject.OnHideHook (frame)
if (interrupt) then
return
end
end
end
local OnShow = function (frame)
if (frame.MyObject.OnShowHook) then
local interrupt = frame.MyObject.OnShowHook (frame)
if (interrupt) then
return
end
end
end
local OnMouseDown = function (frame, button)
if (frame.MyObject.OnMouseDownHook) then
local interrupt = frame.MyObject.OnMouseDownHook (frame, button)
if (interrupt) then
return
end
end
if (not frame.MyObject.container.isLocked and frame.MyObject.container:IsMovable()) then
if (not frame.isLocked and frame:IsMovable()) then
frame.MyObject.container.isMoving = true
frame.MyObject.container:StartMoving()
end
end
end
local OnMouseUp = function (frame, button)
if (frame.MyObject.OnMouseUpHook) then
local interrupt = frame.MyObject.OnMouseUpHook (frame, button)
if (interrupt) then
return
end
end
if (frame.MyObject.container.isMoving) then
frame.MyObject.container:StopMovingOrSizing()
frame.MyObject.container.isMoving = false
end
end
------------------------------------------------------------------------------------------------------------
--> timer
function BarMetaFunctions:OnTimerEnd()
if (self.OnTimerEndHook) then
local interrupt = self.OnTimerEndHook()
if (interrupt) then
return
end
end
self.timer_texture:Hide()
self.div_timer:Hide()
self:Hide()
self.timer = false
end
local OnUpdate = function (self, elapsed)
local timepct = (elapsed / self.tempo) * 100
self.c = self.c - (timepct*self.width/100)
self.remaining = self.remaining - elapsed
self.righttext:SetText (_math_floor (self.remaining))
self.timertexture:SetWidth (self.c)
if (self.c < 1) then
self:SetScript ("OnUpdate", nil)
self.MyObject:OnTimerEnd()
end
end
function BarMetaFunctions:SetTimer (tempo)
self.statusbar.width = self.statusbar:GetWidth()
self.statusbar.tempo = tempo
self.statusbar.remaining = tempo
self.statusbar.c = self.statusbar.width
self.timer_texture:Show()
self.timer_texture:SetWidth (self.statusbar.width)
self.statusbar.t = self.timer_texture
self (1)
self.div_timer:Show()
self.background:Show()
self.timer = true
self.statusbar:SetScript ("OnUpdate", OnUpdate)
end
------------------------------------------------------------------------------------------------------------
--> object constructor
function DetailsNormalBar_OnCreate (self)
self.texture.original_colors = {1, 1, 1, 1}
self.background.original_colors = {.3, .3, .3, .3}
self.timertexture.original_colors = {.3, .3, .3, .3}
return true
end
function gump:NewBar (parent, container, name, member, w, h, value)
if (not name) then
return nil
elseif (not parent) then
return nil
elseif (not container) then
container = parent
end
if (name:find ("$parent")) then
name = name:gsub ("$parent", parent:GetName())
end
local BarObject = {type = "bar", dframework = true}
if (member) then
parent [member] = BarObject
end
if (parent.dframework) then
parent = parent.widget
end
if (container.dframework) then
container = container.widget
end
--> default members:
--> hooks
BarObject.OnEnterHook = nil
BarObject.OnLeaveHook = nil
BarObject.OnHideHook = nil
BarObject.OnShowHook = nil
BarObject.OnMouseDownHook = nil
BarObject.OnMouseUpHook = nil
BarObject.OnTimerEndHook = nil
--> misc
BarObject.tooltip = nil
BarObject.locked = false
BarObject.have_tooltip = nil
BarObject.container = container
--> create widgets
BarObject.statusbar = CreateFrame ("statusbar", name, parent, "DetailsNormalBarTemplate")
BarObject.widget = BarObject.statusbar
if (not APIBarFunctions) then
APIBarFunctions = true
local idx = getmetatable (BarObject.statusbar).__index
for funcName, funcAddress in pairs (idx) do
if (not BarMetaFunctions [funcName]) then
BarMetaFunctions [funcName] = function (object, ...)
local x = loadstring ( "return _G."..object.statusbar:GetName()..":"..funcName.."(...)")
return x (...)
end
end
end
end
BarObject.statusbar:SetHeight (h)
BarObject.statusbar:SetWidth (w)
BarObject.statusbar:SetFrameLevel (parent:GetFrameLevel()+1)
BarObject.statusbar:SetMinMaxValues (0, 100)
BarObject.statusbar:SetValue (value or 50)
BarObject.statusbar.MyObject = BarObject
BarObject.timer_texture = _G [name .. "_timerTexture"]
BarObject.timer_texture:SetWidth (w)
BarObject.timer_texture:SetHeight (h)
BarObject.texture = _G [name .. "_statusbarTexture"]
BarObject.background = _G [name .. "_background"]
BarObject.icon = _G [name .. "_icon"]
BarObject.textleft = _G [name .. "_TextLeft"]
BarObject.textright = _G [name .. "_TextRight"]
BarObject.div = _G [name .. "_sparkMouseover"]
BarObject.div_timer = _G [name .. "_sparkTimer"]
--> hooks
BarObject.statusbar:SetScript ("OnEnter", OnEnter)
BarObject.statusbar:SetScript ("OnLeave", OnLeave)
BarObject.statusbar:SetScript ("OnHide", OnHide)
BarObject.statusbar:SetScript ("OnShow", OnShow)
BarObject.statusbar:SetScript ("OnMouseDown", OnMouseDown)
BarObject.statusbar:SetScript ("OnMouseUp", OnMouseUp)
--> set class
_setmetatable (BarObject, BarMetaFunctions)
return BarObject
end
+90
View File
@@ -0,0 +1,90 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/ .. \FrameXML\UI.xsd">
<Script file="normal_bar.lua"/>
<StatusBar name="DetailsNormalBarTemplate" virtual="true">
<Size x="300" y="14"/>
<Layers>
<Layer level="BACKGROUND">
<!-- background texture -->
<Texture name="$parent_background" hidden="false" setAllPoints="true" parentKey="background" file = "Interface\PaperDollInfoFrame\UI-Character-Skills-Bar" horizTile="false" vertTile="false">
<Size x="300" y="14" />
<Color a = "0.3" r = "0.3" g = "0.3" b = "0.3" />
</Texture>
</Layer>
<Layer level="ARTWORK">
<!-- timer texture -->
<Texture name="$parent_timerTexture" hidden="true" parentKey="timertexture" file = "Interface\PaperDollInfoFrame\UI-Character-Skills-Bar" horizTile="false" vertTile="false">
<Size x="300" y="14" />
<Color a = "1" r = "1" g = "1" b = "1" />
<Anchors>
<Anchor point="LEFT" relativeTo="$parent" />
</Anchors>
</Texture>
<!-- statusbar texture -->
<Texture name="$parent_statusbarTexture" hidden="false" parentKey="texture" file = "Interface\PaperDollInfoFrame\UI-Character-Skills-Bar" horizTile="false" vertTile="false">
<Size x="300" y="14" />
<Color a = "1" r = "1" g = "1" b = "1" />
</Texture>
</Layer>
<Layer level="OVERLAY">
<!-- icon texture -->
<Texture name="$parent_icon" parentKey="icontexture">
<Size x="14" y="14" />
<Anchors>
<Anchor point="LEFT" relativeTo="$parent" relativePoint="LEFT" x="0" y="0"/>
</Anchors>
</Texture>
<!-- spark mouse over -->
<Texture name="$parent_sparkMouseover" hidden="true" parentKey="sparkmouseover" file = "Interface\CastingBar\UI-CastingBar-Spark" alphaMode="ADD">
<Size>
<AbsDimension x="32" y="32"/>
</Size>
<Anchors>
<Anchor point="LEFT" relativeTo="$parent" relativePoint="RIGHT" x="-16" y="-1"/>
</Anchors>
</Texture>
<!-- timer spark -->
<Texture name="$parent_sparkTimer" hidden="true" parentKey="sparktimer" file = "Interface\CastingBar\UI-CastingBar-Spark" alphaMode="ADD">
<Size>
<AbsDimension x="32" y="32"/>
</Size>
<Anchors>
<Anchor point="LEFT" relativeTo="$parent_timerTexture" relativePoint="RIGHT" x="-16" y="-1"/>
</Anchors>
</Texture>
<!-- left text -->
<FontString name="$parent_TextLeft" parentKey="lefttext" inherits="GameFontHighlight" justifyH="LEFT" nonspacewrap="false">
<FontHeight val="10.5"/>
<Anchors>
<Anchor point="LEFT" relativeTo="$parent_icon" relativePoint="RIGHT" x="3" y="0"/>
</Anchors>
</FontString>
<!-- right text -->
<FontString name="$parent_TextRight" parentKey="righttext" inherits="GameFontHighlight" justifyH="RIGHT" nonspacewrap="false">
<FontHeight val="10.5"/>
<Anchors>
<Anchor point="RIGHT" relativeTo="$parent" relativePoint="RIGHT" x="-3" y="0"/>
</Anchors>
</FontString>
</Layer>
</Layers>
<Scripts>
<OnLoad>
self:SetStatusBarTexture (self.texture);
DetailsNormalBar_OnCreate (self);
</OnLoad>
</Scripts>
</StatusBar>
</Ui>
+504
View File
@@ -0,0 +1,504 @@
--> details main objects
local _detalhes = _G._detalhes
local gump = _detalhes.gump
--> lua locals
local _rawset = rawset --> lua local
local _rawget = rawget --> lua local
local _setmetatable = setmetatable --> lua local
local _unpack = unpack --> lua local
local _type = type --> lua local
local _math_floor = math.floor --> lua local
local loadstring = loadstring --> lua local
local cleanfunction = function() end
local PanelMetaFunctions = {}
local APIFrameFunctions
------------------------------------------------------------------------------------------------------------
--> metatables
PanelMetaFunctions.__call = function (_table, value)
--> nothing to do
return true
end
------------------------------------------------------------------------------------------------------------
--> members
--> tooltip
local gmember_tooltip = function (_object)
return _object:GetTooltip()
end
--> shown
local gmember_shown = function (_object)
return _object:IsShown()
end
--> backdrop color
local gmember_color = function (_object)
return _object.frame:GetBackdropColor()
end
--> backdrop table
local gmember_backdrop = function (_object)
return _object.frame:GetBackdrop()
end
--> frame width
local gmember_width = function (_object)
return _object.frame:GetWidth()
end
--> frame height
local gmember_height = function (_object)
return _object.frame:GetHeight()
end
--> locked
local gmember_locked = function (_object)
return _rawget (_object, "is_locked")
end
local get_members_function_index = {
["tooltip"] = gmember_tooltip,
["shown"] = gmember_shown,
["color"] = gmember_color,
["backdrop"] = gmember_backdrop,
["width"] = gmember_width,
["height"] = gmember_height,
["locked"] = gmember_locked,
}
PanelMetaFunctions.__index = function (_table, _member_requested)
local func = get_members_function_index [_member_requested]
if (func) then
return func (_table, _member_requested)
end
local fromMe = _rawget (_table, _member_requested)
if (fromMe) then
return fromMe
end
return PanelMetaFunctions [_member_requested]
end
--> tooltip
local smember_tooltip = function (_object, _value)
return _object:SetTooltip (_value)
end
--> show
local smember_show = function (_object, _value)
if (_value) then
return _object:Show()
else
return _object:Hide()
end
end
--> hide
local smember_hide = function (_object, _value)
if (not _value) then
return _object:Show()
else
return _object:Hide()
end
end
--> backdrop color
local smember_color = function (_object, _value)
local _value1, _value2, _value3, _value4 = gump:ParseColors (_value)
return _object:SetBackdropColor (_value1, _value2, _value3, _value4)
end
--> frame width
local smember_width = function (_object, _value)
return _object.frame:SetWidth (_value)
end
--> frame height
local smember_height = function (_object, _value)
return _object.frame:SetHeight (_value)
end
--> locked
local smember_locked = function (_object, _value)
if (_value) then
_object.frame:SetMovable (false)
return _rawset (_object, "is_locked", true)
else
_object.frame:SetMovable (true)
_rawset (_object, "is_locked", false)
return
end
end
--> backdrop
local smember_backdrop = function (_object, _value)
return _object.frame:SetBackdrop (_value)
end
--> close with right button
local smember_right_close = function (_object, _value)
return _rawset (_object, "rightButtonClose", _value)
end
local set_members_function_index = {
["tooltip"] = smember_tooltip,
["show"] = smember_show,
["hide"] = smember_hide,
["color"] = smember_color,
["backdrop"] = smember_backdrop,
["width"] = smember_width,
["height"] = smember_height,
["locked"] = smember_locked,
["close_with_right"] = smember_right_close,
}
PanelMetaFunctions.__newindex = function (_table, _key, _value)
local func = set_members_function_index [_key]
if (func) then
return func (_table, _value)
else
return _rawset (_table, _key, _value)
end
end
------------------------------------------------------------------------------------------------------------
--> methods
--> show & hide
function PanelMetaFunctions:Show()
self.frame:Show()
end
function PanelMetaFunctions:Hide()
self.frame:Hide()
end
-- setpoint
function PanelMetaFunctions:SetPoint (v1, v2, v3, v4, v5)
v1, v2, v3, v4, v5 = gump:CheckPoints (v1, v2, v3, v4, v5, self)
if (not v1) then
print ("Invalid parameter for SetPoint")
return
end
return self.widget:SetPoint (v1, v2, v3, v4, v5)
end
-- sizes
function PanelMetaFunctions:SetSize (w, h)
if (w) then
self.frame:SetWidth (w)
end
if (h) then
self.frame:SetHeight (h)
end
end
-- clear
function PanelMetaFunctions:HideWidgets()
for widgetName, widgetSelf in pairs (self) do
if (type (widgetSelf) == "table" and widgetSelf.dframework) then
widgetSelf:Hide()
end
end
end
-- backdrop
function PanelMetaFunctions:SetBackdrop (background, edge, tilesize, edgesize, tile, left, right, top, bottom)
if (_type (background) == "boolean" and not background) then
return self.frame:SetBackdrop (nil)
elseif (_type (background) == "table") then
self.frame:SetBackdrop (background)
else
local currentBackdrop = self.frame:GetBackdrop() or {edgeFile="Interface\\DialogFrame\\UI-DialogBox-Border", bgFile="Interface\\DialogFrame\\UI-DialogBox-Background", tile=true, tileSize=16, edgeSize=16, insets={left=1, right=0, top=0, bottom=0}}
currentBackdrop.bgFile = background or currentBackdrop.bgFile
currentBackdrop.edgeFile = edgeFile or currentBackdrop.edgeFile
currentBackdrop.tileSize = tilesize or currentBackdrop.tileSize
currentBackdrop.edgeSize = edgesize or currentBackdrop.edgeSize
currentBackdrop.tile = tile or currentBackdrop.tile
currentBackdrop.insets.left = left or currentBackdrop.insets.left
currentBackdrop.insets.right = left or currentBackdrop.insets.right
currentBackdrop.insets.top = left or currentBackdrop.insets.top
currentBackdrop.insets.bottom = left or currentBackdrop.insets.bottom
self.frame:SetBackdrop (currentBackdrop)
end
end
-- backdropcolor
function PanelMetaFunctions:SetBackdropColor (color, arg2, arg3, arg4)
if (arg2) then
self.frame:SetBackdropColor (color, arg2, arg3, arg4 or 1)
self.frame.Gradient.OnLeave = {color, arg2, arg3, arg4 or 1}
else
local _value1, _value2, _value3, _value4 = gump:ParseColors (color)
self.frame:SetBackdropColor (_value1, _value2, _value3, _value4)
self.frame.Gradient.OnLeave = {_value1, _value2, _value3, _value4}
end
end
-- border color
function PanelMetaFunctions:SetBackdropBorderColor (color, arg2, arg3, arg4)
if (arg2) then
return self.frame:SetBackdropBorderColor (color, arg2, arg3, arg4)
end
local _value1, _value2, _value3, _value4 = gump:ParseColors (color)
self.frame:SetBackdropBorderColor (_value1, _value2, _value3, _value4)
end
-- gradient colors
function PanelMetaFunctions:SetGradient (FadeType, color)
local _value1, _value2, _value3, _value4 = gump:ParseColors (color)
if (FadeType == "OnEnter") then
self.frame.Gradient.OnEnter = {_value1, _value2, _value3, _value4}
elseif (FadeType == "OnLeave") then
self.frame.Gradient.OnLeave = {_value1, _value2, _value3, _value4}
end
end
-- tooltip
function PanelMetaFunctions:SetTooltip (tooltip)
if (tooltip) then
return _rawset (self, "have_tooltip", tooltip)
else
return _rawset (self, "have_tooltip", nil)
end
end
function PanelMetaFunctions:GetTooltip()
return _rawget (self, "have_tooltip")
end
-- enable and disable gradients
function PanelMetaFunctions:DisableGradient()
self.GradientEnabled = false
end
function PanelMetaFunctions:EnableGradient()
self.GradientEnabled = true
end
--> hooks
function PanelMetaFunctions:SetHook (hookType, func)
if (func) then
_rawset (self, hookType.."Hook", func)
else
_rawset (self, hookType.."Hook", nil)
end
end
------------------------------------------------------------------------------------------------------------
--> scripts
function PanelMetaFunctions:RunGradient (cancel)
if (type (cancel) == "boolean" and not canceal) then
local _r, _g, _b, _a = self.frame:GetBackdropColor()
if (_r) then
local OnLeaveColors = self.frame.Gradient.OnLeave
gump:GradientEffect (self.frame, "frame", _r, _g, _b, _a, OnLeaveColors[1], OnLeaveColors[2], OnLeaveColors[3], OnLeaveColors[4], .3)
end
else
local _r, _g, _b, _a = self.frame:GetBackdropColor()
if (_r) then
local OnEnterColors = self.frame.Gradient.OnEnter
gump:GradientEffect (self.frame, "frame", _r, _g, _b, _a, OnEnterColors[1], OnEnterColors[2], OnEnterColors[3], OnEnterColors[4], .3)
end
end
end
local OnEnter = function (frame)
if (frame.MyObject.OnEnterHook) then
local interrupt = frame.MyObject.OnEnterHook (frame)
if (interrupt) then
return
end
end
if (frame.MyObject.GradientEnabled) then
frame.MyObject:RunGradient()
end
if (frame.MyObject.have_tooltip) then
GameCooltip:Reset()
GameCooltip:SetType ("tooltip")
GameCooltip:SetColor ("main", "transparent")
GameCooltip:AddLine (frame.MyObject.have_tooltip)
GameCooltip:SetOwner (frame)
GameCooltip:ShowCooltip()
end
end
local OnLeave = function (frame)
if (frame.MyObject.OnLeaveHook) then
local interrupt = frame.MyObject.OnLeaveHook (frame)
if (interrupt) then
return
end
end
if (frame.MyObject.GradientEnabled) then
frame.MyObject:RunGradient (false)
end
if (frame.MyObject.have_tooltip) then
_detalhes.popup:ShowMe (false)
end
end
local OnHide = function (frame)
if (frame.MyObject.OnHideHook) then
local interrupt = frame.MyObject.OnHideHook (frame)
if (interrupt) then
return
end
end
end
local OnShow = function (frame)
if (frame.MyObject.OnShowHook) then
local interrupt = frame.MyObject.OnShowHook (frame)
if (interrupt) then
return
end
end
end
local OnMouseDown = function (frame, button)
if (frame.MyObject.OnMouseDownHook) then
local interrupt = frame.MyObject.OnMouseDownHook (frame, button)
if (interrupt) then
return
end
end
if (frame.MyObject.container == UIParent) then
if (not frame.isLocked and frame:IsMovable()) then
frame.isMoving = true
frame:StartMoving()
end
elseif (not frame.MyObject.container.isLocked and frame.MyObject.container:IsMovable()) then
if (not frame.isLocked and frame:IsMovable()) then
frame.MyObject.container.isMoving = true
frame.MyObject.container:StartMoving()
end
end
end
local OnMouseUp = function (frame, button)
if (frame.MyObject.OnMouseUpHook) then
local interrupt = frame.MyObject.OnMouseUpHook (frame, button)
if (interrupt) then
return
end
end
if (button == "RightButton" and frame.MyObject.rightButtonClose) then
frame.MyObject:Hide()
end
if (frame.MyObject.container == UIParent) then
if (frame.isMoving) then
frame:StopMovingOrSizing()
frame.isMoving = false
end
else
if (frame.MyObject.container.isMoving) then
frame.MyObject.container:StopMovingOrSizing()
frame.MyObject.container.isMoving = false
end
end
end
------------------------------------------------------------------------------------------------------------
--> object constructor
function gump:NewPanel (parent, container, name, member, w, h, backdrop, backdropcolor, bordercolor)
if (not name) then
return nil
elseif (not parent) then
parent = UIParent
end
if (not container) then
container = parent
end
if (name:find ("$parent")) then
name = name:gsub ("$parent", parent:GetName())
end
local PanelObject = {type = "panel", dframework = true}
if (member) then
parent [member] = PanelObject
end
if (parent.dframework) then
parent = parent.widget
end
if (container.dframework) then
container = container.widget
end
--> default members:
--> hooks
PanelObject.OnEnterHook = nil
PanelObject.OnLeaveHook = nil
PanelObject.OnHideHook = nil
PanelObject.OnShowHook = nil
PanelObject.OnMouseDownHook = nil
PanelObject.OnMouseUpHook = nil
--> misc
PanelObject.is_locked = true
PanelObject.GradientEnabled = true
PanelObject.container = container
PanelObject.rightButtonClose = false
PanelObject.frame = CreateFrame ("frame", name, parent, "DetailsPanelTemplate")
PanelObject.widget = PanelObject.frame
if (not APIFrameFunctions) then
APIFrameFunctions = {}
local idx = getmetatable (PanelObject.frame).__index
for funcName, funcAddress in pairs (idx) do
if (not PanelMetaFunctions [funcName]) then
PanelMetaFunctions [funcName] = function (object, ...)
local x = loadstring ( "return _G."..object.frame:GetName()..":"..funcName.."(...)")
return x (...)
end
end
end
end
PanelObject.frame:SetWidth (w or 100)
PanelObject.frame:SetHeight (h or 100)
PanelObject.frame.MyObject = PanelObject
--> hooks
PanelObject.frame:SetScript ("OnEnter", OnEnter)
PanelObject.frame:SetScript ("OnLeave", OnLeave)
PanelObject.frame:SetScript ("OnHide", OnHide)
PanelObject.frame:SetScript ("OnShow", OnShow)
PanelObject.frame:SetScript ("OnMouseDown", OnMouseDown)
PanelObject.frame:SetScript ("OnMouseUp", OnMouseUp)
_setmetatable (PanelObject, PanelMetaFunctions)
if (backdrop) then
PanelObject:SetBackdrop (backdrop)
elseif (_type (backdrop) == "boolean") then
PanelObject.frame:SetBackdrop (nil)
end
if (backdropcolor) then
PanelObject:SetBackdropColor (backdropcolor)
end
if (bordercolor) then
PanelObject:SetBackdropBorderColor (bordercolor)
end
return PanelObject
end
+32
View File
@@ -0,0 +1,32 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/ .. \FrameXML\UI.xsd">
<Script file="panel.lua"/>
<Frame name="DetailsPanelTemplate" virtual="true">
<Size x="100" y="100"/>
<Backdrop bgFile="Interface\DialogFrame\UI-DialogBox-Background" edgeFile="Interface\DialogFrame\UI-DialogBox-Border" tile="true">
<EdgeSize>
<AbsValue val="10"/>
</EdgeSize>
<TileSize>
<AbsValue val="16"/>
</TileSize>
<BackgroundInsets>
<AbsInset left="1" right="1" top="0" bottom="1"/>
</BackgroundInsets>
</Backdrop>
<Scripts>
<OnLoad>
self.Gradient = {
["OnEnter"] = {0.3, 0.3, 0.3, 0.5},
["OnLeave"] = {0.9, 0.7, 0.7, 1}
}
</OnLoad>
</Scripts>
</Frame>
</Ui>
+234
View File
@@ -0,0 +1,234 @@
--> details main objects
local _detalhes = _G._detalhes
local gump = _detalhes.gump
local _rawset = rawset --> lua local
local _rawget = rawget --> lua local
local _setmetatable = setmetatable --> lua local
local _unpack = unpack --> lua local
local _type = type --> lua local
local _math_floor = math.floor --> lua local
local loadstring = loadstring --> lua local
local cleanfunction = function() end
local APIImageFunctions = false
local ImageMetaFunctions = {}
------------------------------------------------------------------------------------------------------------
--> metatables
ImageMetaFunctions.__call = function (_table, value)
return self.image:SetTexture (value)
end
------------------------------------------------------------------------------------------------------------
--> members
--> shown
local gmember_shown = function (_object)
return _object:IsShown()
end
--> frame width
local gmember_width = function (_object)
return _object.image:GetWidth()
end
--> frame height
local gmember_height = function (_object)
return _object.image:GetHeight()
end
--> texture
local gmember_texture = function (_object)
return _object.image:GetTexture()
end
--> alpha
local gmember_alpha = function (_object)
return _object.image:GetAlpha()
end
local get_members_function_index = {
["shown"] = gmember_shown,
["alpha"] = gmember_alpha,
["width"] = gmember_width,
["height"] = gmember_height,
["texture"] = gmember_texture,
}
ImageMetaFunctions.__index = function (_table, _member_requested)
local func = get_members_function_index [_member_requested]
if (func) then
return func (_table, _member_requested)
end
local fromMe = _rawget (_table, _member_requested)
if (fromMe) then
return fromMe
end
return ImageMetaFunctions [_member_requested]
end
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> show
local smember_show = function (_object, _value)
if (_value) then
return _object:Show()
else
return _object:Hide()
end
end
--> hide
local smember_hide = function (_object, _value)
if (not _value) then
return _object:Show()
else
return _object:Hide()
end
end
--> texture
local smember_texture = function (_object, _value)
return _object.image:SetTexture (_value)
end
--> width
local smember_width = function (_object, _value)
return _object.image:SetWidth (_value)
end
--> height
local smember_height = function (_object, _value)
return _object.image:SetHeight (_value)
end
--> alpha
local smember_alpha = function (_object, _value)
return _object.image:SetAlpha (_value)
end
--> color
local smember_color = function (_object, _value)
local _value1, _value2, _value3 = gump:ParseColors (_value)
return _object.image:SetTexture (_value1, _value2, _value3)
end
local set_members_function_index = {
["show"] = smember_show,
["hide"] = smember_hide,
["alpha"] = smember_alpha,
["width"] = smember_width,
["height"] = smember_height,
["texture"] = smember_texture,
["color"] = smember_color,
}
ImageMetaFunctions.__newindex = function (_table, _key, _value)
local func = set_members_function_index [_key]
if (func) then
return func (_table, _value)
else
return _rawset (_table, _key, _value)
end
end
------------------------------------------------------------------------------------------------------------
--> methods
--> show & hide
function ImageMetaFunctions:IsShown()
return self.image:IsShown()
end
function ImageMetaFunctions:Show()
return self.image:Show()
end
function ImageMetaFunctions:Hide()
return self.image:Hide()
end
-- setpoint
function ImageMetaFunctions:SetPoint (v1, v2, v3, v4, v5)
v1, v2, v3, v4, v5 = gump:CheckPoints (v1, v2, v3, v4, v5, self)
if (not v1) then
print ("Invalid parameter for SetPoint")
return
end
return self.widget:SetPoint (v1, v2, v3, v4, v5)
end
-- sizes
function ImageMetaFunctions:SetSize (w, h)
if (w) then
self.image:SetWidth (w)
end
if (h) then
return self.image:SetHeight (h)
end
end
------------------------------------------------------------------------------------------------------------
--> scripts
------------------------------------------------------------------------------------------------------------
--> object constructor
function gump:NewImage (parent, container, name, member, w, h, texture, layer)
if (not parent) then
return nil
end
if (not container) then
container = parent
end
if (not name) then
name = "DetailsPictureNumber" .. gump.PictureNameCounter
gump.PictureNameCounter = gump.PictureNameCounter + 1
end
if (name:find ("$parent")) then
name = name:gsub ("$parent", parent:GetName())
end
local ImageObject = {type = "image", dframework = true}
if (member) then
parent [member] = ImageObject
end
if (parent.dframework) then
parent = parent.widget
end
if (container.dframework) then
container = container.widget
end
texture = texture or ""
ImageObject.image = parent:CreateTexture (name, layer or "OVERLAY")
ImageObject.widget = ImageObject.image
if (not APIImageFunctions) then
APIImageFunctions = true
local idx = getmetatable (ImageObject.image).__index
for funcName, funcAddress in pairs (idx) do
if (not ImageMetaFunctions [funcName]) then
ImageMetaFunctions [funcName] = function (object, ...)
local x = loadstring ( "return _G."..object.image:GetName()..":"..funcName.."(...)")
return x (...)
end
end
end
end
ImageObject.image.MyObject = ImageObject
if (w) then
ImageObject.image:SetWidth (w)
end
if (h) then
ImageObject.image:SetHeight (h)
end
if (texture) then
ImageObject.image:SetTexture (texture)
end
setmetatable (ImageObject, ImageMetaFunctions)
return ImageObject
end
+474
View File
@@ -0,0 +1,474 @@
local _detalhes = _G._detalhes
local g = _detalhes.gump
local window = g:NewPanel (UIParent, _, "DetailsImageEdit", _, 100, 100, false)
window:SetPoint ("center", UIParent, "center")
window:SetResizable (true)
window:SetMovable (true)
tinsert (UISpecialFrames, "DetailsImageEdit")
local background = g:NewImage (window, _, "$parentBackground", _, _, _, nil, "background")
background:SetAllPoints()
background:SetTexture (0, 0, 0, .8)
local edit_texture = g:NewImage (window, _, "$parentImage", _, _, _, nil, "artwork")
edit_texture:SetPoint ("center", window, "center")
local haveHFlip = false
local haveVFlip = false
--> Top Slider
local topCoordTexture = g:NewImage (window, _, "$parentImageTopCoord", _, _, _, _, "overlay")
topCoordTexture:SetPoint ("topleft", window, "topleft")
topCoordTexture:SetPoint ("topright", window, "topright")
topCoordTexture.color = "red"
topCoordTexture.height = 1
topCoordTexture.alpha = .2
local topSlider = g:NewSlider (window, _, "$parentTopSlider", "topSlider", 100, 100, 0.1, 100, 0.1, 0)
topSlider:SetAllPoints (window.widget)
topSlider:SetOrientation ("VERTICAL")
topSlider.backdrop = nil
topSlider.fractional = true
topSlider:SetHook ("OnEnter", function() return true end)
topSlider:SetHook ("OnLeave", function() return true end)
local topSliderThumpTexture = topSlider:CreateTexture (nil, "overlay")
topSliderThumpTexture:SetTexture (1, 1, 1)
topSliderThumpTexture:SetWidth (512)
topSliderThumpTexture:SetHeight (3)
topSlider:SetThumbTexture (topSliderThumpTexture)
topSlider:SetHook ("OnValueChange", function (_, _, value)
topCoordTexture.image:SetHeight (window.frame:GetHeight()/100*value)
end)
topSlider:Hide()
--> Bottom Slider
local bottomCoordTexture = g:NewImage (window, _, "$parentImageBottomCoord", _, _, _, _, "overlay")
bottomCoordTexture:SetPoint ("bottomleft", window, "bottomleft", 0, 0)
bottomCoordTexture:SetPoint ("bottomright", window, "bottomright", 0, 0)
bottomCoordTexture.color = "red"
bottomCoordTexture.height = 1
bottomCoordTexture.alpha = .2
local bottomSlider= g:NewSlider (window, _, "$parentBottomSlider", "bottomSlider", 100, 100, 0.1, 100, 0.1, 100)
bottomSlider:SetAllPoints (window.widget)
bottomSlider:SetOrientation ("VERTICAL")
bottomSlider.backdrop = nil
bottomSlider.fractional = true
bottomSlider:SetHook ("OnEnter", function() return true end)
bottomSlider:SetHook ("OnLeave", function() return true end)
local bottomSliderThumpTexture = bottomSlider:CreateTexture (nil, "overlay")
bottomSliderThumpTexture:SetTexture (1, 1, 1)
bottomSliderThumpTexture:SetWidth (512)
bottomSliderThumpTexture:SetHeight (3)
bottomSlider:SetThumbTexture (bottomSliderThumpTexture)
bottomSlider:SetHook ("OnValueChange", function (_, _, value)
value = math.abs (value-100)
bottomCoordTexture.image:SetHeight (math.max (window.frame:GetHeight()/100*value, 1))
end)
bottomSlider:Hide()
--> Left Slider
local leftCoordTexture = g:NewImage (window, _, "$parentImageLeftCoord", _, _, _, _, "overlay")
leftCoordTexture:SetPoint ("topleft", window, "topleft", 0, 0)
leftCoordTexture:SetPoint ("bottomleft", window, "bottomleft", 0, 0)
leftCoordTexture.color = "red"
leftCoordTexture.width = 1
leftCoordTexture.alpha = .2
local leftSlider = g:NewSlider (window, _, "$parentLeftSlider", "leftSlider", 100, 100, 0.1, 100, 0.1, 0.1)
leftSlider:SetAllPoints (window.widget)
leftSlider.backdrop = nil
leftSlider.fractional = true
leftSlider:SetHook ("OnEnter", function() return true end)
leftSlider:SetHook ("OnLeave", function() return true end)
local leftSliderThumpTexture = leftSlider:CreateTexture (nil, "overlay")
leftSliderThumpTexture:SetTexture (1, 1, 1)
leftSliderThumpTexture:SetWidth (3)
leftSliderThumpTexture:SetHeight (512)
leftSlider:SetThumbTexture (leftSliderThumpTexture)
leftSlider:SetHook ("OnValueChange", function (_, _, value)
leftCoordTexture.image:SetWidth (window.frame:GetWidth()/100*value)
end)
leftSlider:Hide()
--> Right Slider
local rightCoordTexture = g:NewImage (window, _, "$parentImageRightCoord", _, _, _, _, "overlay")
rightCoordTexture:SetPoint ("topright", window, "topright", 0, 0)
rightCoordTexture:SetPoint ("bottomright", window, "bottomright", 0, 0)
rightCoordTexture.color = "red"
rightCoordTexture.width = 1
rightCoordTexture.alpha = .2
local rightSlider = g:NewSlider (window, _, "$parentRightSlider", "rightSlider", 100, 100, 0.1, 100, 0.1, 100)
rightSlider:SetAllPoints (window.widget)
rightSlider.backdrop = nil
rightSlider.fractional = true
rightSlider:SetHook ("OnEnter", function() return true end)
rightSlider:SetHook ("OnLeave", function() return true end)
--[
local rightSliderThumpTexture = rightSlider:CreateTexture (nil, "overlay")
rightSliderThumpTexture:SetTexture (1, 1, 1)
rightSliderThumpTexture:SetWidth (3)
rightSliderThumpTexture:SetHeight (512)
rightSlider:SetThumbTexture (rightSliderThumpTexture)
--]]
rightSlider:SetHook ("OnValueChange", function (_, _, value)
value = math.abs (value-100)
rightCoordTexture.image:SetWidth (math.max (window.frame:GetWidth()/100*value, 1))
end)
rightSlider:Hide()
--> Edit Buttons
local buttonsBackground = g:NewPanel (UIParent, _, "DetailsImageEditButtonsBg", _, 115, 225)
buttonsBackground:SetPoint ("topleft", window, "topright", 2, 0)
buttonsBackground:Hide()
--buttonsBackground:SetMovable (true)
tinsert (UISpecialFrames, "DetailsImageEditButtonsBg")
local alphaFrameShown = false
local editingSide = nil
local lastButton = nil
local alphaFrame
local originalColor = {0.9999, 0.8196, 0}
local enableTexEdit = function (side, _, button)
if (alphaFrameShown) then
alphaFrame:Hide()
alphaFrameShown = false
button.text:SetTextColor (unpack (originalColor))
end
if (ColorPickerFrame:IsShown()) then
ColorPickerFrame:Hide()
end
if (lastButton) then
lastButton.text:SetTextColor (unpack (originalColor))
end
if (editingSide == side) then
window [editingSide.."Slider"]:Hide()
editingSide = nil
return
elseif (editingSide) then
window [editingSide.."Slider"]:Hide()
end
editingSide = side
button.text:SetTextColor (1, 1, 1)
lastButton = button
window [side.."Slider"]:Show()
end
local leftTexCoordButton = g:NewButton (buttonsBackground, _, "$parentLeftTexButton", _, 100, 20, enableTexEdit, "left", _, _, "Crop Left")
leftTexCoordButton:SetPoint ("topleft", window, "topright", 10, -10)
local rightTexCoordButton = g:NewButton (buttonsBackground, _, "$parentRightTexButton", _, 100, 20, enableTexEdit, "right", _, _, "Crop Right")
rightTexCoordButton:SetPoint ("topleft", window, "topright", 10, -30)
local topTexCoordButton = g:NewButton (buttonsBackground, _, "$parentTopTexButton", _, 100, 20, enableTexEdit, "top", _, _, "Crop Top")
topTexCoordButton:SetPoint ("topleft", window, "topright", 10, -50)
local bottomTexCoordButton = g:NewButton (buttonsBackground, _, "$parentBottomTexButton", _, 100, 20, enableTexEdit, "bottom", _, _, "Crop Bottom")
bottomTexCoordButton:SetPoint ("topleft", window, "topright", 10, -70)
leftTexCoordButton:InstallCustomTexture()
rightTexCoordButton:InstallCustomTexture()
topTexCoordButton:InstallCustomTexture()
bottomTexCoordButton:InstallCustomTexture()
local Alpha = g:NewButton (buttonsBackground, _, "$parentBottomAlphaButton", _, 100, 20, alpha, _, _, _, "Transparency")
Alpha:SetPoint ("topleft", window, "topright", 10, -110)
Alpha:InstallCustomTexture()
--> overlay color
local selectedColor = function (default)
if (default) then
edit_texture:SetVertexColor (unpack (default))
else
edit_texture:SetVertexColor (ColorPickerFrame:GetColorRGB())
end
end
local changeColor = function()
ColorPickerFrame.func = nil
ColorPickerFrame.opacityFunc = nil
ColorPickerFrame.cancelFunc = nil
ColorPickerFrame.previousValues = nil
local r, g, b = edit_texture:GetVertexColor()
ColorPickerFrame:SetColorRGB (r, g, b)
ColorPickerFrame:SetParent (buttonsBackground.widget)
ColorPickerFrame.hasOpacity = false
ColorPickerFrame.previousValues = {r, g, b}
ColorPickerFrame.func = selectedColor
ColorPickerFrame.cancelFunc = selectedColor
ColorPickerFrame:ClearAllPoints()
ColorPickerFrame:SetPoint ("left", buttonsBackground.widget, "right")
ColorPickerFrame:Show()
if (alphaFrameShown) then
alphaFrame:Hide()
alphaFrameShown = false
Alpha.button.text:SetTextColor (unpack (originalColor))
end
if (lastButton) then
lastButton.text:SetTextColor (unpack (originalColor))
if (editingSide) then
window [editingSide.."Slider"]:Hide()
end
end
end
local changeColorButton = g:NewButton (buttonsBackground, _, "$parentOverlayColorButton", _, 100, 20, changeColor, _, _, _, "Overlay Color")
changeColorButton:SetPoint ("topleft", window, "topright", 10, -90)
changeColorButton:InstallCustomTexture()
alphaFrame = g:NewPanel (buttonsBackground, _, "DetailsImageEditAlphaBg", _, 40, 225)
alphaFrame:SetPoint ("topleft", buttonsBackground, "topright", 2, 0)
alphaFrame:Hide()
local alphaSlider = g:NewSlider (alphaFrame, _, "$parentAlphaSlider", "alphaSlider", 30, 220, 1, 100, 1, edit_texture:GetAlpha()*100)
alphaSlider:SetPoint ("top", alphaFrame, "top", 0, -5)
alphaSlider:SetOrientation ("VERTICAL")
alphaSlider.thumb:SetSize (40, 30)
--leftSlider.backdrop = nil
--leftSlider.fractional = true
local alpha = function(_, _, button)
if (ColorPickerFrame:IsShown()) then
ColorPickerFrame:Hide()
end
if (lastButton) then
lastButton.text:SetTextColor (unpack (originalColor))
if (editingSide) then
window [editingSide.."Slider"]:Hide()
end
end
if (not alphaFrameShown) then
alphaFrame:Show()
alphaSlider:SetValue (edit_texture:GetAlpha()*100)
alphaFrameShown = true
button.text:SetTextColor (1, 1, 1)
else
alphaFrame:Hide()
alphaFrameShown = false
button.text:SetTextColor (unpack (originalColor))
end
end
Alpha.clickfunction = alpha
alphaSlider:SetHook ("OnValueChange", function (_, _, value)
edit_texture:SetAlpha (value/100)
end)
local resizer = CreateFrame ("Button", nil, window.widget)
resizer:SetNormalTexture ("Interface\\AddOns\\Details\\images\\ResizeGripD")
resizer:SetHighlightTexture ("Interface\\AddOns\\Details\\images\\ResizeGripD")
resizer:SetWidth (16)
resizer:SetHeight (16)
resizer:SetPoint ("BOTTOMRIGHT", window.widget, "BOTTOMRIGHT", 0, 0)
resizer:EnableMouse (true)
resizer:SetFrameLevel (window.widget:GetFrameLevel() + 2)
resizer:SetScript ("OnMouseDown", function (self, button)
window.widget:StartSizing ("BOTTOMRIGHT")
end)
resizer:SetScript ("OnMouseUp", function (self, button)
window.widget:StopMovingOrSizing()
end)
window.widget:SetScript ("OnMouseDown", function()
window.widget:StartMoving()
end)
window.widget:SetScript ("OnMouseUp", function()
window.widget:StopMovingOrSizing()
end)
window.widget:SetScript ("OnSizeChanged", function()
edit_texture.width = window.width
edit_texture.height = window.height
leftSliderThumpTexture:SetHeight (window.height)
rightSliderThumpTexture:SetHeight (window.height)
topSliderThumpTexture:SetWidth (window.width)
bottomSliderThumpTexture:SetWidth (window.width)
rightCoordTexture.image:SetWidth (math.max ( (window.frame:GetWidth() / 100 * math.abs (rightSlider:GetValue()-100)), 1))
leftCoordTexture.image:SetWidth (window.frame:GetWidth()/100*leftSlider:GetValue())
bottomCoordTexture:SetHeight (math.max ( (window.frame:GetHeight() / 100 * math.abs (bottomSlider:GetValue()-100)), 1))
topCoordTexture:SetHeight (window.frame:GetHeight()/100*topSlider:GetValue())
end)
--> change size
local resizeLabel = g:NewLabel (window, _, "$parentResizerIndicator", _, "RESIZE", _, 9)
resizeLabel:SetPoint ("right", resizer, "left", -2, 0)
--> flip
local flip = function (side)
if (side == 1) then
if (not haveHFlip) then
if (not haveVFlip) then
edit_texture:SetTexCoord (1, 0, 0, 1)
else
edit_texture:SetTexCoord (1, 0, 1, 0)
end
rightCoordTexture:Hide()
leftCoordTexture:Hide()
leftTexCoordButton:Disable()
rightTexCoordButton:Disable()
else
if (not haveVFlip) then
edit_texture:SetTexCoord (0, 1, 0, 1)
else
edit_texture:SetTexCoord (0, 1, 1, 0)
end
rightCoordTexture:Show()
leftCoordTexture:Show()
leftTexCoordButton:Enable()
rightTexCoordButton:Enable()
end
haveHFlip = not haveHFlip
elseif (side == 2) then
if (not haveVFlip) then
if (not haveHFlip) then
edit_texture:SetTexCoord (0, 1, 1, 0)
else
edit_texture:SetTexCoord (1, 0, 1, 0)
end
topCoordTexture:Hide()
bottomCoordTexture:Hide()
topTexCoordButton:Disable()
bottomTexCoordButton:Disable()
else
if (not haveHFlip) then
edit_texture:SetTexCoord (0, 1, 0, 1)
else
edit_texture:SetTexCoord (1, 0, 0, 1)
end
topCoordTexture:Show()
bottomCoordTexture:Show()
topTexCoordButton:Enable()
bottomTexCoordButton:Enable()
end
haveVFlip = not haveVFlip
end
end
local flipButtonH = g:NewButton (buttonsBackground, _, "$parentFlipButton", _, 100, 20, flip, 1, _, _, "Flip Horizontal")
flipButtonH:SetPoint ("topleft", window, "topright", 10, -140)
flipButtonH:InstallCustomTexture()
--
local flipButtonV = g:NewButton (buttonsBackground, _, "$parentFlipButton2", _, 100, 20, flip, 2, _, _, "Flip Vertical")
flipButtonV:SetPoint ("topleft", window, "topright", 10, -160)
flipButtonV:InstallCustomTexture()
--> accept
local accept = function()
buttonsBackground:Hide()
window:Hide()
alphaFrame:Hide()
ColorPickerFrame:Hide()
local coords = {}
if (haveHFlip) then
coords [1] = 1
coords [2] = 0
else
coords [1] = leftSlider.value/100
coords [2] = rightSlider.value /100
end
if (haveVFlip) then
coords [3] = 1
coords [4] = 0
else
coords [3] = topSlider.value/100
coords [4] = bottomSlider.value/100
end
return window.callback_func (edit_texture.width, edit_texture.height, {edit_texture:GetVertexColor()}, edit_texture:GetAlpha(), coords)
end
local acceptButton = g:NewButton (buttonsBackground, _, "$parentAcceptButton", _, 100, 20, accept, _, _, _, "DONE")
acceptButton:SetPoint ("topleft", window, "topright", 10, -200)
acceptButton:InstallCustomTexture()
-- fazer botao de editar a cor
-- fazer botao de editar o tamanho
-- fazer botao de okey e retornar os valores
window:Hide()
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
local ttexcoord
function g:ImageEditor (callback, texture, texcoord, colors)
edit_texture:SetTexture (texture)
colors = colors or {1, 1, 1, 1}
edit_texture:SetVertexColor (colors [1], colors [2], colors [3])
edit_texture:SetAlpha (colors [4] or 1)
texcoord = texcoord or {0, 1, 0, 1}
ttexcoord = texcoord
_detalhes:ScheduleTimer ("RefreshImageEditor", 0.2)
window:Show()
window.callback_func = callback
buttonsBackground:Show()
end
function _detalhes:RefreshImageEditor()
window.width = edit_texture.width
window.height = edit_texture.height
if (ttexcoord[1] == 1 and ttexcoord[2] == 0) then
haveHFlip = false
flip (1)
else
haveHFlip = true
flip (1)
leftSlider:SetValue (ttexcoord[1]*100)
rightSlider:SetValue (ttexcoord[2]*100)
end
if (ttexcoord[3] == 1 and ttexcoord[4] == 0) then
haveVFlip = false
flip (2)
else
haveVFlip = true
flip (2)
topSlider:SetValue (ttexcoord[3]*100)
bottomSlider:SetValue (ttexcoord[4]*100)
end
end
+526
View File
@@ -0,0 +1,526 @@
--> details main objects
local _detalhes = _G._detalhes
local gump = _detalhes.gump
local _rawset = rawset --> lua local
local _rawget = rawget --> lua local
local _setmetatable = setmetatable --> lua local
local _unpack = unpack --> lua local
local _type = type --> lua local
local _math_floor = math.floor --> lua local
local loadstring = loadstring --> lua local
local cleanfunction = function() end
local APISliderFunctions = false
local SliderMetaFunctions = {}
------------------------------------------------------------------------------------------------------------
--> metatables
SliderMetaFunctions.__call = function (_table, value)
if (not value) then
return _table.slider:GetValue()
else
return _table.slider:SetValue (value)
end
end
------------------------------------------------------------------------------------------------------------
--> members
--> tooltip
local gmember_tooltip = function (_object)
return _object:GetTooltip()
end
--> shown
local gmember_shown = function (_object)
return _object:IsShown()
end
--> frame width
local gmember_width = function (_object)
return _object.slider:GetWidth()
end
--> frame height
local gmember_height = function (_object)
return _object.slider:GetHeight()
end
--> locked
local gmember_locked = function (_object)
return _rawget (_object, "lockdown")
end
--> fractional
local gmember_fractional = function (_object, _value)
return _rawget (_object, "useDecimals")
end
local get_members_function_index = {
["tooltip"] = gmember_tooltip,
["shown"] = gmember_shown,
["width"] = gmember_width,
["height"] = gmember_height,
["locked"] = gmember_locked,
["fractional"] = gmember_fractional,
}
SliderMetaFunctions.__index = function (_table, _member_requested)
local func = get_members_function_index [_member_requested]
if (func) then
return func (_table, _member_requested)
end
local fromMe = _rawget (_table, _member_requested)
if (fromMe) then
return fromMe
end
return SliderMetaFunctions [_member_requested]
end
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> tooltip
local smember_tooltip = function (_object, _value)
return _object:SetTooltip (_value)
end
--> show
local smember_show = function (_object, _value)
if (_value) then
return _object:Show()
else
return _object:Hide()
end
end
--> hide
local smember_hide = function (_object, _value)
if (not _value) then
return _object:Show()
else
return _object:Hide()
end
end
--> frame width
local smember_width = function (_object, _value)
return _object.slider:SetWidth (_value)
end
--> frame height
local smember_height = function (_object, _value)
return _object.slider:SetHeight (_value)
end
--> locked
local smember_locked = function (_object, _value)
if (_value) then
return self:Disable()
else
return self:Enable()
end
end
--> backdrop
local smember_backdrop = function (_object, _value)
return _object.slider:SetBackdrop (_value)
end
--> fractional
local smember_fractional = function (_object, _value)
return _rawset (_object, "useDecimals", _value)
end
local set_members_function_index = {
["tooltip"] = smember_tooltip,
["show"] = smember_show,
["hide"] = smember_hide,
["backdrop"] = smember_backdrop,
["width"] = smember_width,
["height"] = smember_height,
["locked"] = smember_locked,
["fractional"] = smember_fractional,
}
SliderMetaFunctions.__newindex = function (_table, _key, _value)
local func = set_members_function_index [_key]
if (func) then
return func (_table, _value)
else
return _rawset (_table, _key, _value)
end
end
------------------------------------------------------------------------------------------------------------
--> methods
--> show & hide
function SliderMetaFunctions:IsShown()
return self.slider:IsShown()
end
function SliderMetaFunctions:Show()
return self.slider:Show()
end
function SliderMetaFunctions:Hide()
return self.slider:Hide()
end
--> fixed value
function SliderMetaFunctions:SetFixedParameter (value)
_rawset (self, "FixedValue", value)
end
-- thumb size
function SliderMetaFunctions:SetThumbSize (w, h)
if (not w) then
w = self.thumb:GetWidth()
end
if (not h) then
h = self.thumb:GetHeight()
end
return self.thumb:SetSize (w, h)
end
-- setpoint
function SliderMetaFunctions:SetPoint (v1, v2, v3, v4, v5)
v1, v2, v3, v4, v5 = gump:CheckPoints (v1, v2, v3, v4, v5, self)
if (not v1) then
print ("Invalid parameter for SetPoint")
return
end
return self.widget:SetPoint (v1, v2, v3, v4, v5)
end
-- sizes
function SliderMetaFunctions:SetSize (w, h)
if (w) then
self.slider:SetWidth (w)
end
if (h) then
return self.slider:SetHeight (h)
end
end
-- tooltip
function SliderMetaFunctions:SetTooltip (tooltip)
if (tooltip) then
return _rawset (self, "have_tooltip", tooltip)
else
return _rawset (self, "have_tooltip", nil)
end
end
function SliderMetaFunctions:GetTooltip()
return _rawget (self, "have_tooltip")
end
-- frame levels
function SliderMetaFunctions:GetFrameLevel()
return self.slider:GetFrameLevel()
end
function SliderMetaFunctions:SetFrameLevel (level, frame)
if (not frame) then
return self.slider:SetFrameLevel (level)
else
local framelevel = frame:GetFrameLevel (frame) + level
return self.slider:SetFrameLevel (framelevel)
end
end
-- frame stratas
function SliderMetaFunctions:SetFrameStrata()
return self.slider:GetFrameStrata()
end
function SliderMetaFunctions:SetFrameStrata (strata)
if (_type (strata) == "table") then
self.slider:SetFrameStrata (strata:GetFrameStrata())
else
self.slider:SetFrameStrata (strata)
end
end
-- enabled
function SliderMetaFunctions:IsEnabled()
return not _rawget (self, "lockdown")
end
function SliderMetaFunctions:Enable()
self.slider:Enable()
self.slider.lock:Hide()
self.slider.amt:Show()
return _rawset (self, "lockdown", false)
end
function SliderMetaFunctions:Disable()
self.slider:Disable()
self.slider.lock:Show()
self.slider.amt:Hide()
return _rawset (self, "lockdown", true)
end
--> hooks
function SliderMetaFunctions:SetHook (hookType, func)
if (func) then
_rawset (self, hookType.."Hook", func)
else
_rawset (self, hookType.."Hook", nil)
end
end
------------------------------------------------------------------------------------------------------------
--> scripts
local OnEnter = function (slider)
if (slider.MyObject.OnEnterHook) then
local interrupt = slider.MyObject.OnEnterHook (slider)
if (interrupt) then
return
end
end
slider.thumb:SetAlpha (1)
if (slider.MyObject.have_tooltip) then
GameCooltip:Reset()
GameCooltip:AddLine (slider.MyObject.have_tooltip)
GameCooltip:ShowCooltip (slider, "tooltip")
end
local parent = slider:GetParent().MyObject
if (parent and parent.type == "panel") then
if (parent.GradientEnabled) then
parent:RunGradient()
end
end
end
local OnLeave = function (slider)
if (slider.MyObject.OnLeaveHook) then
local interrupt = slider.MyObject.OnLeaveHook (slider)
if (interrupt) then
return
end
end
slider.thumb:SetAlpha (.7)
if (slider.MyObject.have_tooltip) then
_detalhes.popup:ShowMe (false)
end
local parent = slider:GetParent().MyObject
if (parent and parent.type == "panel") then
if (parent.GradientEnabled) then
parent:RunGradient (false)
end
end
end
local OnHide = function (slider)
if (slider.MyObject.OnHideHook) then
local interrupt = slider.MyObject.OnHideHook (slider)
if (interrupt) then
return
end
end
end
local OnShow = function (slider)
if (slider.MyObject.OnShowHook) then
local interrupt = slider.MyObject.OnShowHook (slider)
if (interrupt) then
return
end
end
end
local OnValueChanged = function (slider)
local amt = slider:GetValue()
if (slider.MyObject.OnValueChangeHook) then
local interrupt = slider.MyObject.OnValueChangeHook (slider, slider.MyObject.FixedValue, amt)
if (interrupt) then
return
end
end
if (amt < 10 and amt >= 1) then
amt = "0"..amt
end
if (slider.MyObject.useDecimals) then
slider.amt:SetText (string.format ("%.1f", amt))
else
slider.amt:SetText (math.floor (amt))
end
slider.MyObject.value = amt
end
------------------------------------------------------------------------------------------------------------
--> object constructor
function gump:NewSwitch (parent, container, name, member, w, h, ltext, rtext, defaultv)
--> early checks
if (not name) then
return nil
elseif (not parent) then
return nil
end
if (not container) then
container = parent
end
--> defaults
ltext = ltext or "OFF"
rtext = rtext or "ON"
if (type (defaultv) == "boolean" and not defaultv) then
defaultv = 1
elseif (type (defaultv) == "boolean" and defaultv) then
defaultv = 2
else
defaultv = defaultv or 1
end
--> build frames
local slider = gump:NewSlider (parent, container, name, member, w, h, 1, 2, 1, defaultv)
slider:SetHook ("OnValueChange", function (self)
if (slider:GetValue() == 1) then
slider.amt:SetText (ltext)
if (slider.OnSwitch) then
slider.OnSwitch (slider, slider.FixedValue, false)
end
else
slider.amt:SetText (rtext)
if (slider.OnSwitch) then
slider.OnSwitch (slider, slider.FixedValue, true)
end
end
return true
end)
slider:SetValue (1)
slider:SetValue (2)
slider:SetValue (defaultv)
return slider
end
function gump:NewSlider (parent, container, name, member, w, h, min, max, step, defaultv, isDecemal)
--> early checks
if (not name) then
return nil
elseif (not parent) then
return nil
end
if (not container) then
container = parent
end
if (name:find ("$parent")) then
name = name:gsub ("$parent", parent:GetName())
end
local SliderObject = {type = "slider", dframework = true}
if (member) then
parent [member] = SliderObject
end
if (parent.dframework) then
parent = parent.widget
end
if (container.dframework) then
container = container.widget
end
--> defaults
min = min or 1
max = max or 2
step = step or 1
defaultv = defaultv or min
--> default members:
--> hooks
SliderObject.OnEnterHook = nil
SliderObject.OnLeaveHook = nil
SliderObject.OnHideHook = nil
SliderObject.OnShowHook = nil
SliderObject.OnValueChangeHook = nil
--> misc
SliderObject.lockdown = false
SliderObject.container = container
SliderObject.have_tooltip = nil
SliderObject.FixedValue = nil
SliderObject.useDecimals = isDecemal or false
--SliderObject.slider = CreateFrame ("slider", name, parent, "DetailsSliderTemplate")
SliderObject.slider = CreateFrame ("slider", name, parent)
SliderObject.widget = SliderObject.slider
if (not APISliderFunctions) then
APISliderFunctions = true
local idx = getmetatable (SliderObject.slider).__index
for funcName, funcAddress in pairs (idx) do
if (not SliderMetaFunctions [funcName]) then
SliderMetaFunctions [funcName] = function (object, ...)
local x = loadstring ( "return _G."..object.slider:GetName()..":"..funcName.."(...)")
return x (...)
end
end
end
end
SliderObject.slider.MyObject = SliderObject
SliderObject.slider:SetWidth (w or 232)
SliderObject.slider:SetHeight (h or 20)
SliderObject.slider:SetOrientation ("horizontal")
SliderObject.slider:SetMinMaxValues (min, max)
SliderObject.slider:SetValueStep (step)
SliderObject.slider:SetValue (defaultv)
SliderObject.value = defaultv
--SliderObject.amt = _G [name .. "_Amt"]
--SliderObject.lock = _G [name .. "_LockTexture"]
--SliderObject.thumb = _G [name .. "_ThumbTexture"]
SliderObject.slider:SetBackdrop ({edgeFile = "Interface\\Buttons\\UI-SliderBar-Border", edgeSize = 8})
SliderObject.slider:SetBackdropColor (0.9, 0.7, 0.7, 1.0)
SliderObject.thumb = SliderObject.slider:CreateTexture (nil, "artwork")
SliderObject.thumb:SetTexture ("Interface\\Buttons\\UI-ScrollBar-Knob")
--SliderObject.thumb:SetSize (30, 24)
SliderObject.thumb:SetSize (30+(h*0.2), h*1.2)
SliderObject.thumb:SetAlpha (0.7)
SliderObject.slider:SetThumbTexture (SliderObject.thumb)
SliderObject.slider.thumb = SliderObject.thumb
SliderObject.amt = SliderObject.slider:CreateFontString (nil, "overlay", "GameFontHighlightSmall")
local amt = defaultv
if (amt < 10 and amt >= 1) then
amt = "0"..amt
end
if (SliderObject.useDecimals) then
SliderObject.amt:SetText (string.format ("%.1f", amt))
else
SliderObject.amt:SetText (math.floor (amt))
end
SliderObject.amt:SetTextColor (.8, .8, .8, 1)
SliderObject.amt:SetPoint ("center", SliderObject.thumb, "center")
SliderObject.slider.amt = SliderObject.amt
--> hooks
SliderObject.slider:SetScript ("OnEnter", OnEnter)
SliderObject.slider:SetScript ("OnLeave", OnLeave)
SliderObject.slider:SetScript ("OnHide", OnHide)
SliderObject.slider:SetScript ("OnShow", OnShow)
SliderObject.slider:SetScript ("OnValueChanged", OnValueChanged)
_setmetatable (SliderObject, SliderMetaFunctions)
return SliderObject
end
+630
View File
@@ -0,0 +1,630 @@
--> details main objects
local _detalhes = _G._detalhes
local gump = _detalhes.gump
local _rawset = rawset --> lua local
local _rawget = rawget --> lua local
local _setmetatable = setmetatable --> lua local
local _unpack = unpack --> lua local
local _type = type --> lua local
local _math_floor = math.floor --> lua local
local cleanfunction = function() end
local SplitBarMetaFunctions = {}
local APISplitBarFunctions
------------------------------------------------------------------------------------------------------------
--> metatables
SplitBarMetaFunctions.__call = function (_table, value)
if (not value) then
return _table.statusbar:GetValue()
else
_table.div:SetPoint ("left", _table.statusbar, "left", value * (_table.statusbar:GetWidth()/100) - 18, 0)
return _table.statusbar:SetValue (value)
end
end
SplitBarMetaFunctions.__add = function (v1, v2)
if (_type (v1) == "table") then
local v = v1.statusbar:GetValue()
v = v + v2
v1.div:SetPoint ("left", v1.statusbar, "left", value * (v1.statusbar:GetWidth()/100) - 18, 0)
v1.statusbar:SetValue (v)
else
local v = v2.statusbar:GetValue()
v = v + v1
v2.div:SetPoint ("left", v2.statusbar, "left", value * (v2.statusbar:GetWidth()/100) - 18, 0)
v2.statusbar:SetValue (v)
end
end
SplitBarMetaFunctions.__sub = function (v1, v2)
if (_type (v1) == "table") then
local v = v1.statusbar:GetValue()
v = v - v2
v1.div:SetPoint ("left", v1.statusbar, "left", value * (v1.statusbar:GetWidth()/100) - 18, 0)
v1.statusbar:SetValue (v)
else
local v = v2.statusbar:GetValue()
v = v - v1
v2.div:SetPoint ("left", v2.statusbar, "left", value * (v2.statusbar:GetWidth()/100) - 18, 0)
v2.statusbar:SetValue (v)
end
end
------------------------------------------------------------------------------------------------------------
--> members
--> tooltip
local function gmember_tooltip (_object)
return _object:GetTooltip()
end
--> shown
local gmember_shown = function (_object)
return _object.statusbar:IsShown()
end
--> frame width
local gmember_width = function (_object)
return _object.statusbar:GetWidth()
end
--> frame height
local gmember_height = function (_object)
return _object.statusbar:GetHeight()
end
--> value
local gmember_value = function (_object)
return _object.statusbar:GetValue()
end
--> right text
local gmember_rtext = function (_object)
return _object.textright:GetText()
end
--> left text
local gmember_ltext = function (_object)
return _object.textleft:GetText()
end
--> right color
local gmember_rcolor = function (_object)
return _object.background.original_colors
end
--> left color
local gmember_lcolor = function (_object)
return _object.texture.original_colors
end
--> right icon
local gmember_ricon = function (_object)
return _object.iconright:GetTexture()
end
--> left icon
local gmember_licon = function (_object)
return _object.iconleft:GetTexture()
end
--> texture
local gmember_texture = function (_object)
return _object.texture:GetTexture()
end
--> font size
local gmember_textsize = function (_object)
local _, fontsize = _object.textleft:GetFont()
return fontsize
end
--> font face
local gmember_textfont = function (_object)
local fontface = _object.textleft:GetFont()
return fontface
end
--> font color
local gmember_textcolor = function (_object)
return _object.textleft:GetTextColor()
end
local get_members_function_index = {
["tooltip"] = gmember_tooltip,
["shown"] = gmember_shown,
["width"] = gmember_width,
["height"] = gmember_height,
["value"] = gmember_value,
["righttext"] = gmember_rtext,
["lefttext"] = gmember_ltext,
["rightcolor"] = gmember_rcolor,
["leftcolor"] = gmember_lcolor,
["righticon"] = gmember_ricon,
["lefticon"] = gmember_licon,
["texture"] = gmember_texture,
["fontsize"] = gmember_textsize,
["fontface"] = gmember_textfont,
["fontcolor"] = gmember_textcolor,
["textsize"] = gmember_textsize, --alias
["textfont"] = gmember_textfont, --alias
["textcolor"] = gmember_textcolor --alias
}
SplitBarMetaFunctions.__index = function (_table, _member_requested)
local func = get_members_function_index [_member_requested]
if (func) then
return func (_table, _member_requested)
end
local fromMe = _rawget (_table, _member_requested)
if (fromMe) then
return fromMe
end
return SplitBarMetaFunctions [_member_requested]
end
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> tooltip
local smember_tooltip = function (_object, _value)
return _object:SetTooltip (_value)
end
--> show
local smember_shown = function (_object, _value)
if (_value) then
return _object:Show()
else
return _object:Hide()
end
end
--> hide
local smember_hide = function (_object, _value)
if (_value) then
return _object:Hide()
else
return _object:Show()
end
end
--> width
local smember_width = function (_object, _value)
return _object.statusbar:SetWidth (_value)
end
--> height
local smember_height = function (_object, _value)
return _object.statusbar:SetHeight (_value)
end
--> statusbar value
local smember_value = function (_object, _value)
_object.statusbar:SetValue (_value)
return _object.div:SetPoint ("left", _object.statusbar, "left", _value * (_object.statusbar:GetWidth()/100) - 18, 0)
end
--> right text
local smember_rtext = function (_object, _value)
return _object.textright:SetText (_value)
end
--> left text
local smember_ltext = function (_object, _value)
return _object.textleft:SetText (_value)
end
--> right color
local smember_rcolor = function (_object, _value)
local _value1, _value2, _value3, _value4 = gump:ParseColors (_value)
_object.background.original_colors = {_value1, _value2, _value3, _value4}
return _object.background:SetVertexColor (_value1, _value2, _value3, _value4)
end
--> left color
local smember_lcolor = function (_object, _value)
local _value1, _value2, _value3, _value4 = gump:ParseColors (_value)
_object.statusbar:SetStatusBarColor (_value1, _value2, _value3, _value4)
_object.texture.original_colors = {_value1, _value2, _value3, _value4}
return _object.texture:SetVertexColor (_value1, _value2, _value3, _value4)
end
--> right icon
local smember_ricon = function (_object, _value)
if (type (_value) == "table") then
local _value1, _value2 = _unpack (_value)
_object.iconright:SetTexture (_value1)
if (_value2) then
_object.iconright:SetTexCoord (_unpack (_value2))
end
else
_object.iconright:SetTexture (_value)
end
return
end
--> left icon
local smember_licon = function (_object, _value)
if (type (_value) == "table") then
local _value1, _value2 = _unpack (_value)
_object.iconleft:SetTexture (_value1)
if (_value2) then
_object.iconleft:SetTexCoord (_unpack (_value2))
end
else
_object.iconleft:SetTexture (_value)
end
return
end
--> texture
local smember_texture = function (_object, _value)
if (type (_value) == "table") then
local _value1, _value2 = _unpack (_value)
_object.texture:SetTexture (_value1)
_object.background:SetTexture (_value1)
if (_value2) then
_object.texture:SetTexCoord (_unpack (_value2))
_object.background:SetTexCoord (_unpack (_value2))
end
else
_object.texture:SetTexture (_value)
_object.background:SetTexture (_value)
end
return
end
--> font face
local smember_textfont = function (_object, _value)
_detalhes:SetFontFace (_object.textleft, _value)
return _detalhes:SetFontFace (_object.textright, _value)
end
--> font size
local smember_textsize = function (_object, _value)
_detalhes:SetFontSize (_object.textleft, _value)
return _detalhes:SetFontSize (_object.textright, _value)
end
--> font color
local smember_textcolor = function (_object, _value)
local _value1, _value2, _value3, _value4 = gump:ParseColors (_value)
_object.textleft:SetTextColor (_value1, _value2, _value3, _value4)
return _object.textright:SetTextColor (_value1, _value2, _value3, _value4)
end
local set_members_function_index = {
["tooltip"] = smember_tooltip,
["shown"] = smember_shown,
["width"] = smember_width,
["height"] = smember_height,
["value"] = smember_value,
["righttext"] = smember_rtext,
["lefttext"] = smember_ltext,
["rightcolor"] = smember_rcolor,
["leftcolor"] = smember_lcolor,
["righticon"] = smember_ricon,
["lefticon"] = smember_licon,
["texture"] = smember_texture,
["fontsize"] = smember_textsize,
["fontface"] = smember_textfont,
["fontcolor"] = smember_textcolor,
["textsize"] = smember_textsize, --alias
["textfont"] = smember_textfont, --alias
["textcolor"] = smember_textcolor --alias
}
SplitBarMetaFunctions.__newindex = function (_table, _key, _value)
local func = set_members_function_index [_key]
if (func) then
return func (_table, _value)
else
return _rawset (_table, _key, _value)
end
end
------------------------------------------------------------------------------------------------------------
--> methods
--> show & hide
function SplitBarMetaFunctions:Show()
return self.statusbar:Show()
end
function SplitBarMetaFunctions:Hide()
return self.statusbar:Hide()
end
-- set split
function SplitBarMetaFunctions:SetSplit (value)
if (not value) then
value = self.statusbar:GetValue()
elseif (value < 0 or value > 100) then
return
end
self.statusbar:SetValue (value)
self.div:SetPoint ("left", self.statusbar, "left", value * (self.statusbar:GetWidth()/100) - 18, 0)
end
-- setpoint
function SplitBarMetaFunctions:SetPoint (v1, v2, v3, v4, v5)
v1, v2, v3, v4, v5 = gump:CheckPoints (v1, v2, v3, v4, v5, self)
if (not v1) then
print ("Invalid parameter for SetPoint")
return
end
return self.widget:SetPoint (v1, v2, v3, v4, v5)
end
-- sizes
function SplitBarMetaFunctions:SetSize (w, h)
if (w) then
self.statusbar:SetWidth (w)
end
if (h) then
self.statusbar:SetHeight (h)
end
end
-- texture
function SplitBarMetaFunctions:SetTexture (texture)
self.background:SetTexture (texture)
self.texture:SetTexture (texture)
end
-- texts
function SplitBarMetaFunctions:SetLeftText (text)
self.textleft:SetText (text)
end
function SplitBarMetaFunctions:SetRightText (text)
self.textright:SetText (text)
end
-- colors
function SplitBarMetaFunctions:SetLeftColor (r, g, b, a)
r, g, b, a = gump:ParseColors (r, g, b, a)
self.texture:SetVertexColor (r, g, b, a)
self.texture.original_colors = {r, g, b, a}
end
function SplitBarMetaFunctions:SetRightColor (r, g, b, a)
r, g, b, a = gump:ParseColors (r, g, b, a)
self.background:SetVertexColor (r, g, b, a)
self.background.original_colors = {r, g, b, a}
end
-- icons
function SplitBarMetaFunctions:SetLeftIcon (texture, ...)
self.iconleft:SetTexture (texture)
if (...) then
local L, R, U, D = unpack (...)
self.iconleft:SetTexCoord (L, R, U, D)
end
end
function SplitBarMetaFunctions:SetRightIcon (texture, ...)
self.iconright:SetTexture (texture)
if (...) then
local L, R, U, D = unpack (...)
self.iconright:SetTexCoord (L, R, U, D)
end
end
-- tooltip
function SplitBarMetaFunctions:SetTooltip (tooltip)
if (tooltip) then
return _rawset (self, "have_tooltip", tooltip)
else
return _rawset (self, "have_tooltip", nil)
end
end
function SplitBarMetaFunctions:GetTooltip()
return _rawget (self, "have_tooltip")
end
-- frame levels
function SplitBarMetaFunctions:GetFrameLevel()
return self.statusbar:GetFrameLevel()
end
function SplitBarMetaFunctions:SetFrameLevel (level, frame)
if (not frame) then
return self.statusbar:SetFrameLevel (level)
else
local framelevel = frame:GetFrameLevel (frame) + level
return self.statusbar:SetFrameLevel (framelevel)
end
end
-- frame stratas
function SplitBarMetaFunctions:SetFrameStrata()
return self.statusbar:GetFrameStrata()
end
function SplitBarMetaFunctions:SetFrameStrata (strata)
if (_type (strata) == "table") then
self.statusbar:SetFrameStrata (strata:GetFrameStrata())
else
self.statusbar:SetFrameStrata (strata)
end
end
--> hooks
function SplitBarMetaFunctions:SetHook (hookType, func)
if (func) then
_rawset (self, hookType.."Hook", func)
else
_rawset (self, hookType.."Hook", nil)
end
end
------------------------------------------------------------------------------------------------------------
--> scripts
local OnEnter = function (frame)
if (frame.MyObject.OnEnterHook) then
local interrupt = frame.MyObject.OnEnterHook (frame)
if (interrupt) then
return
end
end
local oc = frame.MyObject.texture.original_colors --original colors
gump:GradientEffect ( frame.MyObject.texture, "texture", oc[1], oc[2], oc[3], oc[4], oc[1]+0.2, oc[2]+0.2, oc[3]+0.2, oc[4], .2)
frame.MyObject.div:SetPoint ("left", frame, "left", frame:GetValue() * (frame:GetWidth()/100) - 18, 0)
if (frame.MyObject.have_tooltip) then
GameCooltip:Reset()
GameCooltip:AddLine (frame.MyObject.have_tooltip)
GameCooltip:ShowCooltip (frame, "tooltip")
end
local parent = frame:GetParent().MyObject
if (parent and parent.type == "panel") then
if (parent.GradientEnabled) then
parent:RunGradient()
end
end
end
local OnLeave = function (frame)
if (frame.MyObject.OnLeaveHook) then
local interrupt = frame.MyObject.OnLeaveHook (frame)
if (interrupt) then
return
end
end
local oc = frame.MyObject.texture.original_colors --original colors
local r, g, b, a = frame.MyObject.texture:GetVertexColor()
gump:GradientEffect ( frame.MyObject.texture, "texture", r, g, b, a, oc[1], oc[2], oc[3], oc[4], .2)
if (frame.MyObject.have_tooltip) then
_detalhes.popup:ShowMe (false)
end
local parent = frame:GetParent().MyObject
if (parent and parent.type == "panel") then
if (parent.GradientEnabled) then
parent:RunGradient (false)
end
end
end
local OnHide = function (frame)
if (frame.MyObject.OnHideHook) then
local interrupt = frame.MyObject.OnHideHook (frame)
if (interrupt) then
return
end
end
end
local OnShow = function (frame)
if (frame.MyObject.OnShowHook) then
local interrupt = frame.MyObject.OnShowHook (frame)
if (interrupt) then
return
end
end
end
local OnMouseDown = function (frame, button)
if (frame.MyObject.OnMouseDownHook) then
local interrupt = frame.MyObject.OnMouseDownHook (frame, button)
if (interrupt) then
return
end
end
if (not frame.MyObject.container.isLocked and frame.MyObject.container:IsMovable()) then
if (not frame.isLocked and frame:IsMovable()) then
frame.MyObject.container.isMoving = true
frame.MyObject.container:StartMoving()
end
end
end
local OnMouseUp = function (frame, button)
if (frame.MyObject.OnMouseUpHook) then
local interrupt = frame.MyObject.OnMouseUpHook (frame, button)
if (interrupt) then
return
end
end
if (frame.MyObject.container.isMoving) then
frame.MyObject.container:StopMovingOrSizing()
frame.MyObject.container.isMoving = false
end
end
------------------------------------------------------------------------------------------------------------
--> object constructor
function DetailsSplitlBar_OnCreate (self)
self.texture.original_colors = {1, 1, 1, 1}
self.background.original_colors = {.5, .5, .5, 1}
self.spark:SetPoint ("left", self, "left", self:GetValue() * (self:GetWidth()/100) - 18, 0)
return true
end
function gump:NewSplitBar (parent, container, name, member, w, h)
if (not name) then
return nil
elseif (not parent) then
return nil
elseif (not container) then
container = parent
end
if (name:find ("$parent")) then
name = name:gsub ("$parent", parent:GetName())
end
local SplitBarObject = {type = "barsplit", dframework = true}
if (member) then
parent [member] = SplitBarObject
end
if (parent.dframework) then
parent = parent.widget
end
if (container.dframework) then
container = container.widget
end
--> default members:
--> hooks
SplitBarObject.OnEnterHook = nil
SplitBarObject.OnLeaveHook = nil
SplitBarObject.OnHideHook = nil
SplitBarObject.OnShowHook = nil
SplitBarObject.OnMouseDownHook = nil
SplitBarObject.OnMouseUpHook = nil
--> misc
SplitBarObject.tooltip = nil
SplitBarObject.locked = false
SplitBarObject.have_tooltip = nil
SplitBarObject.container = container
--> create widgets
SplitBarObject.statusbar = CreateFrame ("statusbar", name, parent, "DetailsSplitBarTemplate")
SplitBarObject.widget = SplitBarObject.statusbar
if (not APISplitBarFunctions) then
APISplitBarFunctions = true
local idx = getmetatable (SplitBarObject.statusbar).__index
for funcName, funcAddress in pairs (idx) do
if (not SplitBarMetaFunctions [funcName]) then
SplitBarMetaFunctions [funcName] = function (object, ...)
local x = loadstring ( "return _G."..object.statusbar:GetName()..":"..funcName.."(...)")
return x (...)
end
end
end
end
SplitBarObject.statusbar:SetHeight (h or 200)
SplitBarObject.statusbar:SetWidth (w or 14)
SplitBarObject.statusbar.MyObject = SplitBarObject
SplitBarObject.textleft = _G [name .. "_TextLeft"]
SplitBarObject.textright = _G [name .. "_TextRight"]
SplitBarObject.iconleft = _G [name .. "_IconLeft"]
SplitBarObject.iconright = _G [name .. "_IconRight"]
SplitBarObject.background = _G [name .. "_StatusBarBackground"]
SplitBarObject.texture = _G [name .. "_StatusBarTexture"]
SplitBarObject.div = _G [name .. "_Spark"]
--> hooks
SplitBarObject.statusbar:SetScript ("OnEnter", OnEnter)
SplitBarObject.statusbar:SetScript ("OnLeave", OnLeave)
SplitBarObject.statusbar:SetScript ("OnHide", OnHide)
SplitBarObject.statusbar:SetScript ("OnShow", OnShow)
SplitBarObject.statusbar:SetScript ("OnMouseDown", OnMouseDown)
SplitBarObject.statusbar:SetScript ("OnMouseUp", OnMouseUp)
_setmetatable (SplitBarObject, SplitBarMetaFunctions)
return SplitBarObject
end
+82
View File
@@ -0,0 +1,82 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/ .. \FrameXML\UI.xsd">
<Script file="split_bar.lua"/>
<StatusBar name="DetailsSplitBarTemplate" virtual="true">
<Size x="300" y="14"/>
<Layers>
<Layer level="BACKGROUND">
<!-- background texture -->
<Texture name="$parent_StatusBarBackground" setAllPoints="true" parentKey="background" file = "Interface\PaperDollInfoFrame\UI-Character-Skills-Bar" horizTile="false" vertTile="false">
<Color a = "1" r = ".5" g = ".5" b = ".5" />
</Texture>
</Layer>
<Layer level="ARTWORK">
<!-- statusbar texture -->
<Texture name="$parent_StatusBarTexture" hidden="true" parentKey="texture" file = "Interface\PaperDollInfoFrame\UI-Character-Skills-Bar" horizTile="false" vertTile="false">
<Size x="300" y="14" />
<Color a = "1" r = "1" g = "1" b = "1" />
</Texture>
</Layer>
<Layer level="OVERLAY">
<!-- left icon -->
<Texture name="$parent_IconLeft" parentKey="lefticon">
<Size x="14" y="14" />
<Anchors>
<Anchor point="LEFT" relativeTo="$parent" relativePoint="LEFT" x="0" y="0"/>
</Anchors>
</Texture>
<!-- right icon -->
<Texture name="$parent_IconRight" parentKey="righticon">
<Size x="14" y="14" />
<Anchors>
<Anchor point="RIGHT" relativeTo="$parent" relativePoint="RIGHT" x="0" y="0"/>
</Anchors>
</Texture>
<!-- left text -->
<FontString name="$parent_TextLeft" parentKey="lefttext" inherits="GameFontHighlight" justifyH="LEFT" nonspacewrap="false">
<FontHeight val="10.5"/>
<Anchors>
<Anchor point="LEFT" relativeTo="$parent_IconLeft" relativePoint="RIGHT" x="3" y="0"/>
</Anchors>
</FontString>
<!-- right text -->
<FontString name="$parent_TextRight" parentKey="righttext" inherits="GameFontHighlight" justifyH="RIGHT" nonspacewrap="false">
<FontHeight val="10.5"/>
<Anchors>
<Anchor point="RIGHT" relativeTo="$parent_IconRight" relativePoint="LEFT" x="-3" y="0"/>
</Anchors>
</FontString>
<!-- div spark -->
<Texture name="$parent_Spark" parentKey="spark" file = "Interface\CastingBar\UI-CastingBar-Spark" alphaMode="ADD">
<Size>
<AbsDimension x="32" y="32"/>
</Size>
<Anchors>
<Anchor point="LEFT" relativeTo="$parent" relativePoint="RIGHT" x="-17" y="-1"/>
</Anchors>
</Texture>
</Layer>
</Layers>
<Scripts>
<OnLoad>
self:SetStatusBarTexture (self.texture);
self:SetMinMaxValues (1, 100);
self:SetValue (50);
DetailsSplitlBar_OnCreate (self);
</OnLoad>
</Scripts>
</StatusBar>
</Ui>
+560
View File
@@ -0,0 +1,560 @@
--> details main objects
local _detalhes = _G._detalhes
local gump = _detalhes.gump
local _rawset = rawset --> lua local
local _rawget = rawget --> lua local
local _setmetatable = setmetatable --> lua local
local _unpack = unpack --> lua local
local _type = type --> lua local
local _math_floor = math.floor --> lua local
local loadstring = loadstring --> lua local
local _string_len = string.len --> lua local
local cleanfunction = function() end
local APITextEntryFunctions = false
local TextEntryMetaFunctions = {}
------------------------------------------------------------------------------------------------------------
--> metatables
TextEntryMetaFunctions.__call = function (_table, value)
--> unknow
end
------------------------------------------------------------------------------------------------------------
--> members
--> tooltip
local gmember_tooltip = function (_object)
return _object:GetTooltip()
end
--> shown
local gmember_shown = function (_object)
return _object:IsShown()
end
--> frame width
local gmember_width = function (_object)
return _object.editbox:GetWidth()
end
--> frame height
local gmember_height = function (_object)
return _object.editbox:GetHeight()
end
--> get text
local gmember_text = function (_object)
return _object.editbox:GetText()
end
local get_members_function_index = {
["tooltip"] = gmember_tooltip,
["shown"] = gmember_shown,
["width"] = gmember_width,
["height"] = gmember_height,
["text"] = gmember_text,
}
TextEntryMetaFunctions.__index = function (_table, _member_requested)
local func = get_members_function_index [_member_requested]
if (func) then
return func (_table, _member_requested)
end
local fromMe = _rawget (_table, _member_requested)
if (fromMe) then
return fromMe
end
return TextEntryMetaFunctions [_member_requested]
end
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> tooltip
local smember_tooltip = function (_object, _value)
return _object:SetTooltip (_value)
end
--> show
local smember_show = function (_object, _value)
if (_value) then
return _object:Show()
else
return _object:Hide()
end
end
--> hide
local smember_hide = function (_object, _value)
if (not _value) then
return _object:Show()
else
return _object:Hide()
end
end
--> frame width
local smember_width = function (_object, _value)
return _object.editbox:SetWidth (_value)
end
--> frame height
local smember_height = function (_object, _value)
return _object.editbox:SetHeight (_value)
end
--> set text
local smember_text = function (_object, _value)
return _object.editbox:SetText (_value)
end
--> set multiline
local smember_multiline = function (_object, _value)
if (_value) then
return _object.editbox:SetMultiLine (true)
else
return _object.editbox:SetMultiLine (false)
end
end
--> text horizontal pos
local smember_horizontalpos = function (_object, _value)
return _object.editbox:SetJustifyH (string.lower (_value))
end
local set_members_function_index = {
["tooltip"] = smember_tooltip,
["show"] = smember_show,
["hide"] = smember_hide,
["width"] = smember_width,
["height"] = smember_height,
["text"] = smember_text,
["multiline"] = smember_multiline,
["align"] = smember_horizontalpos,
}
TextEntryMetaFunctions.__newindex = function (_table, _key, _value)
local func = set_members_function_index [_key]
if (func) then
return func (_table, _value)
else
return _rawset (_table, _key, _value)
end
end
------------------------------------------------------------------------------------------------------------
--> methods
--> set point
function TextEntryMetaFunctions:SetPoint (MyAnchor, SnapTo, HisAnchor, x, y, Width)
if (type (MyAnchor) == "boolean" and MyAnchor and self.space) then
local textWidth = self.label:GetStringWidth()+2
self.editbox:SetWidth (self.space - textWidth - 15)
return
elseif (type (MyAnchor) == "boolean" and MyAnchor and not self.space) then
self.space = self.label:GetStringWidth()+2 + self.editbox:GetWidth()
end
if (Width) then
self.space = Width
end
MyAnchor, SnapTo, HisAnchor, x, y = gump:CheckPoints (MyAnchor, SnapTo, HisAnchor, x, y, self)
if (not MyAnchor) then
print ("Invalid parameter for SetPoint")
return
end
if (self.space) then
self.label:ClearAllPoints()
self.editbox:ClearAllPoints()
self.label:SetPoint (MyAnchor, SnapTo, HisAnchor, x, y)
self.editbox:SetPoint ("left", self.label, "right", 2, 0)
local textWidth = self.label:GetStringWidth()+2
self.editbox:SetWidth (self.space - textWidth - 15)
else
self.label:ClearAllPoints()
self.editbox:ClearAllPoints()
self.editbox:SetPoint (MyAnchor, SnapTo, HisAnchor, x, y)
end
end
--> frame levels
function TextEntryMetaFunctions:GetFrameLevel()
return self.editbox:GetFrameLevel()
end
function TextEntryMetaFunctions:SetFrameLevel (level, frame)
if (not frame) then
return self.editbox:SetFrameLevel (level)
else
local framelevel = frame:GetFrameLevel (frame) + level
return self.editbox:SetFrameLevel (framelevel)
end
end
--> set labal description
function TextEntryMetaFunctions:SetLabelText (text)
if (text) then
self.label:SetText (text)
else
self.label:SetText ("")
end
self:SetPoint (true) --> refresh
end
--> set tab order
function TextEntryMetaFunctions:SetNext (nextbox)
self.next = nextbox
end
--> blink
function TextEntryMetaFunctions:Blink()
self.label:SetTextColor (1, .2, .2, 1)
end
--> show & hide
function TextEntryMetaFunctions:IsShown()
return self.editbox:IsShown()
end
function TextEntryMetaFunctions:Show()
return self.editbox:Show()
end
function TextEntryMetaFunctions:Hide()
return self.editbox:Hide()
end
-- tooltip
function TextEntryMetaFunctions:SetTooltip (tooltip)
if (tooltip) then
return _rawset (self, "have_tooltip", tooltip)
else
return _rawset (self, "have_tooltip", nil)
end
end
function TextEntryMetaFunctions:GetTooltip()
return _rawget (self, "have_tooltip")
end
--> hooks
function TextEntryMetaFunctions:SetHook (hookType, func)
if (func) then
_rawset (self, hookType.."Hook", func)
else
_rawset (self, hookType.."Hook", nil)
end
end
------------------------------------------------------------------------------------------------------------
--> scripts
local OnEnter = function (textentry)
if (textentry.MyObject.OnEnterHook) then
local interrupt = textentry.MyObject.OnEnterHook (textentry)
if (interrupt) then
return
end
end
if (textentry.MyObject.have_tooltip) then
GameCooltip:Reset()
GameCooltip:SetType ("tooltip")
GameCooltip:SetColor ("main", "transparent")
GameCooltip:AddLine (textentry.MyObject.have_tooltip)
GameCooltip:SetOwner (textentry)
GameCooltip:ShowCooltip()
end
textentry.mouse_over = true
if (textentry:IsEnabled()) then
textentry:SetBackdropBorderColor (0.5, 0.5, 0.5, 1)
end
local parent = textentry:GetParent().MyObject
if (parent and parent.type == "panel") then
if (parent.GradientEnabled) then
parent:RunGradient()
end
end
end
local OnLeave = function (textentry)
if (textentry.MyObject.OnLeaveHook) then
local interrupt = textentry.MyObject.OnLeaveHook (textentry)
if (interrupt) then
return
end
end
if (textentry.MyObject.have_tooltip) then
_detalhes.popup:ShowMe (false)
end
textentry.mouse_over = false
if (textentry:IsEnabled()) then
textentry:SetBackdropBorderColor(0.3, 0.3, 0.3, 0.8)
end
local parent = textentry:GetParent().MyObject
if (parent and parent.type == "panel") then
if (parent.GradientEnabled) then
parent:RunGradient (false)
end
end
end
local OnHide = function (textentry)
if (textentry.MyObject.OnHideHook) then
local interrupt = textentry.MyObject.OnHideHook (textentry)
if (interrupt) then
return
end
end
end
local OnShow = function (textentry)
if (textentry.MyObject.OnShowHook) then
local interrupt = textentry.MyObject.OnShowHook (textentry)
if (interrupt) then
return
end
end
end
local OnEnterPressed = function (textentry, byScript)
if (textentry.MyObject.OnEnterPressedHook) then
local interrupt = textentry.MyObject.OnEnterPressedHook (textentry)
if (interrupt) then
return
end
end
local texto = _detalhes:trim (textentry:GetText())
if (_string_len (texto) > 0) then
textentry.text = texto
if (textentry.MyObject.func) then
textentry.MyObject.func (textentry.MyObject.param1, textentry.MyObject.param2, texto, textentry, byScript or textentry)
end
else
textentry:SetText ("")
textentry.MyObject.currenttext = ""
end
textentry.focuslost = true --> perdeu_focus isso aqui pra quando estiver editando e clicar em outra caixa
textentry:ClearFocus()
if (textentry.MyObject.tab_on_enter and textentry.MyObject.next) then
textentry.MyObject.next:SetFocus()
end
end
local OnEscapePressed = function (textentry)
if (textentry.MyObject.OnEscapePressedHook) then
local interrupt = textentry.MyObject.OnEscapePressedHook (textentry)
if (interrupt) then
return
end
end
textentry:SetText("")
textentry.MyObject.currenttext = ""
textentry.focuslost = true
textentry:ClearFocus()
end
local OnEditFocusLost = function (textentry)
if (textentry:IsShown()) then
if (textentry.MyObject.OnEditFocusLostHook) then
local interrupt = textentry.MyObject.OnEditFocusLostHook (textentry)
if (interrupt) then
return
end
end
if (not textentry.focuslost) then
local texto = _detalhes:trim (textentry:GetText())
if (_string_len (texto) > 0) then
textentry.MyObject.currenttext = texto
if (textentry.MyObject.func) then
textentry.MyObject.func (textentry.MyObject.param1, textentry.MyObject.param2, texto, textentry, nil)
end
else
textentry:SetText ("")
textentry.MyObject.currenttext = ""
end
else
textentry.focuslost = false
end
textentry.MyObject.label:SetTextColor (.8, .8, .8, 1)
end
end
local OnEditFocusGained = function (textentry)
if (textentry.MyObject.OnEditFocusGainedHook) then
local interrupt = textentry.MyObject.OnEditFocusGainedHook (textentry)
if (interrupt) then
return
end
end
textentry.MyObject.label:SetTextColor (1, 1, 1, 1)
end
local OnChar = function (textentry, text)
if (textentry.MyObject.OnCharHook) then
local interrupt = textentry.MyObject.OnCharHook (textentry, text)
if (interrupt) then
return
end
end
end
local OnTextChanged = function (textentry, byUser)
if (textentry.MyObject.OnTextChangedHook) then
local interrupt = textentry.MyObject.OnTextChangedHook (textentry, byUser)
if (interrupt) then
return
end
end
end
local OnTabPressed = function (textentry)
if (textentry.MyObject.OnTabPressedHook) then
local interrupt = textentry.MyObject.OnTabPressedHook (textentry, byUser)
if (interrupt) then
return
end
end
if (textentry.MyObject.next) then
OnEnterPressed (textentry, false)
textentry.MyObject.next:SetFocus()
end
end
function TextEntryMetaFunctions:PressEnter (byScript)
OnEnterPressed (self.editbox, byScript)
end
------------------------------------------------------------------------------------------------------------
--> object constructor
function gump:NewTextEntry (parent, container, name, member, w, h, func, param1, param2, space)
if (not name) then
return nil
elseif (not parent) then
return nil
end
if (not container) then
container = parent
end
if (name:find ("$parent")) then
name = name:gsub ("$parent", parent:GetName())
end
local TextEntryObject = {type = "textentry", dframework = true}
if (member) then
parent [member] = TextEntryObject
end
if (parent.dframework) then
parent = parent.widget
end
if (container.dframework) then
container = container.widget
end
--> default members:
--> hooks
TextEntryObject.OnEnterHook = nil
TextEntryObject.OnLeaveHook = nil
TextEntryObject.OnHideHook = nil
TextEntryObject.OnShowHook = nil
TextEntryObject.OnEnterPressedHook = nil
TextEntryObject.OnEscapePressedHook = nil
TextEntryObject.OnEditFocusGainedHook = nil
TextEntryObject.OnEditFocusLostHook = nil
TextEntryObject.OnCharHook = nil
TextEntryObject.OnTextChangedHook = nil
TextEntryObject.OnTabPressedHook = nil
--> misc
TextEntryObject.container = container
TextEntryObject.have_tooltip = nil
TextEntryObject.editbox = CreateFrame ("EditBox", name, parent, "DetailsEditBoxTemplate2")
TextEntryObject.widget = TextEntryObject.editbox
if (not APITextEntryFunctions) then
APITextEntryFunctions = true
local idx = getmetatable (TextEntryObject.editbox).__index
for funcName, funcAddress in pairs (idx) do
if (not TextEntryMetaFunctions [funcName]) then
TextEntryMetaFunctions [funcName] = function (object, ...)
local x = loadstring ( "return _G."..object.editbox:GetName()..":"..funcName.."(...)")
return x (...)
end
end
end
end
TextEntryObject.editbox.MyObject = TextEntryObject
if (not w and space) then
w = space
elseif (w and space) then
if (gump.debug) then
print ("warning: you are using width and space, try use only space for better results.")
end
end
TextEntryObject.editbox:SetWidth (w)
TextEntryObject.editbox:SetHeight (h)
TextEntryObject.editbox:SetJustifyH ("center")
TextEntryObject.editbox:EnableMouse (true)
TextEntryObject.editbox:SetText ("")
TextEntryObject.editbox:SetBackdrop ({bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
edgeFile = "Interface\\ChatFrame\\ChatFrameBackground",
tile = true, edgeSize = 1, tileSize = 5})
TextEntryObject.editbox:SetBackdropColor (0, 0, 0, 0.5)
TextEntryObject.editbox:SetBackdropBorderColor (0.3, 0.3, 0.30, 0.80)
TextEntryObject.editbox:SetAutoFocus (false)
TextEntryObject.editbox:SetFontObject ("GameFontHighlightSmall")
TextEntryObject.func = func
TextEntryObject.param1 = param1
TextEntryObject.param2 = param2
TextEntryObject.next = nil
TextEntryObject.space = space
TextEntryObject.tab_on_enter = false
TextEntryObject.label = _G [name .. "_Desc"]
--> hooks
TextEntryObject.editbox:SetScript ("OnEnter", OnEnter)
TextEntryObject.editbox:SetScript ("OnLeave", OnLeave)
TextEntryObject.editbox:SetScript ("OnHide", OnHide)
TextEntryObject.editbox:SetScript ("OnShow", OnShow)
TextEntryObject.editbox:SetScript ("OnEnterPressed", OnEnterPressed)
TextEntryObject.editbox:SetScript ("OnEscapePressed", OnEscapePressed)
TextEntryObject.editbox:SetScript ("OnEditFocusLost", OnEditFocusLost)
TextEntryObject.editbox:SetScript ("OnEditFocusGained", OnEditFocusGained)
TextEntryObject.editbox:SetScript ("OnChar", OnChar)
TextEntryObject.editbox:SetScript ("OnTextChanged", OnTextChanged)
TextEntryObject.editbox:SetScript ("OnTabPressed", OnTabPressed)
_setmetatable (TextEntryObject, TextEntryMetaFunctions)
return TextEntryObject
end
+36
View File
@@ -0,0 +1,36 @@
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/..\FrameXML\UI.xsd">
<Script file="textentry.lua"/>
<EditBox name="DetailsEditBoxTemplate2" virtual="true">
<Size x="232" y="20"/>
<Backdrop bgFile="Interface\\ChatFrame\\ChatFrameBackground" edgeFile="Interface\\ChatFrame\\ChatFrameBackground" tile="true">
<EdgeSize>
<AbsValue val="1"/>
</EdgeSize>
<TileSize>
<AbsValue val="16"/>
</TileSize>
<BackgroundInsets>
<AbsInset left="0" right="0" top="0" bottom="0"/>
</BackgroundInsets>
</Backdrop>
<Layers>
<Layer level="OVERLAY">
<!-- box description -->
<FontString name="$parent_Desc" text="" parentKey="label" inherits="GameFontHighlightSmall" justifyH="LEFT" nonspacewrap="false">
<Color r = "0.8" g = "0.8" b = "0.8" a = "1"/>
<Anchors>
<Anchor point="RIGHT" relativeTo="$parent" relativePoint="LEFT" x="-2" y="0" />
</Anchors>
</FontString>
</Layer>
</Layers>
</EditBox>
</Ui>
+157
View File
@@ -0,0 +1,157 @@
--[[ Attributes: Damage, Heal, Energy, Miscellaneous ]]
do
local _detalhes = _G._detalhes
local Loc = LibStub ("AceLocale-3.0"):GetLocale ( "Details" )
--> Globals
DETAILS_ATTRIBUTE_DAMAGE = 1
DETAILS_ATTRIBUTE_HEAL = 2
DETAILS_ATTRIBUTE_ENERGY = 3
DETAILS_ATTRIBUTE_MISC = 4
--> Main Attributes
_detalhes.atributos = {
--> Attributes amount = 4: damage / heal / energy / misc
[0] = 4,
--[[ DAMAGE ]]
dano = 1, --> identifier
[1] = 4, --> sub attributes
--[[ HEALING ]]
cura = 2, --> identifier
[2] = 4, --> sub attributes
--[[ ENERGY ]]
e_energy = 3,--> identifier
[3] = 4, --> sub attributes
--[[ MISC ]]
misc = 4, --> identifier
[4] = 5, --> sub attributes
--[[ CUSTOM ]]
custom = 5,
[5] = false,
--[[ String Names ]]
lista = {
Loc ["STRING_ATTRIBUTE_DAMAGE"],--> Damage
Loc ["STRING_ATTRIBUTE_HEAL"], --> Healing
Loc ["STRING_ATTRIBUTE_ENERGY"], --> Energy
Loc ["STRING_ATTRIBUTE_MISC"], --> Misc
Loc ["STRING_ATTRIBUTE_CUSTOM"] --> Custom
}
}
--> Sub Attributes
_detalhes.sub_atributos = {
{
--> Damage sub classes information
damage_done = 1,
dps = 2,
damage_taken = 3,
friendly_fire = 4,
lista = { --[[ String Names ]]
Loc ["STRING_ATTRIBUTE_DAMAGE_DONE"],
Loc ["STRING_ATTRIBUTE_DAMAGE_DPS"],
Loc ["STRING_ATTRIBUTE_DAMAGE_TAKEN"],
Loc ["STRING_ATTRIBUTE_DAMAGE_FRIENDLYFIRE"]
},
icones = {
{"Interface\\AddOns\\Details\\images\\atributos_icones_damage", {0, .125, 0, 1}},
{"Interface\\AddOns\\Details\\images\\atributos_icones_damage", {.125, .25, 0, 1}},
{"Interface\\AddOns\\Details\\images\\atributos_icones_damage", {.25, .375, 0, 1}},
{"Interface\\AddOns\\Details\\images\\atributos_icones_damage", {.375, .5, 0, 1}}
}
},
{
--> Healing sub classes information
healing_done = 1,
hps = 2,
overheal = 3,
healing_tanken = 4,
lista = { --[[ String Names ]]
Loc ["STRING_ATTRIBUTE_HEAL_DONE"],
Loc ["STRING_ATTRIBUTE_HEAL_HPS"],
Loc ["STRING_ATTRIBUTE_HEAL_OVERHEAL"],
Loc ["STRING_ATTRIBUTE_HEAL_TAKEN"]
},
icones = {
{"Interface\\AddOns\\Details\\images\\atributos_icones_heal", {0, .125, 0, 1}},
{"Interface\\AddOns\\Details\\images\\atributos_icones_heal", {.125, .25, 0, 1}},
{"Interface\\AddOns\\Details\\images\\atributos_icones_heal", {.25, .375, 0, 1}},
{"Interface\\AddOns\\Details\\images\\atributos_icones_heal", {.375, .5, 0, 1}}
}
},
{
--> Energy sub classes information
mana_ganha = 1, -- id 0
rage_ganha = 2, -- id 1
energy_ganha = 3, --id 3
rune_ganha = 4, --id 6
lista = { --[[ String Names ]]
Loc ["STRING_ATTRIBUTE_ENERGY_MANA"],
Loc ["STRING_ATTRIBUTE_ENERGY_RAGE"],
Loc ["STRING_ATTRIBUTE_ENERGY_ENERGY"],
Loc ["STRING_ATTRIBUTE_ENERGY_RUNEPOWER"]
},
icones = {
{"Interface\\AddOns\\Details\\images\\atributos_icones_energyze", {0, .125, 0, 1}},
{"Interface\\AddOns\\Details\\images\\atributos_icones_energyze", {.125, .25, 0, 1}},
{"Interface\\AddOns\\Details\\images\\atributos_icones_energyze", {.25, .375, 0, 1}},
{"Interface\\AddOns\\Details\\images\\atributos_icones_energyze", {.375, .5, 0, 1}}
},
internal = {"mana", "e_rage", "e_energy", "runepower"}
},
{
--> Misc sub classes information
cc_break = 1,
ress = 2,
kick = 3,
dispell = 4,
deaths = 5,
lista = { --[[ String Names ]]
Loc ["STRING_ATTRIBUTE_MISC_CCBREAK"],
Loc ["STRING_ATTRIBUTE_MISC_RESS"],
Loc ["STRING_ATTRIBUTE_MISC_INTERRUPT"],
Loc ["STRING_ATTRIBUTE_MISC_DISPELL"],
Loc ["STRING_ATTRIBUTE_MISC_DEAD"],
},
icones = {
{"Interface\\AddOns\\Details\\images\\atributos_icones_misc", {0, .125, 0, 1}},
{"Interface\\AddOns\\Details\\images\\atributos_icones_misc", {.125, .25, 0, 1}},
{"Interface\\AddOns\\Details\\images\\atributos_icones_misc", {.25, .375, 0, 1}},
{"Interface\\AddOns\\Details\\images\\atributos_icones_misc", {.375, .5, 0, 1}},
{"Interface\\AddOns\\Details\\images\\atributos_icones_misc", {.5, .625, 0, 1}}
},
internal = {"cc_break", "ress", "interrupt", "dispell", "dead"}
}
}
function _detalhes:GetAttributeName (attribute)
return _detalhes.atributos.lista [attribute]
end
function _detalhes:GetSubAttributeName (attribute, subAttribute)
if (attribute == 5) then
local CustomObject = _detalhes.custom [subAttribute]
return CustomObject.name
end
return _detalhes.sub_atributos [attribute].lista [subAttribute]
end
function _detalhes:GetInternalSubAttributeName (attribute, subAttribute)
if (attribute == 3 or attribute == 4) then
return _detalhes.sub_atributos [attribute].internal [subAttribute]
end
end
end
+96
View File
@@ -0,0 +1,96 @@
do
local _detalhes = _G._detalhes
_detalhes.EncounterInformation = {}
local _ipairs = ipairs --> lua local
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> details api functions
--> return if the player is inside a raid supported by details
function _detalhes:IsInInstance()
local _, _, _, _, _, _, _, zoneMapID = GetInstanceInfo()
if (_detalhes.EncounterInformation [zoneMapID]) then
return true
else
return false
end
end
--> return the function for the boss
function _detalhes:GetBossFunction (mapid, bossindex)
local func = _detalhes.EncounterInformation [mapid] and _detalhes.EncounterInformation [mapid].encounters [bossindex] and _detalhes.EncounterInformation [mapid].encounters [bossindex].func
if (func) then
return func, _detalhes.EncounterInformation [mapid].encounters [bossindex].funcType
end
return
end
--> return the boss table with information about name, adds, spells, etc
function _detalhes:GetBossDetails (mapid, bossindex)
return _detalhes.EncounterInformation [mapid] and _detalhes.EncounterInformation [mapid].encounters [bossindex]
end
--> return a table with spells id of specified encounter
function _detalhes:GetEncounterSpells (mapid, bossindex)
local encounter = _detalhes:GetBossDetails (mapid, bossindex)
local habilidades_poll = {}
if (encounter.continuo) then
for index, spellid in _ipairs (encounter.continuo) do
habilidades_poll [spellid] = true
end
end
local fases = encounter.phases
for fase_id, fase in _ipairs (fases) do
if (fase.spells) then
for index, spellid in _ipairs (fase.spells) do
habilidades_poll [spellid] = true
end
end
end
return habilidades_poll
end
--> return a table with all boss ids from a raid instance
function _detalhes:GetBossIds (mapid)
return _detalhes.EncounterInformation [mapid] and _detalhes.EncounterInformation [mapid].boss_ids
end
--> return a table with all encounter names present in raid instance
function _detalhes:GetBossNames (mapid)
return _detalhes.EncounterInformation [mapid] and _detalhes.EncounterInformation [mapid].boss_names
end
--> return the encounter name
function _detalhes:GetBossName (mapid, bossindex)
return _detalhes.EncounterInformation [mapid] and _detalhes.EncounterInformation [mapid].boss_names [bossindex]
end
--> same thing as GetBossDetails, just a alias
function _detalhes:GetBossEncounterDetails (mapid, bossindex)
return _detalhes.EncounterInformation [mapid] and _detalhes.EncounterInformation [mapid].encounters [bossindex]
end
--> return the wallpaper for the raid instance
function _detalhes:GetRaidBackground (mapid)
return _detalhes.EncounterInformation [mapid] and _detalhes.EncounterInformation [mapid].background
end
--> return the boss icon
function _detalhes:GetBossIcon (mapid, bossindex)
if (_detalhes.EncounterInformation [mapid]) then
local line = math.ceil (bossindex / 4)
local x = ( bossindex - ( (line-1) * 4 ) ) / 4
return x-0.25, x, 0.25 * (line-1), 0.25 * line, _detalhes.EncounterInformation [mapid].icons
end
end
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> core
function _detalhes:InstallEncounter (InstanceTable)
_detalhes.EncounterInformation [InstanceTable.id] = InstanceTable
return true
end
end
+195
View File
@@ -0,0 +1,195 @@
--File Revision: 1
--Last Modification: 27/07/2013
-- Change Log:
-- 27/07/2013: Finished alpha version.
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
local _detalhes = _G._detalhes
local Loc = LibStub ("AceLocale-3.0"):GetLocale ( "Details" )
--> initialize buffs name container
_detalhes.Buffs.BuffsTable = {} -- armazenara o [nome do buff] = { tabela do buff }
_detalhes.Buffs.__index = _detalhes.Buffs
--> switch off recording buffs by default
_detalhes.RecordPlayerSelfBuffs = false
_detalhes.RecordPlayerAbilityWithBuffs = false
_detalhes.RecordPlayerSelfDebuffs = false
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> local pointers
local _pairs = pairs --> lua local
local _ipairs = ipairs --> lua local
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> details api functions
--> return if the buff is already registred or not
function _detalhes.Buffs:IsRegistred (buff)
if (type (buff) == "number") then
for _, buffObject in _pairs (_detalhes.Buffs.BuffsTable) do
if (buffObject.id == buff) then
return true
end
end
return false
elseif (type (buff) == "string") then
for name, _ in _pairs (_detalhes.Buffs.BuffsTable) do
if (name == buff) then
return true
end
end
return false
end
end
--> register a new buff name
function _detalhes.Buffs:NewBuff (BuffName, BuffId)
if (not BuffName) then
BuffName = GetSpellInfo (BuffId)
end
if (_detalhes.Buffs.BuffsTable [BuffName]) then
return false
else
_detalhes.Buffs.BuffsTable [BuffName] = _detalhes.Buffs:BuildBuffTable (BuffName, BuffId)
end
end
--> remove a registred buff
function _detalhes.Buffs:RemoveBuff (BuffName)
if (not _detalhes.Buffs.BuffsTable [BuffName]) then
return false
else
_detalhes.Buffs.BuffsTable = _detalhes:tableRemove (_detalhes.Buffs.BuffsTable, BuffName)
return true
end
end
--> return a list of registred buffs
function _detalhes.Buffs:GetBuffList()
local list = {}
for name, _ in _pairs (_detalhes.Buffs.BuffsTable) do
list [#list+1] = name
end
return list
end
--> return a list of registred buffs ids
function _detalhes.Buffs:GetBuffListIds()
local list = {}
for name, buffObject in _pairs (_detalhes.Buffs.BuffsTable) do
list [#list+1] = buffObject.id
end
return list
end
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> internal functions
function _detalhes.Buffs:UpdateBuff (method)
-- self = buff table
if (method == "new") then
self.start = _detalhes._tempo
self.castedAmt = self.castedAmt + 1
self.active = true
self.appliedAt [#self.appliedAt+1] = _detalhes.tabela_vigente:GetCombatTime()
_detalhes:SendEvent ("BUFF_UPDATE")
elseif (method == "refresh") then
self.refreshAmt = self.refreshAmt + 1
self.duration = self.duration + (_detalhes._tempo - self.start)
self.start = _detalhes._tempo
self.appliedAt [#self.appliedAt+1] = _detalhes.tabela_vigente:GetCombatTime()
_detalhes:SendEvent ("BUFF_UPDATE")
elseif (method == "remove") then
if (self.start) then
self.duration = self.duration + (_detalhes._tempo - self.start)
else
self.duration = 0
end
self.droppedAmt = self.droppedAmt + 1
self.start = nil
self.active = false
_detalhes:SendEvent ("BUFF_UPDATE")
end
end
--> build buffs
function _detalhes.Buffs:BuildTables()
_detalhes.Buffs.built = true
if (_detalhes.savedbuffs) then
for _, BuffId in _ipairs (_detalhes.savedbuffs) do
_detalhes.Buffs:NewBuff (nil, BuffId)
end
end
end
--> save buff list when addon exit
function _detalhes.Buffs:SaveBuffs()
_detalhes_database.savedbuffs = _detalhes.Buffs:GetBuffListIds()
end
--> construct a buff table of the new buff registred
function _detalhes.Buffs:BuildBuffTable (BuffName, BuffId)
local bufftable = {name = BuffName, id = BuffId, duration = 0, start = nil, castedAmt = 0, refreshAmt = 0, droppedAmt = 0, active = false, appliedAt = {}}
bufftable.IsBuff = true
setmetatable (bufftable, _detalhes.Buffs)
return bufftable
end
--> update player buffs
function _detalhes.Buffs:CatchBuffs()
if (not _detalhes.Buffs.built) then
_detalhes.Buffs:BuildTables()
end
for _, BuffTable in _pairs (_detalhes.Buffs.BuffsTable) do
if (BuffTable.active) then
BuffTable.start = _detalhes._tempo
BuffTable.castedAmt = 1
else
BuffTable.start = nil
BuffTable.castedAmt = 0
end
BuffTable.appliedAt = {}
BuffTable.duration = 0
BuffTable.refreshAmt = 0
BuffTable.droppedAmt = 0
end
--> catch buffs untracked yet
for buffIndex = 1, 41 do
local name = UnitAura ("player", buffIndex)
if (name) then
local bufftable = _detalhes.Buffs.BuffsTable [name]
if (bufftable and not bufftable.active) then
bufftable.active = true
bufftable.castedAmt = 1
bufftable.start = _detalhes._tempo
end
--[[
for index, BuffName in _pairs (_detalhes.SoloTables.BuffsTableNameCache) do
if (BuffName == name) then
local BuffObject = _detalhes.SoloTables.SoloBuffUptime [name]
if (not BuffObject) then
_detalhes.SoloTables.SoloBuffUptime [name] = {name = name, duration = 0, start = nil, castedAmt = 1, refreshAmt = 0, droppedAmt = 0, Active = true, tableIndex = index, appliedAt = {}}
--_detalhes.SoloTables.BuffTextEntry [index].backgroundFrame:Active()
end
end
end
--]]
end
end
end
+101
View File
@@ -0,0 +1,101 @@
--[[ Declare all Details classes and container indexes ]]
do
local _detalhes = _G._detalhes
local setmetatable = setmetatable
-------- container que armazena o cache de pets
_detalhes.container_pets = {}
_detalhes.container_pets.__index = _detalhes.container_pets
setmetatable (_detalhes.container_pets, _detalhes)
-------- time machine controla o tempo em combate dos jogadores
_detalhes.timeMachine = {}
_detalhes.timeMachine.__index = _detalhes.timeMachine
setmetatable (_detalhes.timeMachine, _detalhes)
-------- classe da tabela que armazenará todos os combates efetuados
_detalhes.historico = {}
_detalhes.historico.__index = _detalhes.historico
setmetatable (_detalhes.historico, _detalhes)
---------------- classe da tabela onde serão armazenados cada combate efetuado
_detalhes.combate = {}
_detalhes.combate.__index = _detalhes.combate
setmetatable (_detalhes.combate, _detalhes.historico)
------------------------ armazenas classes de jogadores ou outros derivados
_detalhes.container_combatentes = {}
_detalhes.container_combatentes.__index = _detalhes.container_combatentes
setmetatable (_detalhes.container_combatentes, _detalhes.combate)
-------------------------------- dano das habilidades.
_detalhes.atributo_damage = {}
_detalhes.atributo_damage.__index = _detalhes.atributo_damage
setmetatable (_detalhes.atributo_damage, _detalhes.container_combatentes)
-------------------------------- cura das habilidades.
_detalhes.atributo_heal = {}
_detalhes.atributo_heal.__index = _detalhes.atributo_heal
setmetatable (_detalhes.atributo_heal, _detalhes.container_combatentes)
-------------------------------- e_energy ganha
_detalhes.atributo_energy = {}
_detalhes.atributo_energy.__index = _detalhes.atributo_energy
setmetatable (_detalhes.atributo_energy, _detalhes.container_combatentes)
-------------------------------- outros atributos
_detalhes.atributo_misc = {}
_detalhes.atributo_misc.__index = _detalhes.atributo_misc
setmetatable (_detalhes.atributo_misc, _detalhes.container_combatentes)
-------------------------------- atributos customizados
_detalhes.atributo_custom = {}
_detalhes.atributo_custom.__index = _detalhes.atributo_custom
setmetatable (_detalhes.atributo_custom, _detalhes.container_combatentes)
-------------------------------- armazena as classes de habilidades usadas pelo combatente
_detalhes.container_habilidades = {}
_detalhes.container_habilidades.__index = _detalhes.container_habilidades
setmetatable (_detalhes.container_habilidades, _detalhes.combate)
---------------------------------------- classe das habilidades que dão cura
_detalhes.habilidade_cura = {}
_detalhes.habilidade_cura.__index = _detalhes.habilidade_cura
setmetatable (_detalhes.habilidade_cura, _detalhes.container_habilidades)
---------------------------------------- classe das habilidades que dão danos
_detalhes.habilidade_dano = {}
_detalhes.habilidade_dano.__index = _detalhes.habilidade_dano
setmetatable (_detalhes.habilidade_dano, _detalhes.container_habilidades)
---------------------------------------- classe das habilidades que dão e_energy
_detalhes.habilidade_e_energy = {}
_detalhes.habilidade_e_energy.__index = _detalhes.habilidade_e_energy
setmetatable (_detalhes.habilidade_e_energy, _detalhes.container_habilidades)
---------------------------------------- classe das habilidades variadas
_detalhes.habilidade_misc = {}
_detalhes.habilidade_misc.__index = _detalhes.habilidade_misc
setmetatable (_detalhes.habilidade_misc, _detalhes.container_habilidades)
---------------------------------------- classe dos alvos das habilidads
_detalhes.alvo_da_habilidade = {}
_detalhes.alvo_da_habilidade.__index = _detalhes.alvo_da_habilidade
setmetatable (_detalhes.alvo_da_habilidade, _detalhes.container_combatentes)
--[[ Armazena os diferentes tipos de containers ]] --[[ Container Types ]]
_detalhes.container_type = {
CONTAINER_PLAYERNPC = 1,
CONTAINER_DAMAGE_CLASS = 2,
CONTAINER_HEAL_CLASS = 3,
CONTAINER_HEALTARGET_CLASS = 4,
CONTAINER_FRIENDLYFIRE = 5,
CONTAINER_DAMAGETARGET_CLASS = 6,
CONTAINER_ENERGY_CLASS = 7,
CONTAINER_ENERGYTARGET_CLASS = 8,
CONTAINER_MISC_CLASS = 9,
CONTAINER_MISCTARGET_CLASS = 10
}
end
+532
View File
@@ -0,0 +1,532 @@
--File Revision: 1
--Last Modification: 27/07/2013
-- Change Log:
-- 27/07/2013: Finished alpha version.
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
local _detalhes = _G._detalhes
local Loc = LibStub ("AceLocale-3.0"):GetLocale ( "Details" )
--> Event types:
_detalhes.RegistredEvents = {
--> details self events
--> instances
["DETAILS_INSTANCE_OPEN"] = {},
["DETAILS_INSTANCE_CLOSE"] = {},
["DETAILS_INSTANCE_SIZECHANGED"] = {},
["DETAILS_INSTANCE_STARTRESIZE"] = {},
["DETAILS_INSTANCE_ENDRESIZE"] = {},
["DETAILS_INSTANCE_STARTSTRETCH"] = {},
["DETAILS_INSTANCE_ENDSTRETCH"] = {},
["DETAILS_INSTANCE_CHANGESEGMENT"] = {},
["DETAILS_INSTANCE_CHANGEATTRIBUTE"] = {},
["DETAILS_INSTANCE_CHANGEMODE"] = {},
--> data
["DETAILS_DATA_RESET"] = {},
["DETAILS_DATA_SEGMENTREMOVED"] = {},
--> combat
["COMBAT_PLAYER_ENTER"] = {},
["COMBAT_PLAYER_LEAVE"] = {},
["COMBAT_PLAYER_TIMESTARTED"] = {},
["COMBAT_BOSS_FOUND"] = {},
--> buffs
["BUFF_UPDATE"] = {},
["BUFF_UPDATE_DEBUFFPOWER"] = {}
}
local function AlreadyRegistred (_tables, _object)
for index, _this_object in ipairs (_tables) do
if (_this_object.__eventtable) then
if (_this_object [1] == _object) then
return index
end
elseif (_this_object == _object) then
return index
end
end
return false
end
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> details api functions
--> Register a Event
function _detalhes:RegisterEvent (object, event, func)
-------> combat -------------------------------------------------------------------------------------------------------------------------------------------------
if (event == "COMBAT_PLAYER_ENTER") then
if (not AlreadyRegistred (_detalhes.RegistredEvents ["COMBAT_PLAYER_ENTER"], object)) then
if (func) then
tinsert (_detalhes.RegistredEvents ["COMBAT_PLAYER_ENTER"], {object, func, __eventtable = true})
else
tinsert (_detalhes.RegistredEvents ["COMBAT_PLAYER_ENTER"], object)
end
return true
else
return false
end
elseif (event == "COMBAT_PLAYER_LEAVE") then
if (not AlreadyRegistred (_detalhes.RegistredEvents ["COMBAT_PLAYER_LEAVE"], object)) then
if (func) then
tinsert (_detalhes.RegistredEvents ["COMBAT_PLAYER_LEAVE"], {object, func, __eventtable = true})
else
tinsert (_detalhes.RegistredEvents ["COMBAT_PLAYER_LEAVE"], object)
end
return true
else
return false
end
elseif (event == "COMBAT_PLAYER_TIMESTARTED") then
if (not AlreadyRegistred (_detalhes.RegistredEvents ["COMBAT_PLAYER_TIMESTARTED"], object)) then
if (func) then
tinsert (_detalhes.RegistredEvents ["COMBAT_PLAYER_TIMESTARTED"], {object, func, __eventtable = true})
else
tinsert (_detalhes.RegistredEvents ["COMBAT_PLAYER_TIMESTARTED"], object)
end
return true
else
return false
end
elseif (event == "COMBAT_BOSS_FOUND") then
if (not AlreadyRegistred (_detalhes.RegistredEvents ["COMBAT_BOSS_FOUND"], object)) then
if (func) then
tinsert (_detalhes.RegistredEvents ["COMBAT_BOSS_FOUND"], {object, func, __eventtable = true})
else
tinsert (_detalhes.RegistredEvents ["COMBAT_BOSS_FOUND"], object)
end
return true
else
return false
end
-------> buffs -------------------------------------------------------------------------------------------------------------------------------------------------
elseif (event == "BUFF_UPDATE") then
if (not AlreadyRegistred (_detalhes.RegistredEvents ["BUFF_UPDATE"], object)) then
if (func) then
tinsert (_detalhes.RegistredEvents ["BUFF_UPDATE"], {object, func, __eventtable = true})
else
tinsert (_detalhes.RegistredEvents ["BUFF_UPDATE"], object)
end
_detalhes.Buffs:CatchBuffs()
_detalhes.RecordPlayerSelfBuffs = true
_detalhes:UpdateParserGears()
return true
else
return false
end
elseif (event == "BUFF_UPDATE_DEBUFFPOWER") then
if (not AlreadyRegistred (_detalhes.RegistredEvents ["BUFF_UPDATE_DEBUFFPOWER"], object)) then
if (func) then
tinsert (_detalhes.RegistredEvents ["BUFF_UPDATE_DEBUFFPOWER"], {object, func, __eventtable = true})
else
tinsert (_detalhes.RegistredEvents ["BUFF_UPDATE_DEBUFFPOWER"], object)
end
_detalhes.RecordPlayerAbilityWithBuffs = true
_detalhes:UpdateDamageAbilityGears()
_detalhes:UpdateParserGears()
return true
else
return false
end
-------> Addon Instances -------------------------------------------------------------------------------------------------------------------------------------------------
elseif (event == "DETAILS_INSTANCE_OPEN") then
if (not AlreadyRegistred (_detalhes.RegistredEvents ["DETAILS_INSTANCE_OPEN"], object)) then
if (func) then
tinsert (_detalhes.RegistredEvents ["DETAILS_INSTANCE_OPEN"], {object, func, __eventtable = true})
else
tinsert (_detalhes.RegistredEvents ["DETAILS_INSTANCE_OPEN"], object)
end
return true
else
return false
end
elseif (event == "DETAILS_INSTANCE_CLOSE") then
if (not AlreadyRegistred (_detalhes.RegistredEvents ["DETAILS_INSTANCE_CLOSE"], object)) then
if (func) then
tinsert (_detalhes.RegistredEvents ["DETAILS_INSTANCE_CLOSE"], {object, func, __eventtable = true})
else
tinsert (_detalhes.RegistredEvents ["DETAILS_INSTANCE_CLOSE"], object)
end
return true
else
return false
end
elseif (event == "DETAILS_INSTANCE_SIZECHANGED") then
if (not AlreadyRegistred (_detalhes.RegistredEvents ["DETAILS_INSTANCE_SIZECHANGED"], object)) then
if (func) then
tinsert (_detalhes.RegistredEvents ["DETAILS_INSTANCE_SIZECHANGED"], {object, func, __eventtable = true})
else
tinsert (_detalhes.RegistredEvents ["DETAILS_INSTANCE_SIZECHANGED"], object)
end
return true
else
return false
end
elseif (event == "DETAILS_INSTANCE_STARTRESIZE") then
if (not AlreadyRegistred (_detalhes.RegistredEvents ["DETAILS_INSTANCE_STARTRESIZE"], object)) then
if (func) then
tinsert (_detalhes.RegistredEvents ["DETAILS_INSTANCE_STARTRESIZE"], {object, func, __eventtable = true})
else
tinsert (_detalhes.RegistredEvents ["DETAILS_INSTANCE_STARTRESIZE"], object)
end
return true
else
return false
end
elseif (event == "DETAILS_INSTANCE_ENDRESIZE") then
if (not AlreadyRegistred (_detalhes.RegistredEvents ["DETAILS_INSTANCE_ENDRESIZE"], object)) then
if (func) then
tinsert (_detalhes.RegistredEvents ["DETAILS_INSTANCE_ENDRESIZE"], {object, func, __eventtable = true})
else
tinsert (_detalhes.RegistredEvents ["DETAILS_INSTANCE_ENDRESIZE"], object)
end
return true
else
return false
end
elseif (event == "DETAILS_INSTANCE_ENDSTRETCH") then
if (not AlreadyRegistred (_detalhes.RegistredEvents ["DETAILS_INSTANCE_ENDSTRETCH"], object)) then
if (func) then
tinsert (_detalhes.RegistredEvents ["DETAILS_INSTANCE_ENDSTRETCH"], {object, func, __eventtable = true})
else
tinsert (_detalhes.RegistredEvents ["DETAILS_INSTANCE_ENDSTRETCH"], object)
end
return true
else
return false
end
elseif (event == "DETAILS_INSTANCE_STARTSTRETCH") then
if (not AlreadyRegistred (_detalhes.RegistredEvents ["DETAILS_INSTANCE_STARTSTRETCH"], object)) then
if (func) then
tinsert (_detalhes.RegistredEvents ["DETAILS_INSTANCE_STARTSTRETCH"], {object, func, __eventtable = true})
else
tinsert (_detalhes.RegistredEvents ["DETAILS_INSTANCE_STARTSTRETCH"], object)
end
return true
else
return false
end
elseif (event == "DETAILS_INSTANCE_CHANGESEGMENT") then
if (not AlreadyRegistred (_detalhes.RegistredEvents ["DETAILS_INSTANCE_CHANGESEGMENT"], object)) then
if (func) then
tinsert (_detalhes.RegistredEvents ["DETAILS_INSTANCE_CHANGESEGMENT"], {object, func, __eventtable = true})
else
tinsert (_detalhes.RegistredEvents ["DETAILS_INSTANCE_CHANGESEGMENT"], object)
end
return true
else
return false
end
elseif (event == "DETAILS_INSTANCE_CHANGEATTRIBUTE") then
if (not AlreadyRegistred (_detalhes.RegistredEvents ["DETAILS_INSTANCE_CHANGEATTRIBUTE"], object)) then
if (func) then
tinsert (_detalhes.RegistredEvents ["DETAILS_INSTANCE_CHANGEATTRIBUTE"], {object, func, __eventtable = true})
else
tinsert (_detalhes.RegistredEvents ["DETAILS_INSTANCE_CHANGEATTRIBUTE"], object)
end
return true
else
return false
end
elseif (event == "DETAILS_INSTANCE_CHANGEMODE") then
if (not AlreadyRegistred (_detalhes.RegistredEvents ["DETAILS_INSTANCE_CHANGEMODE"], object)) then
if (func) then
tinsert (_detalhes.RegistredEvents ["DETAILS_INSTANCE_CHANGEMODE"], {object, func, __eventtable = true})
else
tinsert (_detalhes.RegistredEvents ["DETAILS_INSTANCE_CHANGEMODE"], object)
end
return true
else
return false
end
elseif (event == "DETAILS_DATA_RESET") then
if (not AlreadyRegistred (_detalhes.RegistredEvents ["DETAILS_DATA_RESET"], object)) then
if (func) then
tinsert (_detalhes.RegistredEvents ["DETAILS_DATA_RESET"], {object, func, __eventtable = true})
else
tinsert (_detalhes.RegistredEvents ["DETAILS_DATA_RESET"], object)
end
return true
else
return false
end
elseif (event == "DETAILS_DATA_SEGMENTREMOVED") then
if (not AlreadyRegistred (_detalhes.RegistredEvents ["DETAILS_DATA_SEGMENTREMOVED"], object)) then
if (func) then
tinsert (_detalhes.RegistredEvents ["DETAILS_DATA_SEGMENTREMOVED"], {object, func, __eventtable = true})
else
tinsert (_detalhes.RegistredEvents ["DETAILS_DATA_SEGMENTREMOVED"], object)
end
return true
else
return false
end
end
end
------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> Unregister a Event
------------------------------------------------------------------------------------------------------------------------------------------------------------------
function _detalhes:UnregisterEvent (object, event)
-------> combat -------------------------------------------------------------------------------------------------------------------------------------------------
if (event == "COMBAT_PLAYER_ENTER") then
local index = AlreadyRegistred (_detalhes.RegistredEvents ["COMBAT_PLAYER_ENTER"], object)
if (index) then
table.remove (_detalhes.RegistredEvents ["COMBAT_PLAYER_ENTER"], index)
return true
else
return false
end
elseif (event == "COMBAT_PLAYER_LEAVE") then
local index = AlreadyRegistred (_detalhes.RegistredEvents ["COMBAT_PLAYER_LEAVE"], object)
if (index) then
table.remove (_detalhes.RegistredEvents ["COMBAT_PLAYER_LEAVE"], index)
return true
else
return false
end
elseif (event == "COMBAT_PLAYER_TIMESTARTED") then
local index = AlreadyRegistred (_detalhes.RegistredEvents ["COMBAT_PLAYER_TIMESTARTED"], object)
if (index) then
table.remove (_detalhes.RegistredEvents ["COMBAT_PLAYER_TIMESTARTED"], index)
return true
else
return false
end
elseif (event == "COMBAT_BOSS_FOUND") then
local index = AlreadyRegistred (_detalhes.RegistredEvents ["COMBAT_BOSS_FOUND"], object)
if (index) then
table.remove (_detalhes.RegistredEvents ["COMBAT_BOSS_FOUND"], index)
return true
else
return false
end
-------> buffs -------------------------------------------------------------------------------------------------------------------------------------------------
elseif (event == "BUFF_UPDATE") then
local index = AlreadyRegistred (_detalhes.RegistredEvents ["BUFF_UPDATE"], object)
if (index) then
table.remove (_detalhes.RegistredEvents ["BUFF_UPDATE"], index)
if (#_detalhes.RegistredEvents ["BUFF_UPDATE"] < 1) then
_detalhes.RecordPlayerSelfBuffs = true
_detalhes:UpdateParserGears()
end
return true
else
return false
end
elseif (event == "BUFF_UPDATE_DEBUFFPOWER") then
local index = AlreadyRegistred (_detalhes.RegistredEvents ["BUFF_UPDATE_DEBUFFPOWER"], object)
if (index) then
table.remove (_detalhes.RegistredEvents ["BUFF_UPDATE_DEBUFFPOWER"], index)
if (#_detalhes.RegistredEvents ["BUFF_UPDATE_DEBUFFPOWER"] < 1) then
_detalhes.RecordPlayerAbilityWithBuffs = false
_detalhes:UpdateDamageAbilityGears()
_detalhes:UpdateParserGears()
end
return true
else
return false
end
-------> Addon Instances -------------------------------------------------------------------------------------------------------------------------------------------------
elseif (event == "DETAILS_INSTANCE_OPEN") then
local index = AlreadyRegistred (_detalhes.RegistredEvents ["DETAILS_INSTANCE_OPEN"], object)
if (index) then
table.remove (_detalhes.RegistredEvents ["DETAILS_INSTANCE_OPEN"], index)
return true
else
return false
end
elseif (event == "DETAILS_INSTANCE_CLOSE") then
local index = AlreadyRegistred (_detalhes.RegistredEvents ["DETAILS_INSTANCE_CLOSE"], object)
if (index) then
table.remove (_detalhes.RegistredEvents ["DETAILS_INSTANCE_CLOSE"], index)
return true
else
return false
end
elseif (event == "DETAILS_INSTANCE_SIZECHANGED") then
local index = AlreadyRegistred (_detalhes.RegistredEvents ["DETAILS_INSTANCE_SIZECHANGED"], object)
if (index) then
table.remove (_detalhes.RegistredEvents ["DETAILS_INSTANCE_SIZECHANGED"], index)
return true
else
return false
end
elseif (event == "DETAILS_INSTANCE_STARTRESIZE") then
local index = AlreadyRegistred (_detalhes.RegistredEvents ["DETAILS_INSTANCE_STARTRESIZE"], object)
if (index) then
table.remove (_detalhes.RegistredEvents ["DETAILS_INSTANCE_STARTRESIZE"], index)
return true
else
return false
end
elseif (event == "DETAILS_INSTANCE_ENDRESIZE") then
local index = AlreadyRegistred (_detalhes.RegistredEvents ["DETAILS_INSTANCE_ENDRESIZE"], object)
if (index) then
table.remove (_detalhes.RegistredEvents ["DETAILS_INSTANCE_ENDRESIZE"], index)
return true
else
return false
end
elseif (event == "DETAILS_INSTANCE_ENDSTRETCH") then
local index = AlreadyRegistred (_detalhes.RegistredEvents ["DETAILS_INSTANCE_ENDSTRETCH"], object)
if (index) then
table.remove (_detalhes.RegistredEvents ["DETAILS_INSTANCE_ENDSTRETCH"], index)
return true
else
return false
end
elseif (event == "DETAILS_INSTANCE_STARTSTRETCH") then
local index = AlreadyRegistred (_detalhes.RegistredEvents ["DETAILS_INSTANCE_STARTSTRETCH"], object)
if (index) then
table.remove (_detalhes.RegistredEvents ["DETAILS_INSTANCE_STARTSTRETCH"], index)
return true
else
return false
end
elseif (event == "DETAILS_INSTANCE_CHANGESEGMENT") then
local index = AlreadyRegistred (_detalhes.RegistredEvents ["DETAILS_INSTANCE_CHANGESEGMENT"], object)
if (index) then
table.remove (_detalhes.RegistredEvents ["DETAILS_INSTANCE_CHANGESEGMENT"], index)
return true
else
return false
end
elseif (event == "DETAILS_INSTANCE_CHANGEATTRIBUTE") then
local index = AlreadyRegistred (_detalhes.RegistredEvents ["DETAILS_INSTANCE_CHANGEATTRIBUTE"], object)
if (index) then
table.remove (_detalhes.RegistredEvents ["DETAILS_INSTANCE_CHANGEATTRIBUTE"], index)
return true
else
return false
end
elseif (event == "DETAILS_INSTANCE_CHANGEMODE") then
local index = AlreadyRegistred (_detalhes.RegistredEvents ["DETAILS_INSTANCE_CHANGEMODE"], object)
if (index) then
table.remove (_detalhes.RegistredEvents ["DETAILS_INSTANCE_CHANGEMODE"], index)
return true
else
return false
end
elseif (event == "DETAILS_DATA_RESET") then
local index = AlreadyRegistred (_detalhes.RegistredEvents ["DETAILS_DATA_RESET"], object)
if (index) then
table.remove (_detalhes.RegistredEvents ["DETAILS_DATA_RESET"], index)
return true
else
return false
end
elseif (event == "DETAILS_DATA_SEGMENTREMOVED") then
local index = AlreadyRegistred (_detalhes.RegistredEvents ["DETAILS_DATA_SEGMENTREMOVED"], object)
if (index) then
table.remove (_detalhes.RegistredEvents ["DETAILS_DATA_SEGMENTREMOVED"], index)
return true
else
return false
end
end
end
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> internal functions
--> Send Event
function _detalhes:SendEvent (event, object, ...)
--> send event to all registred plugins
if (not object) then
for _, PluginObject in ipairs (_detalhes.RegistredEvents[event]) do
if (PluginObject.__eventtable) then
if (PluginObject [1].Enabled) then
if (type (PluginObject [2]) == "function") then
PluginObject [2] (event, ...)
else
PluginObject [1] [PluginObject [2]] (event, ...)
end
end
else
if (PluginObject.Enabled) then
PluginObject:OnDetailsEvent (event, ...)
end
end
end
elseif (type (object) == "string" and object == "SEND_TO_ALL") then
for _, PluginObject in ipairs (_detalhes.RaidTables.Plugins) do
PluginObject:OnDetailsEvent (event)
end
for _, PluginObject in ipairs (_detalhes.SoloTables.Plugins) do
PluginObject:OnDetailsEvent (event)
end
for _, PluginObject in ipairs (_detalhes.ToolBar.Plugins) do
PluginObject:OnDetailsEvent (event)
end
else
--> send the event only for requested plugin
if (object.Enabled) then
object:OnDetailsEvent (event, ...)
end
end
end
+29
View File
@@ -0,0 +1,29 @@
--[[ Link actor with his twin shadow ]]
do
local _detalhes = _G._detalhes
local _rawget = rawget
local _setmetatable = setmetatable
--> default weaktable
_detalhes.weaktable = {__mode = "v"}
--> create link between two tables
function _detalhes:FazLinkagem (objeto)
local meus_links = _rawget (self, "links")
if (not meus_links) then
meus_links = _setmetatable ({}, _detalhes.weaktable)
self.links = meus_links
end
meus_links [#meus_links+1] = objeto
end
--> create the link
function _detalhes:CriaLink (link)
--> se tiver a tabela no overall
if (link) then
link:FazLinkagem (self)
end
end
end
+88
View File
@@ -0,0 +1,88 @@
--[[ detect actor class ]]
do
local _detalhes = _G._detalhes
local _pairs = pairs
local _ipairs = ipairs
local _UnitClass = UnitClass
local _select = select
-- try get the class from actor name
function _detalhes:GetClass (name)
local _, class = _UnitClass (name)
if (not class) then
for _, container in _ipairs (_detalhes.tabela_overall) do
local index = container._NameIndexTable [name]
if (index) then
local actor = container._ActorTable [index]
if (actor.classe ~= "UNGROUPPLAYER") then
return actor.classe, _detalhes:unpacks (_detalhes.class_coords [actor.classe] or {0.75, 1, 0.75, 1}, _detalhes.class_colors [actor.classe])
end
end
end
else
return class, _detalhes:unpacks (_detalhes.class_coords [class] or {0.75, 1, 0.75, 1}, _detalhes.class_colors [class])
end
end
function _detalhes:GuessClass (t)
local Actor, container, tries = t[1], t[2], t[3]
if (not Actor) then
return false
end
if (Actor.spell_tables) then --> correcao pros containers misc, precisa pegar os diferentes tipos de containers de lá
for spellid, _ in _pairs (Actor.spell_tables._ActorTable) do
local class = _detalhes.ClassSpellList [spellid]
if (class) then
Actor.classe = class
Actor.shadow.classe = class
Actor.guessing_class = nil
if (container) then
container.need_refresh = true
container.shadow.need_refresh = true
end
if (Actor.minha_barra) then
Actor.minha_barra.minha_tabela = nil
end
return class
end
end
end
local class = _detalhes:GetClass (Actor.nome)
if (class) then
Actor.classe = class
Actor.shadow.classe = class
Actor.need_refresh = true
Actor.shadow.need_refresh = true
Actor.guessing_class = nil
if (container) then
container.need_refresh = true
container.shadow.need_refresh = true
end
if (Actor.minha_barra) then
Actor.minha_barra.minha_tabela = nil
end
return class
end
if (tries and tries < 10) then
_detalhes:ScheduleTimer ("GuessClass", 2, {Actor, container, tries+1})
end
return false
end
end
View File
+287
View File
@@ -0,0 +1,287 @@
--[[this file save the data when player logout and load data and player login back again]]
local _detalhes = _G._detalhes
function _detalhes:SaveData()
if (_G._detalhes_saver) then
return
end
_detalhes:SaveDataOnLogout()
end
function _detalhes:SaveDataOnLogout()
--> cleanup tables
_detalhes:PrepareTablesForSave()
--> get data
-- On Character
--> save instances (windows)
_detalhes_database.tabela_instancias = _detalhes.tabela_instancias
--> options data
--window size
_detalhes_database.max_window_size = _detalhes.max_window_size
_detalhes_database.new_window_size = _detalhes.new_window_size
_detalhes_database.window_clamp = _detalhes.window_clamp
--> text sizes
_detalhes_database.font_sizes = _detalhes.font_sizes
--tutorial
_detalhes_database.tutorial = _detalhes.tutorial
-- max segments
_detalhes_database.segments_amount = _detalhes.segments_amount
_detalhes_database.clear_ungrouped = _detalhes.clear_ungrouped
_detalhes_database.clear_graphic = _detalhes.clear_graphic
-- row animation
_detalhes_database.use_row_animations = _detalhes.use_row_animations
_detalhes_database.animate_scroll = _detalhes.animate_scroll
_detalhes_database.use_scroll = _detalhes.use_scroll
-- death log
_detalhes_database.deadlog_limit = _detalhes.deadlog_limit
-- report
_detalhes_database.report_lines = _detalhes.report_lines
_detalhes_database.report_to_who = _detalhes.report_to_who
-- colors
_detalhes_database.default_bg_color = _detalhes.default_bg_color
_detalhes_database.default_bg_alpha = _detalhes.default_bg_alpha
_detalhes_database.class_colors = _detalhes.class_colors
-- fades
_detalhes_database.row_fade_in = _detalhes.row_fade_in
_detalhes_database.windows_fade_in = _detalhes.windows_fade_in
_detalhes_database.row_fade_out = _detalhes.row_fade_out
_detalhes_database.windows_fade_out = _detalhes.windows_fade_out
-- modes
_detalhes_database.solo = _detalhes.solo
_detalhes_database.tank = _detalhes.raid
-- switch
_detalhes_database.switch = {}
_detalhes_database.switch.slots = _detalhes.switch.slots
_detalhes_database.switch.table = _detalhes.switch.table
-- capture
_detalhes_database.capture_real = _detalhes.capture_real
_detalhes_database.minimum_combat_time = _detalhes.minimum_combat_time
--> combat data
-- segments table
_detalhes_database.tabela_historico = _detalhes.tabela_historico
-- combat id
_detalhes_database.combat_id = _detalhes.combat_id
-- modes
_detalhes_database.SoloTables = {}
_detalhes_database.RaidTables = {}
--> precisa pegar o nome do plugin
if (_detalhes.SoloTables.Mode) then
_detalhes_database.SoloTables.Mode = _detalhes.SoloTables.Mode
_detalhes_database.SoloTables.LastSelected = _detalhes.SoloTables.Plugins [_detalhes.SoloTables.Mode].real_name
end
if (_detalhes.RaidTables.Mode) then
_detalhes_database.RaidTables.Mode = _detalhes.RaidTables.Mode
_detalhes_database.RaidTables.LastSelected = _detalhes.RaidTables.Plugins [_detalhes.RaidTables.Mode].real_name
end
--> buff data
_detalhes.Buffs:SaveBuffs()
--> customs
_detalhes_database.custom = _detalhes.custom
--> version
_detalhes_database.last_realversion = _detalhes.realversion
-- On Account
_detalhes_global = _detalhes_global or {}
_detalhes_global.savedStyles = _detalhes.savedStyles
--max segments
_detalhes_global.segments_amount = _detalhes.segments_amount
-- animations
_detalhes_global.use_row_animations = _detalhes.use_row_animations
_detalhes_global.animate_scroll = _detalhes.animate_scroll
-- scrollbar
_detalhes_global.use_scroll = _detalhes.use_scroll
-- core
_detalhes_global.clear_ungrouped = _detalhes.clear_ungrouped
_detalhes_global.update_speed = _detalhes.update_speed
_detalhes_global.time_type = _detalhes.time_type
_detalhes_global.SpellOverwriteUser = _detalhes.SpellOverwriteUser
return true
end
local force_reset = function()
_detalhes.tabela_instancias = {}
_detalhes.tabela_historico = _detalhes.historico:NovoHistorico()
_detalhes.tabela_pets = _detalhes.container_pets:NovoContainer()
_detalhes.tabela_overall = _detalhes.combate:NovaTabela()
_detalhes.tabela_vigente = _detalhes.combate:NovaTabela (_, _detalhes.tabela_overall)
_detalhes_database = {}
return
end
function _detalhes:LoadData()
--[[
if (true) then --> DEBUG, force empty data
return force_reset()
end --]]
local _detalhes_database = _G._detalhes_database
if (_detalhes_database) then
--> build basic containers
_detalhes.tabela_historico = _detalhes_database.tabela_historico or _detalhes.historico:NovoHistorico() -- segments
_detalhes.tabela_overall = _detalhes.combate:NovaTabela() -- overall
_detalhes.tabela_pets = _detalhes_database.tabela_pets or _detalhes.container_pets:NovoContainer() -- pets
--> re-build all indexes and metatables
_detalhes:RestauraMetaTables()
--> instances (windows)
_detalhes.tabela_instancias = _detalhes_database.tabela_instancias or {}
--> get last combat table
local historico_UM = _detalhes.tabela_historico.tabelas[1]
if (historico_UM) then
_detalhes.tabela_vigente = historico_UM --> significa que elas eram a mesma tabela, então aqui elas se tornam a mesma tabela
else
_detalhes.tabela_vigente = _detalhes.combate:NovaTabela (_, _detalhes.tabela_overall)
end
_detalhes.combat_id = _detalhes_database.combat_id
if (_detalhes_database.SoloTables) then
if (_detalhes_database.SoloTables.Mode) then
_detalhes.SoloTables.Mode = _detalhes_database.SoloTables.Mode
_detalhes.SoloTables.LastSelected = _detalhes_database.SoloTables.LastSelected
else
_detalhes.SoloTables.Mode = 1
end
end
if (_detalhes_database.RaidTables) then
if (_detalhes_database.RaidTables.Mode) then
_detalhes.RaidTables.Mode = _detalhes_database.RaidTables.Mode
_detalhes.RaidTables.LastSelected = _detalhes_database.RaidTables.LastSelected
else
_detalhes.RaidTables.Mode = 1
end
end
--> load options data
--window size
_detalhes.max_window_size = _detalhes_database.max_window_size
_detalhes.new_window_size = _detalhes_database.new_window_size
_detalhes.window_clamp = _detalhes_database.window_clamp
-- max segments
_detalhes.segments_amount = _detalhes_database.segments_amount
_detalhes.clear_ungrouped = _detalhes_database.clear_ungrouped
_detalhes.clear_graphic = _detalhes_database.clear_graphic
--> text sizes
_detalhes.font_sizes = _detalhes_database.font_sizes
--tutorial
_detalhes.tutorial = _detalhes_database.tutorial
-- row animation
_detalhes.use_row_animations = _detalhes_database.use_row_animations
_detalhes.animate_scroll = _detalhes_database.animate_scroll
_detalhes.use_scroll = _detalhes_database.use_scroll
-- death log
_detalhes.deadlog_limit = _detalhes_database.deadlog_limit
-- report
_detalhes.report_lines = _detalhes_database.report_lines
_detalhes.report_to_who = _detalhes_database.report_to_who
-- colors
_detalhes.class_colors = _detalhes_database.class_colors
_detalhes.default_bg_color = _detalhes_database.default_bg_color
_detalhes.default_bg_alpha = _detalhes_database.default_bg_alpha
-- fades
_detalhes.row_fade_in = _detalhes_database.row_fade_in
_detalhes.windows_fade_in = _detalhes_database.windows_fade_in
_detalhes.row_fade_out = _detalhes_database.row_fade_out
_detalhes.windows_fade_out = _detalhes_database.windows_fade_out
-- modes
_detalhes.solo = _detalhes_database.solo
_detalhes.raid = _detalhes_database.tank
-- switch
if (_detalhes_database.switch) then
_detalhes.switch.slots = _detalhes_database.switch.slots
_detalhes.switch.table = _detalhes_database.switch.table
end
--> buffs
_detalhes.savedbuffs = _detalhes_database.savedbuffs
_detalhes.Buffs:BuildTables()
--> customs
_detalhes.custom = _detalhes_database.custom
--> need refresh for all containers
for _, container in ipairs (_detalhes.tabela_overall) do
container.need_refresh = true
end
for _, container in ipairs (_detalhes.tabela_vigente) do
container.need_refresh = true
end
_detalhes_database.tabela_vigente = nil
_detalhes_database.tabela_historico = nil
_detalhes_database.tabela_pets = nil
-- version
_detalhes.last_realversion = _detalhes_database.last_realversion or _detalhes.realversion
else
_detalhes.tabela_instancias = {}
_detalhes.tabela_historico = _detalhes.historico:NovoHistorico()
_detalhes.tabela_pets = _detalhes.container_pets:NovoContainer()
_detalhes.tabela_overall = _detalhes.combate:NovaTabela()
_detalhes.tabela_vigente = _detalhes.combate:NovaTabela (_, _detalhes.tabela_overall)
_detalhes_database = {}
end
-- capture
_detalhes.capture_real = _detalhes_database and _detalhes_database.capture_real or {
["damage"] = true,
["heal"] = true,
["energy"] = true,
["miscdata"] = true,
["aura"] = true,
}
_detalhes.capture_current = {}
for captureType, captureValue in pairs (_detalhes.capture_real) do
_detalhes.capture_current [captureType] = captureValue
end
_detalhes.minimum_combat_time = _detalhes_database.minimum_combat_time
-- On Account
local _detalhes_global = _G._detalhes_global
if (_detalhes_global) then
--saved styles
vardump (_detalhes_global.savedStyles)
_detalhes.savedStyles = _detalhes_global.savedStyles or _detalhes.savedStyles
--max segments
_detalhes.segments_amount = _detalhes_global.segments_amount or _detalhes.segments_amount
-- row animation
_detalhes.use_row_animations = _detalhes_global.use_row_animations or _detalhes.use_row_animations
_detalhes.animate_scroll = _detalhes_global.animate_scroll or _detalhes.animate_scroll
-- scrollbar
_detalhes.use_scroll = _detalhes_global.use_scroll or _detalhes.use_scroll
-- core
_detalhes.clear_ungrouped = _detalhes_global.clear_ungrouped or _detalhes.clear_ungrouped
_detalhes.update_speed = _detalhes_global.update_speed or _detalhes.update_speed
_detalhes.time_type = _detalhes_global.time_type or _detalhes.time_type
_detalhes.SpellOverwriteUser = _detalhes_global.SpellOverwriteUser or _detalhes.SpellOverwriteUser
end
return true
end
+157
View File
@@ -0,0 +1,157 @@
local _detalhes = _G._detalhes
local Loc = LibStub ("AceLocale-3.0"):GetLocale ( "Details" )
local CreateFrame = CreateFrame
local pairs = pairs
local UIParent = UIParent
local UnitGUID = UnitGUID
local tonumber= tonumber
local LoggingCombat = LoggingCombat
SLASH_DETAILS1, SLASH_DETAILS2, SLASH_DETAILS3 = "/details", "/dt", "/d"
function SlashCmdList.DETAILS (msg, editbox)
local command, rest = msg:match("^(%S*)%s*(.-)$")
if (msg == Loc ["STRING_SLASH_NEW"]) then
_detalhes:CriarInstancia()
elseif (msg == "copy") then
_G.DetailsCopy:Show()
_G.DetailsCopy.MyObject.text:HighlightText()
_G.DetailsCopy.MyObject.text:SetFocus()
elseif (msg == "imageedit") then
local callback = function (width, height, overlayColor, alpha, texCoords)
print (width, height, alpha)
print ("overlay: ", unpack (overlayColor))
print ("crop: ", unpack (texCoords))
end
_detalhes.gump:ImageEditor (callback, "Interface\\TALENTFRAME\\bg-paladin-holy", nil, {1, 1, 1, 1}) -- {0.25, 0.25, 0.25, 0.25}
elseif (msg == "error") then
a = nil + 1
--> debug
elseif (command == "resetcapture") then
_detalhes.capture_real = {
["damage"] = true,
["heal"] = true,
["energy"] = true,
["miscdata"] = true,
["aura"] = true,
}
_detalhes.capture_current = _detalhes.capture_real
_detalhes:CaptureRefresh()
--> debug
elseif (msg == "opened") then
print ("Instances opened: " .. _detalhes.opened_windows)
--> debug, get a guid of something
elseif (command == "guid") then --> localize-me
local pass_guid = rest:match("^(%S*)%s*(.-)$")
if (not _detalhes.id_frame) then
local backdrop = {
bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
edgeFile = "Interface\\ChatFrame\\ChatFrameBackground",
tile = true, edgeSize = 1, tileSize = 5,
}
_detalhes.id_frame = CreateFrame ("Frame", "DetailsID", UIParent)
_detalhes.id_frame:SetHeight(14)
_detalhes.id_frame:SetWidth(120)
_detalhes.id_frame:SetPoint ("center", UIParent, "center")
_detalhes.id_frame:SetBackdrop(backdrop)
tinsert (UISpecialFrames, "DetailsID")
_detalhes.id_frame.texto = CreateFrame ("editbox", nil, _detalhes.id_frame)
_detalhes.id_frame.texto:SetPoint ("topleft", _detalhes.id_frame, "topleft")
_detalhes.id_frame.texto:SetAutoFocus(false)
_detalhes.id_frame.texto:SetFontObject (GameFontHighlightSmall)
_detalhes.id_frame.texto:SetHeight(14)
_detalhes.id_frame.texto:SetWidth(120)
_detalhes.id_frame.texto:SetJustifyH("CENTER")
_detalhes.id_frame.texto:EnableMouse(true)
_detalhes.id_frame.texto:SetBackdrop(ManualBackdrop)
_detalhes.id_frame.texto:SetBackdropColor(0, 0, 0, 0.5)
_detalhes.id_frame.texto:SetBackdropBorderColor(0.3, 0.3, 0.30, 0.80)
_detalhes.id_frame.texto:SetText ("") --localize-me
_detalhes.id_frame.texto.perdeu_foco = nil
_detalhes.id_frame.texto:SetScript ("OnEnterPressed", function ()
_detalhes.id_frame.texto:ClearFocus()
_detalhes.id_frame:Hide()
end)
_detalhes.id_frame.texto:SetScript ("OnEscapePressed", function()
_detalhes.id_frame.texto:ClearFocus()
_detalhes.id_frame:Hide()
end)
end
_detalhes.id_frame:Show()
if (pass_guid == "-") then
local guid = UnitGUID ("target")
if (guid) then
print (guid.. " -> " .. tonumber (guid:sub(6, 10), 16))
_detalhes.id_frame.texto:SetText (""..tonumber (guid:sub(6, 10), 16))
_detalhes.id_frame.texto:HighlightText()
end
else
print (pass_guid.. " -> " .. tonumber (pass_guid:sub(6, 10), 16))
_detalhes.id_frame.texto:SetText (""..tonumber (pass_guid:sub(6, 10), 16))
_detalhes.id_frame.texto:HighlightText()
end
--> debug
elseif (msg == "id") then
local one, two = rest:match("^(%S*)%s*(.-)$")
if (one ~= "") then
print("NPC ID:", one:sub(-12, -9), 16)
print("NPC ID:", tonumber((one):sub(-12, -9), 16))
else
print("NPC ID:", tonumber((UnitGUID("target")):sub(-12, -9), 16) )
end
--> debug
elseif (msg == "debug") then
if (_detalhes.debug) then
_detalhes.debug = false
print ("Details Diagnostic mode OFF")
else
_detalhes.debug = true
print ("Details Diagnostic mode ON")
end
--> debug combat log
elseif (msg == "combatlog") then
if (_detalhes.isLoggingCombat) then
LoggingCombat (false)
print ("Wow combatlog record turned OFF.")
_detalhes.isLoggingCombat = nil
else
LoggingCombat (true)
print ("Wow combatlog record turned ON.")
_detalhes.isLoggingCombat = true
end
--> debug
elseif (msg == "gs") then
_detalhes:teste_grayscale()
end
end
+99
View File
@@ -0,0 +1,99 @@
--[[ Spell Cache store all spells shown on frames and make able to change spells name, icons, etc... ]]
do
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> On The Fly SpellCache
local _detalhes = _G._detalhes
local Loc = LibStub ("AceLocale-3.0"):GetLocale ( "Details" )
local _rawget = rawget
local _rawset = rawset
local _setmetatable = setmetatable
local _GetSpellInfo = GetSpellInfo
local _unpack = unpack
--> default container
_detalhes.spellcache = {}
local unknowSpell = {Loc ["STRING_UNKNOWSPELL"], _, "Interface\\Icons\\Ability_Druid_Eclipse"} --> localize-me
--> reset spell cache
function _detalhes:ClearSpellCache()
_detalhes.spellcache = _setmetatable ({},
{__index = function (tabela, valor)
local esta_magia = _rawget (tabela, valor)
if (esta_magia) then
return esta_magia
end
--> should save only icon and name, other values are not used
if (valor) then --> check if spell is valid before
local cache = {_GetSpellInfo (valor)}
tabela [valor] = cache
return cache
else
return unknowSpell
end
end})
--> default overwrites
_rawset (_detalhes.spellcache, 1, {Loc ["STRING_MELEE"], 1, "Interface\\AddOns\\Details\\images\\melee.tga"})
_rawset (_detalhes.spellcache, 2, {Loc ["STRING_AUTOSHOT"], 1, "Interface\\AddOns\\Details\\images\\autoshot.tga"})
--> built-in overwrites
for spellId, spellTable in pairs (_detalhes.SpellOverwrite) do
local name, _, icon = _GetSpellInfo (spellId)
_rawset (_detalhes.spellcache, spellId, {spellTable.name or name, 1, spellTable.icon or icon})
end
--> user overwrites
for spellId, spellTable in pairs (_detalhes.SpellOverwriteUser) do
local name, _, icon = _GetSpellInfo (spellId)
_rawset (_detalhes.spellcache, spellId, {spellTable.name or name, 1, spellTable.icon or icon})
end
end
--> initialize spell cache
_detalhes:ClearSpellCache()
--> overwrite for API GetSpellInfo function
_detalhes.getspellinfo = function (spellid) return _unpack (_detalhes.spellcache[spellid]) end
--> overwrite SpellInfo if spell is a Dot, so GetSpellInfo will return the name modified
function _detalhes:SpellIsDot (spellid)
local nome, rank, icone = _GetSpellInfo (spellid)
_rawset (_detalhes.spellcache, spellid, {nome .. Loc ["STRING_DOT"], rank, icone})
end
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--> Cache All Spells
function _detalhes:BuildSpellList()
local SpellCache = {a={}, b={}, c={}, d={}, e={}, f={}, g={}, h={}, i={}, j={}, k={}, l={}, m={}, n={}, o={}, p={}, q={}, r={}, s={}, t={}, u={}, v={}, w={}, x={}, y={}, z={}}
local _string_lower = string.lower
local _string_sub = string.sub
local blizzGetSpellInfo = GetSpellInfo
for spellid = 1, 160000 do
local name, rank, icon = blizzGetSpellInfo (spellid)
if (name) then
local index = _string_lower (_string_sub (name, 1, 1))
local CachedIndex = SpellCache [index]
if (CachedIndex) then
CachedIndex [spellid] = {name, icon, rank}
end
end
end
_detalhes.spellcachefull = SpellCache
return true
end
function _detalhes:ClearSpellList()
_detalhes.spellcachefull = nil
collectgarbage()
end
end
+376
View File
@@ -0,0 +1,376 @@
do
local _detalhes = _G._detalhes
_detalhes.ClassSpellList = {
--death knight
[77535] = "DEATHKNIGHT", --Blood Shield (heal)
[45470] = "DEATHKNIGHT", --Death Strike (heal)
[53365] = "DEATHKNIGHT", --Unholy Strength (heal)
[48707] = "DEATHKNIGHT", -- Anti-Magic Shell (heal)
[48982] = "DEATHKNIGHT", --rune tap
--> DK Frost
[49020] = "DEATHKNIGHT", --obliterate
[49143] = "DEATHKNIGHT", --frost strike
[55095] = "DEATHKNIGHT", --frost fever
[55078] = "DEATHKNIGHT", --blood plague
[49184] = "DEATHKNIGHT", --howling blast
--> DK Blood
[49998] = "DEATHKNIGHT", --death strike
--> DK Unholy
[55090] = "DEATHKNIGHT",--scourge strike
[47632] = "DEATHKNIGHT",--death coil
--druid
--> Druid Cat
[1822] = "DRUID", --rake
[1079] = "DRUID", --rip
[5221] = "DRUID", --shred
[33876] = "DRUID", --mangle
[33878] = "DRUID", --mangle (energy)
[102545] = "DRUID", --ravage!
[33878] = "DRUID", --mangle (energy gain)
[17057] = "DRUID", --bear form (energy gain)
[16959] = "DRUID", --primal fury (energy gain)
[5217] = "DRUID", --tiger's fury (energy gain)
[68285] = "DRUID", --leader of the pack (mana)
--> Druid Balance
[5176] = "DRUID", --wrath
[93402] = "DRUID", --sunfire
[2912] = "DRUID", --starfire
[8921] = "DRUID", --moonfire
[81070] = "DRUID", --eclipse
--> Druid Resto
[29166] = "DRUID", --innervate
[774] = "DRUID", --rejuvenation
[44203] = "DRUID", --tranquility
[48438] = "DRUID", --wild growth
[81269] = "DRUID", --shiftmend
[102792] = "DRUID", --wind moshroom: bloom
[5185] = "DRUID", --healing touch
[8936] = "DRUID", --regrowth
[33778] = "DRUID", --lifebloom
[48503] = "DRUID", --living seed
[50464] = "DRUID", --nourish
--hunter
[131900] = "HUNTER",--a murder of crows
[118253] = "HUNTER",--serpent sting
[77767] = "HUNTER",--cobra shot
[3044] = "HUNTER",--arcane shot
[53301] = "HUNTER",--explosive shot
[120361] = "HUNTER",--barrage
--mage
--> Mage Frost
[116] = "MAGE",--frost bolt
[30455] = "MAGE",--ice lance
[84721] = "MAGE",--frozen orb
[1449] = "MAGE",--arcane explosion
[113092] = "MAGE",--frost bomb
[115757] = "MAGE",--frost nova
[44614] = "MAGE",--forstfire bolt
[42208] = "MAGE",--blizzard
[11426] = "MAGE",--Ice Barrier (heal)
--> Mage Fire
[11366] = "MAGE",--pyroblast
[133] = "MAGE",--fireball
[108853] = "MAGE",--infernoblast
[2948] = "MAGE",--scorch
--> Mage Arcane
[30451] = "MAGE",--arcane blase
[12051] = "MAGE",--evocation
--monk
--> Monk
[107428] = "MONK", --rising sun kick
[100784] = "MONK", --blackout kick
[132467] = "MONK", --Chi wave
[107270] = "MONK", --spinning crane kick
[100787] = "MONK", --tiger palm
[123761] = "MONK", --mana tea
--> Mistwave
[119611] = "MONK", --renewing mist
[115310] = "MONK", --revival
[116670] = "MONK", --uplift
[115175] = "MONK", --soothing mist
[124041] = "MONK", --gift of the serpent
[124040] = "MONK", -- shi torpedo
[132120] = "MONK", -- enveloping mist
[132463] = "MONK", -- shi wave
[117895] = "MONK", --eminence (statue)
--> drunk monk
[115295] = "MONK", --guard
[115072] = "MONK", --expel harm
--paladin
--> Paladin Retri
[35395] = "PALADIN",--cruzade strike
[879] = "PALADIN",--exorcism
[85256] = "PALADIN",--templar's verdict
[20167] = "PALADIN",--seal of insight (mana)
--> Paladin Protection
[31935] = "PALADIN",--avenger's shield
[20271] = "PALADIN", --judgment
[35395] = "PALADIN", --cruzader strike
[81297] = "PALADIN", --consacration
[31803] = "PALADIN", --censure
[65148] = "PALADIN", --Sacred Shield
[20167] = "PALADIN", --Seal of Insight
--> holy
[86273] = "PALADIN", --illuminated healing
[85222] = "PALADIN", --light of dawn
[53652] = "PALADIN", --beacon of light
[82327] = "PALADIN", --holy radiance
[119952] = "PALADIN", --arcing light
[25914] = "PALADIN", --holy shock
[19750] = "PALADIN", --flash of light
--priest
[34650] = "PRIEST", --mana leech (pet)
--> shadow priest
[589] = "PRIEST", --shadow word: pain
[34914] = "PRIEST", --vampiric touch
[34919] = "PRIEST", --vampiric touch (mana)
[15407] = "PRIEST", --mind flay
[8092] = "PRIEST", --mind blast
[15290] = "PRIEST",-- Vampiric Embrace
[127626] = "PRIEST",--devouring plague (heal)
[2944] = "PRIEST",--devouring plague (damage)
--> disc priest
[585] = "PRIEST", --smite
[47666] = "PRIEST", --penance
[14914] = "PRIEST", --holy fire
[81751] = "PRIEST", --atonement
[47753] = "PRIEST", --divine aegis
--> holy priest
[33110] = "PRIEST", --prayer of mending
[77489] = "PRIEST", --mastery echo of light
[596] = "PRIEST", --prayer of healing
[34861] = "PRIEST", --circle of healing
[139] = "PRIEST", --renew
[120692] = "PRIEST", --halo
[2060] = "PRIEST", --greater heal
[110745] = "PRIEST", --divine star
[2061] = "PRIEST", --flash heal
[88686] = "PRIEST", --santuary
[17] = "PRIEST", --power word: shield
[64904] = "PRIEST", --hymn of hope
--> talent
[129250] = "PRIEST", --power word: solace
--rogue
[53] = "ROGUE", --backstab
[8680] = "ROGUE", --wound pouson
[2098] = "ROGUE", --eviscerate
[2818] = "ROGUE", --deadly poison
[113780] = "ROGUE", --deadly poison
[51723] = "ROGUE", --fan of knifes
[111240] = "ROGUE", --dispatch
[703] = "ROGUE", --garrote
[1943] = "ROGUE", --rupture
[114014] = "ROGUE", --shuriken toss
[16511] = "ROGUE", --hemorrhage
[89775] = "ROGUE", --hemorrhage
[8676] = "ROGUE", --amcush
[5374] = "ROGUE", --mutilate
[32645] = "ROGUE", --envenom
[1943] = "ROGUE", --rupture
[73651] = "ROGUE", --Recuperate (heal)
[35546] = "ROGUE", --combat potency (energy)
[98440] = "ROGUE", --relentless strikes (energy)
[51637] = "ROGUE", --venomous vim (energy)
--shaman
--> Shaman Elemental
[88765] = "SHAMAN", --rolling thunder (mana)
[51490] = "SHAMAN", --thunderstorm (mana)
[82987] = "SHAMAN", --telluric currents glyph (mana)
[101033] = "SHAMAN", --resurgence (mana)
[51505] = "SHAMAN", --lava burst
[8050] = "SHAMAN", --flame shock
[117014] = "SHAMAN", --elemental blast
[403] = "SHAMAN", --lightning bolt
[45284] = "SHAMAN", --lightning bolt
[421] = "SHAMAN", --chain lightining
--> Shaman Melee
[32175] = "SHAMAN", --stormstrike
[25504] = "SHAMAN", --windfury
[8042] = "SHAMAN", --earthshock
[26364] = "SHAMAN", --lightning shield
[117014] = "SHAMAN", --elemental blast
[73683] = "SHAMAN", --unleash flame
[51522] = "SHAMAN", --primal wisdom (mana)
[63375] = "SHAMAN", --primal wisdom (mana)
--> Shaman Resto
[114942] = "SHAMAN", --healing tide
[73921] = "SHAMAN", --healing rain
[1064] = "SHAMAN", --chain heal
[52042] = "SHAMAN", --healing stream totem
[61295] = "SHAMAN", --riptide
[51945] = "SHAMAN", --earthliving
[114083] = "SHAMAN", --restorative mists
[8004] = "SHAMAN", --healing surge
--warlock
[77799] = "WARLOCK", --fel flame
[63106] = "WARLOCK", --siphon life
[1454] = "WARLOCK", --life tap
--> warlock affliction
[103103] = "WARLOCK", --malefic grasp
[980] = "WARLOCK", --agony
[30108] = "WARLOCK", --unstable affliction
[172] = "WARLOCK", --corruption
[48181] = "WARLOCK", --haunt
--> warlock destruction
[29722] = "WARLOCK", --incenerate
[348] = "WARLOCK", --Immolate
[116858] = "WARLOCK", --Chaos Bolt
[114654] = "WARLOCK", --incinerate
[108686] = "WARLOCK", --immolate
[108685] = "WARLOCK", --conflagrate
[104233] = "WARLOCK", --rain of fire
--> warlock demo
[103964] = "WARLOCK", --touch os chaos
[686] = "WARLOCK", --shadow bolt
[114328] = "WARLOCK", --shadow bolt glyph
[140719] = "WARLOCK", --hellfire
[104027] = "WARLOCK", --soul fire
[603] = "WARLOCK", --doom
--> talents
[108371] = "WARLOCK", --Harvest life
--warrior
[100130] = "WARRIOR", --wild strike
[96103] = "WARRIOR", --raging blow
[12294] = "WARRIOR", --mortal strike
[1464] = "WARRIOR", --Slam
[23922] = "WARRIOR", --shield slam
[20243] = "WARRIOR", --devastate
[11800] = "WARRIOR", --dragon roar
[115767] = "WARRIOR", --deep wounds
[109128] = "WARRIOR", --charge
[11294] = "WARRIOR", --mortal strike
[109128] = "WARRIOR", --charge
[12880] = "WARRIOR", --enrage
[29842] = "WARRIOR", --undribled wrath
}
_detalhes.CrowdControlSpells = {
--death knight
[96294] = true, --chains of ice
--druid
--hibernate
[2637] = true, --hibernate
[339] = true, --entangling toots
--hunter
[3355] = true, --freezing trap
[24335] = true, --wyvern sting
[136634] = true, --narrow escape
[4167] = true, --web (spider)
[19503] = true, --scatter shot
--mage
[118] = true, --polymorph sheep
[61305] = true, --polymorph black cat
[28272] = true, --polymorph pig
[61721] = true, --polymorph rabbit
[61780] = true, --polymorph turkey
[28271] = true, --polymorph turtle
[122] = true, --frost nova
[33395] = true, --freeze
[111340] = true, --ice ward
[82691] = true, --ring of frost
--monk
[116706] = true, --disable
--paladin
[105421] = true, --blinding light
[20066] = true, --repentance
--prist
--shackle undead
[8122] = true, --psychic scream
[9484] = true, --shackle undead
--rogue
[2094] = true, --blind
[1776] = true, --gouge
[6770] = true, --sap
[408] = true, --kidney shot
[1833] = true, --cheap shot
--shaman
[51514] = true, --hex
[64695] = true, --earthgrab (earthgrab totem)
[76780] = true, --bind elemental
--warlock
[6358] = true, --seduction (succubus)
[115268] = true, --mesmerize (shivarra)
[118699] = true, --fear
[5484] = true, --howl of terror
--warrior
[5246] = true, --intimidating shout
[107566] = true, --staggering shout
}
_detalhes.AbsorbSpells = {
--priest
[47753] = true, --Divine Aegis (discipline)
[17] = true, --Power Word: Shield (discipline)
[114908] = true, --Spirit Shell (discipline)
[114214] = true, --Angelic Bulwark (talent)
--death knight
[48707] = true, --Anti-Magic Shell
[116888] = true, --Shroud of Purgatory (talent)
[51052] = true, --Anti-Magic Zone (talent)
[77535] = true, --Blood Shield
--shaman
[114893] = true, --Stone Bulwark (stone bulwark totem)
--paladin
[86273] = true, --Illuminated Healing (holy)
[65148] = true, --Sacred Shield (talent)
--monk
[116849] = true, --Life Cocoon (mistweaver)
[115295] = true, --Guard (brewmaster)
[118604] = true, --Guard (brewmaster)
--warlock
[6229] = true, --Twilight Ward
[108366] = true, --Soul Leech (talent)
[108416] = true, --Sacrificial Pact (talent)
[110913] = true, --Dark Bargain (talent)
[7812] = true, --Voidwalker's Sacrifice
--mage
[11426] = true, --Ice Barrier (talent)
[1463] = true, --Incanter's Ward (talent)
--warrior
[112048] = true, -- Shield Barrier (protection)
--others
[116631] = true, -- enchant "Enchant Weapon - Colossus"
[140380] = true, -- trinket "Inscribed Bag of Hydra-Spawn"
}
local Loc = LibStub ("AceLocale-3.0"):GetLocale ( "Details" )
_detalhes.SpellOverwrite = {
[124464] = {name = GetSpellInfo (124464) .. " " .. Loc ["STRING_MASTERY"]}, --> shadow word: pain mastery proc
[124465] = {name = GetSpellInfo (124465) .. " " .. Loc ["STRING_MASTERY"]} --> vampiric touch mastery proc
}
end

Some files were not shown because too many files have changed in this diff Show More