Merge pull request #509 from Tercioo/breakdown

Breakdown
This commit is contained in:
Tercio Jose
2023-04-30 18:25:12 -03:00
committed by GitHub
44 changed files with 6258 additions and 3528 deletions
+4 -4
View File
@@ -382,11 +382,11 @@ spell.successful_casted = how many times this spell has been casted successfully
spell.n_min = minimal damage made on a normal hit.
spell.n_max = max damage made on a normal hit.
spell.n_amt = amount of normal hits.
spell.n_dmg = total amount made doing only normal hits.
spell.n_total = total amount made doing only normal hits.
spell.c_min = minimal damage made on a critical hit.
spell.c_max = max damage made on a critical hit.
spell.c_amt = how many times this spell got a critical hit.
spell.c_dmg = total amount made doing only normal hits.
spell.c_total = total amount made doing only normal hits.
spell.g_amt = how many glancing blows this spell has.
spell.g_dmg = total damage made by glancing blows.
spell.r_amt = total of times this spell got resisted by the target.
@@ -438,11 +438,11 @@ spell.overheal = amount of overheal made by this spell.
spell.n_min = minimal heal made on a normal hit.
spell.n_max = max heal made on a normal hit.
spell.n_amt = amount of normal hits.
spell.n_curado = total amount made doing only normal hits (weird name I know).
spell.n_total = total amount made doing only normal hits (weird name I know).
spell.c_min = minimal heal made on a critical hit.
spell.c_max = max heal made on a critical hit.
spell.c_amt = how many times this spell got a critical hit.
spell.c_curado = total amount made doing only normal hits.
spell.c_total = total amount made doing only normal hits.
spell.targets = hash table containing {["targetname"] = total healing done by this spell on this target}
spell.targets_overheal = hash table containing {["targetname"] = total overhealing by this spell on this target}
+4 -4
View File
@@ -385,11 +385,11 @@ spell.successful_casted = how many times this spell has been casted successfully
spell.n_min = minimal damage made on a normal hit.
spell.n_max = max damage made on a normal hit.
spell.n_amt = amount of normal hits.
spell.n_dmg = total amount made doing only normal hits.
spell.n_total = total amount made doing only normal hits.
spell.c_min = minimal damage made on a critical hit.
spell.c_max = max damage made on a critical hit.
spell.c_amt = how many times this spell got a critical hit.
spell.c_dmg = total amount made doing only normal hits.
spell.c_total = total amount made doing only normal hits.
spell.g_amt = how many glancing blows this spell has.
spell.g_dmg = total damage made by glancing blows.
spell.r_amt = total of times this spell got resisted by the target.
@@ -442,11 +442,11 @@ spell.overheal = amount of overheal made by this spell.
spell.n_min = minimal heal made on a normal hit.
spell.n_max = max heal made on a normal hit.
spell.n_amt = amount of normal hits.
spell.n_curado = total amount made doing only normal hits (weird name I know).
spell.n_total = total amount made doing only normal hits (weird name I know).
spell.c_min = minimal heal made on a critical hit.
spell.c_max = max heal made on a critical hit.
spell.c_amt = how many times this spell got a critical hit.
spell.c_curado = total amount made doing only normal hits.
spell.c_total = total amount made doing only normal hits.
spell.targets = hash table containing {["targetname"] = total healing done by this spell on this target}
spell.targets_overheal = hash table containing {["targetname"] = total overhealing by this spell on this target}
+325 -80
View File
@@ -1,9 +1,17 @@
--uiobject: is an object that represents a UI element, such as a frame, a texture, or a button. UIObjects are the base class for all UI elements in the WoW API.
--3D World: is an object which is placed behind|below all UI elements, cannot be parent of any object, in the 3D World object is where the game world is rendered
--size: corresponds to the height and height of an object, it is measure in pixels, must be bigger than zero.
--scale: the size of an object is multiplied by this value, it is measure in percentage, must be between 0.65 and 2.40.
--alpha: corresponds to the transparency of an object, the bigger is the value less transparent is the object, it is measure in percentage, must be between 0 and 1, zero is fully transparent and one is fully opaque.
---@class _G
---@field RegisterAttributeDriver fun(statedriver: frame, attribute: string, conditional: string)
---@field RegisterStateDriver fun(statedriver: frame, attribute: string, conditional: string)
---@field UnitGUID fun(unit: unit): string
---@field UnitName fun(unit: unit): string
---@field GetCursorPosition fun(): number, number return the position of the cursor on the screen, in pixels, relative to the bottom left corner of the screen.
---@class unixtime : number const
@@ -16,6 +24,9 @@
---@field NewTimer fun(delay: number, func: function): timer
---@field NewTicker fun(interval: number, func: function, iterations: number|nil): timer
---@class tablesize : {H: number, W: number}
---@class tablecoords : {L: number, R: number, T: number, B: number}
---@class red : number color value representing the red component of a color, the value must be between 0 and 1. To retrieve a color from a string or table use: local red, green, blue, alpha = DetailsFramework:ParseColors(color)
---@class green : number color value representing the green component of a color, the value must be between 0 and 1. To retrieve a color from a string or table use: local red, green, blue, alpha = DetailsFramework:ParseColors(color)
---@class blue : number color value representing the blue component of a color, the value must be between 0 and 1. To retrieve a color from a string or table use: local red, green, blue, alpha = DetailsFramework:ParseColors(color)
@@ -23,9 +34,9 @@
---@class color : table, string @table(r: red|number, g: green|number, b: blue|number, a: alpha|number) @string(color name) @hex (000000-ffffff) value representing a color, the value must be a table with the following fields: r, g, b, a. r, g, b are numbers between 0 and 1, a is a number between 0 and 1. To retrieve a color from a string or table use: local red, green, blue, alpha = DetailsFramework:ParseColors(color)
---@class scale : number @number(0.65-2.40) value representing the scale factor of the UIObject, the value must be between 0.65 and 2.40, the width and height of the UIObject will be multiplied by this value.
---@class texture : string, number is an object that represents a graphical image. Textures are used to display visual elements such as icons, backgrounds, borders, and more.
---@class frame : UIObject represents a container for other UI elements, such as textures, buttons, text, and more.
---@class frame : uiobject represents a container for other UI elements, such as textures, buttons, text, and more. Gotten from the first result of GetWidth() or from the first result of GetSize(). It is expected a GetWidth() or GetSize() when the type 'width' is used.
---@class width : number property that represents the horizontal size of a UI element, such as a frame or a texture.
---@class height : number property that represents the vertical size of a UI element, such as a frame or a texture.
---@class height : number property that represents the vertical size of a UI element, such as a frame or a texture. Gotten from the first result of GetHeight() or from the second result of GetSize(). It is expected a GetHeight() or GetSize() when the type 'height' is used.
---@class script : string, function is a piece of code that is executed in response to a specific event, such as a button click or a frame update. Scripts can be used to implement behavior and logic for UI elements.
---@class event : string is a notification that is sent to a frame when something happens, such as a button click or a frame update. Events can be used to trigger scripts.
---@class framestrata : string @string(BACKGROUND, LOW, MEDIUM, HIGH, DIALOG, FULLSCREEN, FULLSCREEN_DIALOG, TOOLTIP) property that determines the stacking order of frames. Higher strata values indicate frames that should be displayed on top of frames with lower strata values.
@@ -33,31 +44,33 @@
---@class unit : string string that represents a unit in the game, such as the player, a party member, or a raid member.
---@class health : number amount of hit points (health) of a unit. This value can be changed by taking damage or healing.
---@class role : string @string(TANK, HEALER, DAMAGER, NONE) is a string that represents the role of a unit, such as tank, healer, or damage dealer.
---@class point : string @string(topleft, topright, bottomleft, bottomright, top, bottom, left, right, center) is a string that represents a point on a frame. Points are used to position frames relative to each other.
---@class UIObject
---@field Show fun(self: UIObject)
---@field Hide fun(self: UIObject)
---@field SetShown fun(self: UIObject, state: boolean)
---@field IsShown fun(self: UIObject) : boolean
---@field SetAllPoints fun(self: UIObject)
---@field SetParent fun(self: UIObject, parent: frame)
---@field SetSize fun(self: UIObject, width: width|number, height: height|number)
---@field SetWidth fun(self: UIObject, width: width|number)
---@field SetHeight fun(self: UIObject, height: height|number)
---@field SetAlpha fun(self: UIObject, alpha: alpha|number)
---@field SetScale fun(self: UIObject, scale: scale|number)
---@field GetWidth fun(self: UIObject) : width|number
---@field GetHeight fun(self: UIObject) : height|number
---@field GetScale fun(self: UIObject) : scale|number
---@field GetAlpha fun(self: UIObject) : alpha|number
---@field GetSize fun(self: UIObject) : width|number, height|number
---@field GetParent fun(self: UIObject) : frame
---@field GetPoint fun(self: UIObject, index: number): string, frame, string, number, number
---@field SetPoint fun(self: UIObject, point: string, relativeFrame: frame, relativePoint: string, xOffset: number, yOffset: number)
---@field ClearAllPoints fun(self: UIObject)
---@field CreateAnimationGroup fun(self: UIObject, name: string|nil, templateName: string|nil) : animationgroup
---@class uiobject
---@field Show fun(self: uiobject) make the object be shown on the user screen
---@field Hide fun(self: uiobject) make the object be hidden from the user screen
---@field SetShown fun(self: uiobject, state: boolean) show or hide the object
---@field IsShown fun(self: uiobject) : boolean return if the object is shown or not
---@field SetAllPoints fun(self: uiobject) set the object to be the same size as its parent
---@field SetParent fun(self: uiobject, parent: frame) set the parent object of the object
---@field SetSize fun(self: uiobject, width: width|number, height: height|number) set the width and height of the object
---@field SetWidth fun(self: uiobject, width: width|number) set only the width of the object
---@field SetHeight fun(self: uiobject, height: height|number) set only the height of the object
---@field SetAlpha fun(self: uiobject, alpha: alpha|number) set the transparency of the object
---@field SetScale fun(self: uiobject, scale: scale|number)
---@field GetWidth fun(self: uiobject) : width|number
---@field GetHeight fun(self: uiobject) : height|number
---@field GetScale fun(self: uiobject) : scale|number
---@field GetAlpha fun(self: uiobject) : alpha|number
---@field GetSize fun(self: uiobject) : width|number, height|number
---@field GetParent fun(self: uiobject) : frame
---@field GetPoint fun(self: uiobject, index: number): string, frame, string, number, number
---@field GetCenter fun(self: uiobject): number, number
---@field SetPoint fun(self: uiobject, point: "topleft"|"topright"|"bottomleft"|"bottomright"|"top"|"bottom"|"left"|"right"|"center", relativeFrame: uiobject, relativePoint: "topleft"|"topright"|"bottomleft"|"bottomright"|"top"|"bottom"|"left"|"right"|"center", xOffset: number, yOffset: number)
---@field ClearAllPoints fun(self: uiobject)
---@field CreateAnimationGroup fun(self: uiobject, name: string|nil, templateName: string|nil) : animationgroup
---@class animationgroup : UIObject
---@class animationgroup : uiobject
---@field CreateAnimation fun(self: animationgroup, animationType: string, name: string|nil, inheritsFrom: string|nil) : animation
---@field GetAnimation fun(self: animationgroup, name: string) : animation
---@field GetAnimations fun(self: animationgroup) : table
@@ -75,11 +88,11 @@
---@field SetDuration fun(self: animationgroup, duration: number)
---@field SetEndDelay fun(self: animationgroup, delay: number)
---@field SetLooping fun(self: animationgroup, loop: boolean)
---@field SetScript fun(self: animationgroup, event: string, handler: function)
---@field SetScript fun(self: animationgroup, event: string, handler: function|nil) "OnEvent"|"OnShow"
---@field SetSmoothProgress fun(self: animationgroup, smooth: boolean)
---@field Stop fun(self: animationgroup)
---@class animation : UIObject
---@class animation : uiobject
---@field GetDuration fun(self: animation) : number
---@field GetEndDelay fun(self: animation) : number
---@field GetOrder fun(self: animation) : number
@@ -94,15 +107,15 @@
---@field SetDuration fun(self: animation, duration: number)
---@field SetEndDelay fun(self: animation, delay: number)
---@field SetOrder fun(self: animation, order: number)
---@field SetScript fun(self: animation, event: string, handler: function)
---@field SetScript fun(self: animation, event: string, handler: function|nil)
---@field SetSmoothing fun(self: animation, smoothing: string)
---@field Stop fun(self: animation)
---@class frame : UIObject
---@class frame : uiobject
---@field SetAttribute fun(self: frame, name: string, value: any)
---@field SetScript fun(self: frame, event: string, handler: function)
---@field SetScript fun(self: frame, event: string, handler: function|nil)
---@field GetScript fun(self: frame, event: string) : function
---@field SetFrameStrata fun(self: frame, strata: framestrata|string)
---@field SetFrameStrata fun(self: frame, strata: framestrata|"background"|"low"|"medium"|"high"|"dialog"|"fullscreen"|"fullscreen_dialog"|"tooltip")
---@field SetFrameLevel fun(self: frame, level: number)
---@field SetClampedToScreen fun(self: frame, clamped: boolean)
---@field SetClampRectInsets fun(self: frame, left: number, right: number, top: number, bottom: number)
@@ -115,6 +128,9 @@
---@field SetToplevel fun(self: frame, toplevel: boolean)
---@field SetPropagateKeyboardInput fun(self: frame, propagate: boolean)
---@field SetPropagateGamepadInput fun(self: frame, propagate: boolean)
---@field StartMoving fun(self: frame)
---@field StartSizing fun(self: frame, point: "top"|"topright"|"right"|"bottomright"|"bottom"|"bottomleft"|"left"|"topleft")
---@field StopMovingOrSizing fun(self: frame)
---@field GetAttribute fun(self: frame, name: string) : any
---@field GetFrameLevel fun(self: frame) : number
---@field GetFrameStrata fun(self: frame) : framestrata|string
@@ -125,9 +141,13 @@
---@field GetObjectType fun(self: frame) : string
---@field GetChildren fun(self: frame) : frame[]
---@field GetRegions fun(self: frame) : region[]
---@field CreateTexture fun(self: frame, name: string|nil, layer: string, inherits: string|nil, subLayer: number|nil) : texture
---@field CreateFontString fun(self: frame, name: string|nil, layer: string, inherits: string|nil, subLayer: number|nil) : fontstring
---@field CreateTexture fun(self: frame, name: string|nil, layer: "background"|"border"|"artwork"|"overlay"|"highlight", inherits: string|nil, subLayer: number|nil) : texture
---@field CreateFontString fun(self: frame, name: string|nil, layer: "background"|"border"|"artwork"|"overlay"|"highlight", inherits: string|nil, subLayer: number|nil) : fontstring
---@field EnableMouse fun(self: frame, enable: boolean)
---@field SetResizable fun(self: frame, enable: boolean)
---@field EnableMouseWheel fun(self: frame, enable: boolean)
---@field RegisterForDrag fun(self: frame, button: string)
---@field SetResizeBounds fun(self: frame, minWidth: number, minHeight: number, maxWidth: number, maxHeight: number)
---@class button : frame
---@field SetNormalTexture fun(self: button, texture: texture)
@@ -148,14 +168,45 @@
---@field GetFontString fun(self: button) : fontstring
---@field SetButtonState fun(self: button, state: string, enable: boolean)
---@field GetButtonState fun(self: button, state: string) : boolean
---@field RegisterForClicks fun(self: button, button1: string|nil, button2: string|nil)
---@field RegisterForClicks fun(self: button, button1: nil|"AnyUp"|"AnyDown"|"LeftButtonDown"|"LeftButtonUp"|"MiddleButtonUp"|"MiddleButtonDown"|"RightButtonDown"|"RightButtonUp"|"Button4Up"|"Button4Down"|"Button5Up"|"Button5Down", button2: nil|"AnyUp"|"AnyDown"|"LeftButtonDown"|"LeftButtonUp"|"MiddleButtonUp"|"MiddleButtonDown"|"RightButtonDown"|"RightButtonUp"|"Button4Up"|"Button4Down"|"Button5Up"|"Button5Down")
---@field GetNormalTexture fun(self: button) : texture
---@field GetPushedTexture fun(self: button) : texture
---@field GetHighlightTexture fun(self: button) : texture
---@field GetDisabledTexture fun(self: button) : texture
---@class fontstring : UIObject
---@field SetDrawLayer fun(self: fontstring, layer: string, subLayer: number|nil)
---@class statusbar : frame
---@field SetStatusBarColor fun(self: statusbar, r: red|number, g: green|number, b: blue|number, a: alpha|number)
---@field SetStatusBarTexture fun(self: statusbar, path: string)
---@field SetMinMaxValues fun(self: statusbar, minValue: number, maxValue: number)
---@field SetValue fun(self: statusbar, value: number)
---@field SetValueStep fun(self: statusbar, valueStep: number)
---@field SetOrientation fun(self: statusbar, orientation: string)
---@field SetReverseFill fun(self: statusbar, reverseFill: boolean)
---@field GetMinMaxValues fun(self: statusbar) : number, number
---@field GetValue fun(self: statusbar) : number
---@field GetValueStep fun(self: statusbar) : number
---@field GetOrientation fun(self: statusbar) : string
---@field GetReverseFill fun(self: statusbar) : boolean
---@class scrollframe : frame
---@field SetScrollChild fun(self: scrollframe, child: frame)
---@field GetScrollChild fun(self: scrollframe) : frame
---@field SetHorizontalScroll fun(self: scrollframe, offset: number)
---@field SetVerticalScroll fun(self: scrollframe, offset: number)
---@field GetHorizontalScroll fun(self: scrollframe) : number
---@field GetVerticalScroll fun(self: scrollframe) : number
---@field GetHorizontalScrollRange fun(self: scrollframe) : number
---@field GetVerticalScrollRange fun(self: scrollframe) : number
---@class region : uiobject
---@class fontstring : region
---@field SetDrawLayer fun(self: fontstring, layer: "background"|"border"|"artwork"|"overlay"|"highlight", subLayer: number|nil)
---@field SetFont fun(self: fontstring, font: string, size: number, flags: string)
---@field SetText fun(self: fontstring, text: string)
---@field SetText fun(self: fontstring, text: string|number)
---@field GetText fun(self: fontstring) : string
---@field GetFont fun(self: fontstring) : string, number, string
---@field GetStringWidth fun(self: fontstring) : number return the width of the string in pixels
---@field SetShadowColor fun(self: fontstring, r: red|number, g: green|number, b: blue|number, a: alpha|number)
---@field GetShadowColor fun(self: fontstring) : number, number, number, number
---@field SetShadowOffset fun(self: fontstring, offsetX: number, offsetY: number)
@@ -166,10 +217,6 @@
---@field GetJustifyH fun(self: fontstring) : string
---@field SetJustifyV fun(self: fontstring, justifyV: string)
---@field GetJustifyV fun(self: fontstring) : string
---@field SetWidth fun(self: fontstring, width: number)
---@field GetWidth fun(self: fontstring) : number
---@field SetHeight fun(self: fontstring, height: number)
---@field GetHeight fun(self: fontstring) : number
---@field SetNonSpaceWrap fun(self: fontstring, nonSpaceWrap: boolean)
---@field GetNonSpaceWrap fun(self: fontstring) : boolean
---@field SetIndentedWordWrap fun(self: fontstring, indentedWordWrap: boolean)
@@ -200,41 +247,17 @@
---@field SetTextTruncateLines fun(self: fontstring, lines: number)
---@field GetTextTruncateLines fun(self: fontstring) : number
---@class statusbar : frame
---@field SetStatusBarColor fun(self: statusbar, r: red|number, g: green|number, b: blue|number, a: alpha|number)
---@field SetStatusBarTexture fun(self: statusbar, path: string)
---@field SetMinMaxValues fun(self: statusbar, minValue: number, maxValue: number)
---@field SetValue fun(self: statusbar, value: number)
---@field SetValueStep fun(self: statusbar, valueStep: number)
---@field SetOrientation fun(self: statusbar, orientation: string)
---@field SetReverseFill fun(self: statusbar, reverseFill: boolean)
---@field GetMinMaxValues fun(self: statusbar) : number, number
---@field GetValue fun(self: statusbar) : number
---@field GetValueStep fun(self: statusbar) : number
---@field GetOrientation fun(self: statusbar) : string
---@field GetReverseFill fun(self: statusbar) : boolean
---@class texture : UIObject
---@field SetDrawLayer fun(self: texture, layer: string, subLayer: number|nil)
---@class texture : region
---@field SetDrawLayer fun(self: texture, layer: "background"|"border"|"artwork"|"overlay"|"highlight", subLayer: number|nil)
---@field SetTexture fun(self: texture, path: string)
---@field SetColorTexture fun(self: texture, r: red|number, g: green|number, b: blue|number, a: alpha|number)
---@field SetColorTexture fun(self: texture, r: red|number, g: green|number, b: blue|number, a: alpha|number|nil)
---@field SetDesaturated fun(self: texture, desaturate: boolean)
---@field SetBlendMode fun(self: texture, mode: string)
---@field SetVertexColor fun(self: texture, r: red|number, g: green|number, b: blue|number, a: alpha|number)
---@field SetAlpha fun(self: texture, alpha: number)
---@field GetAlpha fun(self: texture) : number
---@field SetWidth fun(self: texture, width: number)
---@field SetHeight fun(self: texture, height: number)
---@field GetWidth fun(self: texture) : number
---@field GetHeight fun(self: texture) : number
---@field SetPoint fun(self: texture, point: string, relativeFrame: table, relativePoint: string, xOfs: number, yOfs: number)
---@field SetBlendMode fun(self: texture, mode: "ADD"|"BLEND"|"DISABLE"|"MOD"|"MOD2X"|"OVERLAY"|"REPLACE"|"SUBTRACT")
---@field SetVertexColor fun(self: texture, r: red|number, g: green|number, b: blue|number, a: alpha|number|nil)
---@field GetPoint fun(self: texture, index: number) : string, table, string, number, number
---@field SetShown fun(self: texture, state: boolean)
---@field IsShown fun(self: texture) : boolean
---@field SetParent fun(self: texture, parent: table)
---@field GetParent fun(self: texture) : table
---@field SetScale fun(self: texture, scale: number)
---@field GetScale fun(self: texture) : number
---@field SetTexCoord fun(self: texture, left: number, right: number, top: number, bottom: number)
---@field GetTexCoord fun(self: texture) : number, number, number, number
---@field SetRotation fun(self: texture, rotation: number)
@@ -263,20 +286,40 @@
---@field GetBlendMode fun(self: texture) : string
---@field GetVertexColor fun(self: texture) : number, number, number, number
---@class details
---@field GetInstance fun(self: details) : instance
---@field GetWindow fun(self: details) : instance this is an alias of GetInstance
---@field GetCombat fun(self: details) : combat
---@field GetSpellSchoolFormatedName fun(self: details, spellschool: number) : string
---@field CommaValue fun(self: details, number: number) : string
---@field CreateEventListener fun(self: details) : table
---@class detailseventlistener : table
---@field RegisterEvent fun(self: detailseventlistener, event: "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"|"DETAILS_INSTANCE_NEWROW"|"DETAILS_OPTIONS_MODIFIED"|"DETAILS_DATA_RESET"|"DETAILS_DATA_SEGMENTREMOVED"|"COMBAT_ENCOUNTER_START"|"COMBAT_ENCOUNTER_END"|"COMBAT_PLAYER_ENTER"|"COMBAT_PLAYER_LEAVE"|"COMBAT_PLAYER_TIMESTARTED"|"COMBAT_BOSS_WIPE"|"COMBAT_BOSS_DEFEATED"|"COMBAT_BOSS_FOUND"|"COMBAT_INVALID"|"COMBAT_PREPOTION_UPDATED"|"COMBAT_CHARTTABLES_CREATING"|"COMBAT_CHARTTABLES_CREATED"|"COMBAT_ENCOUNTER_PHASE_CHANGED"|"COMBAT_ARENA_START"|"COMBAT_ARENA_END"|"COMBAT_MYTHICDUNGEON_START"|"COMBAT_MYTHICDUNGEON_END"|"GROUP_ONENTER"|"GROUP_ONLEAVE"|"ZONE_TYPE_CHANGED"|"REALM_CHANNEL_ENTER"|"REALM_CHANNEL_LEAVE"|"COMM_EVENT_RECEIVED"|"COMM_EVENT_SENT"|"UNIT_SPEC"|"UNIT_TALENTS"|"PLAYER_TARGET"|"DETAILS_PROFILE_APPLYED", callback: function)
---@field UnregisterEvent fun(self: detailseventlistener, event: "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"|"DETAILS_INSTANCE_NEWROW"|"DETAILS_OPTIONS_MODIFIED"|"DETAILS_DATA_RESET"|"DETAILS_DATA_SEGMENTREMOVED"|"COMBAT_ENCOUNTER_START"|"COMBAT_ENCOUNTER_END"|"COMBAT_PLAYER_ENTER"|"COMBAT_PLAYER_LEAVE"|"COMBAT_PLAYER_TIMESTARTED"|"COMBAT_BOSS_WIPE"|"COMBAT_BOSS_DEFEATED"|"COMBAT_BOSS_FOUND"|"COMBAT_INVALID"|"COMBAT_PREPOTION_UPDATED"|"COMBAT_CHARTTABLES_CREATING"|"COMBAT_CHARTTABLES_CREATED"|"COMBAT_ENCOUNTER_PHASE_CHANGED"|"COMBAT_ARENA_START"|"COMBAT_ARENA_END"|"COMBAT_MYTHICDUNGEON_START"|"COMBAT_MYTHICDUNGEON_END"|"GROUP_ONENTER"|"GROUP_ONLEAVE"|"ZONE_TYPE_CHANGED"|"REALM_CHANNEL_ENTER"|"REALM_CHANNEL_LEAVE"|"COMM_EVENT_RECEIVED"|"COMM_EVENT_SENT"|"UNIT_SPEC"|"UNIT_TALENTS"|"PLAYER_TARGET"|"DETAILS_PROFILE_APPLYED")
---@class combat : table
---@field GetCombatTime fun(combat)
---@field GetDeaths fun(combat) --get the table which contains the deaths of the combat
---@field end_time number
---@field start_time number
---@field GetStartTime fun(combat: combat, time: number)
---@field SetStartTime fun(combat: combat, time: number)
---@field GetEndTime fun(combat: combat, time: number)
---@field SetEndTime fun(combat: combat, time: number)
---@field CopyDeathsFrom fun(combat1: combat, combat2: combat, bMythicPlus: boolean) copy the deaths from combat2 to combat1, use true on bMythicPlus if the combat is from a mythic plus run
---@field GetContainer fun(combat: combat, containerType: number) get an actor container, containerType can be 1 for damage, 2 heal, 3 energy, 4 utility
---@field is_mythic_dungeon_trash boolean
---@field is_mythic_dungeon_run_id number
---@field is_mythic_dungeon_segment boolean
---@field GetCombatTime fun(combat) : number
---@field GetDeaths fun(combat) : table --get the table which contains the deaths of the combat
---@field GetStartTime fun(combat: combat) : number
---@field SetStartTime fun(combat: combat, time: number)
---@field GetEndTime fun(combat: combat) : number
---@field SetEndTime fun(combat: combat, time: number)
---@field CopyDeathsFrom fun(combat1: combat, combat2: combat, bMythicPlus: boolean) copy the deaths from combat2 to combat1, use true on bMythicPlus if the combat is from a mythic plus run
---@field GetContainer fun(combat: combat, containerType: number) : actorcontainer get an actor container, containerType can be 1 for damage, 2 heal, 3 energy, 4 utility
---@field GetSpellCastAmount fun(combat: combat, actorName: string, spellId: number) : number get the amount of times a spell was casted
---@field GetSpellUptime fun(combat: combat, actorName: string, spellId: number, auraType: string|nil) : number get the uptime of a buff or debuff
---@class actorcontainer : table
---@field _ActorTable table
@@ -289,24 +332,73 @@
---@field GetActorTable fun(container: actorcontainer) get the table<actorIndex, actorObject> which contains the actors
---@field ListActors fun(container: actorcontainer) usage: for index, actorObject in container:ListActors() do
---@class spellcontainer : table
---@field GetSpell fun(container: spellcontainer, spellId: number) get a spell by its id
---@field ListActors fun(container: spellcontainer) : pairs usage: for spellId, spelltable in container:ListActors() do
---@field _ActorTable table
---@class spelltable : table
---@field uptime number
---@field total number
---@field spellschool number
---@field counter number amount of hits
---@field c_amt number critical hits by a damage or heal spell
---@field c_min number min damage or healing done by critical hits of the spell
---@field c_max number min damage or healing done by critical hits of the spell
---@field c_total number total damage or heal made by critical hits of the spell
---@field n_amt number normal hits by a damage or heal spell
---@field n_min number min damage or healing done by normal hits of the spell
---@field n_max number min damage or healing done by normal hits of the spell
---@field n_total number total damage or heal made by normal hits of the spell
---@field targets table<string, number> store the [target name] = total value
---@field targets_overheal table<string, number>
---@field targets_absorbs table<string, number>
---@field id number --spellid
---@field is_shield boolean --true if the spell is a shield
---@field successful_casted number successful casted times (only for enemies)
---@field g_amt number glacing hits
---@field g_dmg number
---@field r_amt number --resisted
---@field r_dmg number
---@field b_amt number --blocked
---@field b_dmg number
---@field a_amt number --absorved
---@field a_dmg number
---@field isReflection boolean
---@field totalabsorb number healing absorbed
---@field absorbed number damage absorbed by shield | healing absorbed by buff or debuff
---@field overheal number
---@field totaldenied number
---@class targettable : {[string]: number}
---@class actor : table
---@field GetSpellContainer fun(actor: actor, containerType: "debuff"|"buff"|"spell"|"cooldowns") : spellcontainer
---@field Name fun(actor: actor) : string get the name of the actor
---@field Tempo fun(actor: actor) : number get the activity or effective time of the actor
---@field GetPets fun(actor: actor) : table<number, string> get a table with all pet names that belong to the player
---@field GetSpellList fun(actor: actor) : table<number, spelltable>
---@field BuildSpellTargetFromBreakdownSpellData fun(actor: actor, bkSpellData: spelltableadv) : table
---@field BuildSpellTargetFromSpellTable fun(actor: actor, spellTable: spelltable) : table
---@field debuff_uptime_spells table
---@field buff_uptime_spells table
---@field spells table
---@field aID number|string
---@field spellicon number|string
---@field cooldowns_defensive_spells table
---@field nome string
---@field serial string
---@field spec number
---@field grupo boolean
---@field fight_component boolean
---@field boss_fight_component boolean
---@field boss boolean
---@field last_event unixtime
---@field total_without_pet number
---@field total number
---@field spell_cast table<number, number>
---@field pets table<number, string>
---@field targets targettable
---@class segmentid : number
---@class instanceid : number
@@ -344,7 +436,160 @@
---@field RefreshData fun(instance: instance, force: boolean|nil)
---@field RefreshWindow fun(instance: instance, force: boolean|nil)
---@class tabframe : frame this is the tab frame object for the breakdown window
---@class breakdownscrolldata : table
---@field totalValue number total done by the actor
---@field combatTime number
---@field [spelltableadv] spelltableadv indexed part of the table
---@class breakdownexpandbutton : button
---@field texture texture
---@class breakdownspellscrollframe : df_scrollboxmixin, scrollframe
---@field Header df_headerframe
---@field RefreshMe fun(scrollFrame: breakdownspellscrollframe, data: table|nil)
---@class breakdowntargetscrollframe : df_scrollboxmixin, scrollframe
---@field Header df_headerframe
---@field RefreshMe fun(scrollFrame: breakdowntargetscrollframe, data: table|nil)
---@class breakdowntargetbar : button, df_headerfunctions
---@field index number
---@field rank number
---@field name string
---@field percent number
---@field amount number
---@field total number
---@field actorName string
---@field bkTargetData breakdowntargettable
---@field Icon texture
---@field InLineTexts fontstring[]
---@field statusBar breakdownspellbarstatusbar
---@class breakdownspellbar : button, df_headerfunctions
---@field index number
---@field rank number
---@field spellId number
---@field name string
---@field combatTime number
---@field perSecond number
---@field percent number
---@field amountCasts number
---@field average number
---@field castAverage number
---@field onMouseUpTime number GetTime() of when the spellbar got OnMouseUp event
---@field cursorPosX number mouse position when the spellbar got OnMouseDown event
---@field cursorPosY number mouse position when the spellbar got OnMouseDown event
---@field spellTable spelltable
---@field bkSpellData spelltableadv
---@field statusBar breakdownspellbarstatusbar
---@field expandButton breakdownexpandbutton
---@field spellIconFrame frame
---@field spellIcon texture
---@field targetsSquareFrame breakdowntargetframe
---@field targetsSquareTexture texture
---@field overlayTexture texture
---@field bIsExpandedSpell boolean
---@field ExpandedChildren breakdownspellbar[] store the spellbars which are expanded from this spellbar (spellbars shown when the expand button is pressed)
---@field InLineTexts fontstring[]
---@class breakdownspellbarstatusbar : statusbar
---@field backgroundTexture texture
---@field overlayTexture texture
---@field highlightTexture texture
---spelltableadv is similar to spelltable but allow custom members, methods and any modification isn't save to saved variables
---@class spelltableadv : spelltable, spelltablemixin
---@field expanded boolean if is true the show the nested spells
---@field spellTables spelltable[]
---@field spellIds number[]
---@field petNames string[]
---@field bCanExpand boolean
---@field expandedIndex number
---@field bIsExpanded boolean
---@field statusBarValue number
---@class breakdowntargetframe : frame
---@field spellId number
---@field bkSpellData spelltableadv
---@field spellTable spelltable
---@field texture texture
---@field bIsMainLine boolean
---@class breakdowntargettablelist : breakdowntargettable[]
---@field totalValue number
---@field totalValueOverheal number
---@field combatTime number
---@class breakdowntargettable : table
---@field name string
---@field total number
---@field overheal number|nil
---@field absorbed number|nil
---@field statusBarValue number
---@class breakdownspelldatalist : spelltableadv[]
---@field totalValue number
---@field combatTime number
---@class breakdownspellstab : tabframe
---@field SpellScrollFrame breakdownspellscrollframe
---@field SpellBlockFrame breakdownspellblockframe
---@class breakdownspellblockframe : frame container for the spellblocks in the breakdown window
---@field SpellBlocks breakdownspellblock[]
---@field UpdateBlocks fun(self: breakdownspellblockframe)
---@field ClearBlocks fun(self: breakdownspellblockframe)
---@field GetBlock fun(self: breakdownspellblockframe, index: number) : breakdownspellblock
---@class breakdownspellblock : statusbar breakdownspellblock object which is created inside the breakdownspellblockframe
---@field Lines breakdownspellblockline[]
---@field reportButton button
---@field overlay texture
---@field statusBarTexture texture
---@field sparkTexture texture
---@field gradientTexture texture
---@field backgroundTexture texture
---@field GetLine fun(self: breakdownspellblock, index: number) : breakdownspellblockline
---@field GetLines fun(self: breakdownspellblock) : breakdownspellblockline, breakdownspellblockline, breakdownspellblockline
---@field SetColor fun(self: breakdownspellblock, r: any, g: number|nil, b: number|nil, a: number|nil)
---@class breakdownspellblockline : frame a line inside a breakdownspellblock, there's 3 of them in each breakdownspellblock
---@field leftText fontstring
---@field centerText fontstring
---@field rightText fontstring
---@class breakdownspelltab
---@field selectedSpellBar breakdownspellbar
---@field TabFrame breakdownspellstab
---@field mainAttribute number
---@field subAttribute number
---@field GetActor fun() : actor
---@field GetCombat fun() : combat
---@field GetInstance fun() : instance
---@field GetSpellScrollFrame fun() : breakdownspellscrollframe
---@field GetSpellBlockFrame fun() : breakdownspellblockframe
---@field GetTargetScrollFrame fun() : breakdowntargetscrollframe
---@field GetSpellScrollContainer fun() : df_framecontainer
---@field GetSpellBlockContainer fun() : df_framecontainer
---@field GetTargetScrollContainer fun() : df_framecontainer
---@field OnProfileChange fun()
---@field UpdateHeadersSettings fun(containerType: string)
---@field BuildHeaderTable fun(containerType: string) : {name: string, width: number, text: string, align: string}[]
---@field SelectSpellBar fun(spellBar: breakdownspellbar)
---@field UnSelectSpellBar fun()
---@field GetSelectedSpellBar fun() : breakdownspellbar
---@field HasSelectedSpellBar fun() : boolean
---@field OnShownTab fun()
---@field OnCreateTabCallback fun(tabButton: button, tabFrame: frame)
---@field CreateSpellBlock fun(spellBlockContainer: breakdownspellblockframe, index: number) : breakdownspellblock
---@field CreateSpellBlockContainer fun(tabFrame: tabframe) : breakdownspellblockframe
---@field UpdateShownSpellBlock fun()
---@field CreateTargetContainer fun(tabFrame: tabframe) : breakdowntargetscrollframe
---@field CreateSpellScrollContainer fun(tabFrame: tabframe) : breakdownspellscrollframe
---@field CreateTargetBar fun(self: breakdowntargetscrollframe, index: number) : breakdowntargetbar
---@field CreateSpellBar fun(self: breakdownspellscrollframe, index: number) : breakdownspellbar
+3
View File
@@ -87,6 +87,8 @@ frames\window_playerbreakdown_list.lua
frames\window_playerbreakdown_compare.lua
frames\window_playerbreakdown_avoidance.lua
frames\window_playerbreakdown_auras.lua
frames\window_playerbreakdown_spells.lua
frames\window_playerbreakdown_spells_options.lua
frames\window_report.lua
frames\window_main.lua
frames\window_custom.lua
@@ -113,6 +115,7 @@ frames\window_statistics.lua
frames\window_aura_tracker.lua
classes\class_error.lua
classes\class_spelltable.lua
classes\class_combat.lua
classes\class_damage.lua
classes\class_spelldamage.lua
+2
View File
@@ -80,6 +80,8 @@ frames\window_playerbreakdown_list.lua
frames\window_playerbreakdown_compare.lua
frames\window_playerbreakdown_avoidance.lua
frames\window_playerbreakdown_auras.lua
frames\window_playerbreakdown_spells.lua
frames\window_playerbreakdown_spells_options.lua
frames\window_report.lua
frames\window_main.lua
frames\window_custom.lua
+559
View File
@@ -0,0 +1,559 @@
local detailsFramework = _G ["DetailsFramework"]
if (not detailsFramework or not DetailsFrameworkCanLoad) then
return
end
local _
local DF = detailsFramework
local CreateFrame = CreateFrame
local wipe = wipe
local unpack = unpack
---@class df_framecontainer : frame, dfframecontainermixin, df_optionsmixin
---@field bIsSizing boolean
---@field options table
---@field currentWidth number
---@field currentHeight number
---@field bottomLeftResizer framecontainerresizer
---@field bottomRightResizer framecontainerresizer
---@field topLeftResizer framecontainerresizer
---@field topRightResizer framecontainerresizer
---@field topResizer framecontainerresizer
---@field bottomResizer framecontainerresizer
---@field leftResizer framecontainerresizer
---@field rightResizer framecontainerresizer
---@field cornerResizers framecontainerresizer[]
---@field sideResizers framecontainerresizer[]
---@field components table<frame, boolean>
---@field moverFrame frame
---@field movableChildren table<frame, boolean>
---@field settingChangedCallback fun(frameContainer: df_framecontainer, settingName: string, settingValue: any)
---@field OnSizeChanged fun(frameContainer: df_framecontainer)
---@field OnResizerMouseDown fun(resizerButton: button, mouseButton: string)
---@field OnResizerMouseUp fun(resizerButton: button, mouseButton: string)
---@field HideResizer fun(frameContainer: df_framecontainer)
---@field ShowResizer fun(frameContainer: df_framecontainer)
---@field OnInitialize fun(frameContainer: df_framecontainer)
---@field SetResizeLocked fun(frameContainer: df_framecontainer, isLocked: boolean)
---@field SetMovableLocked fun(frameContainer: df_framecontainer, isLocked: boolean)
---@field CheckResizeLockedState fun(frameContainer: df_framecontainer)
---@field CheckMovableLockedState fun(frameContainer: df_framecontainer)
---@field CreateMover fun(frameContainer: df_framecontainer)
---@field CreateResizers fun(frameContainer: df_framecontainer)
---@field RegisterChildForDrag fun(frameContainer: df_framecontainer, child: frame)
---@field UnregisterChildForDrag fun(frameContainer: df_framecontainer, child: frame)
---@field RefreshChildrenState fun(frameContainer: df_framecontainer)
---@field OnChildDragStart fun(frameContainer: df_framecontainer, child: frame)
---@field OnChildDragStop fun(frameContainer: df_framecontainer, child: frame)
---@field SetSettingChangedCallback fun(frameContainer: df_framecontainer, callback: fun(frameContainer: df_framecontainer, settingName: string, settingValue: any))
---@field SendSettingChangedCallback fun(frameContainer: df_framecontainer, settingName: string, settingValue: any)
---@class framecontainerresizer : button
---@field sizingFrom string
---@class dfframecontainermixin
detailsFramework.FrameContainerMixin = {
--methods
---run when the user click on the resizer
---@param resizerButton framecontainerresizer
---@param mouseButton string
OnResizerMouseDown = function(resizerButton, mouseButton)
if (mouseButton ~= "LeftButton") then
return
end
---@type df_framecontainer
local frameContainer = resizerButton:GetParent() --Cannot assign `frame` to `df_framecontainer`. .. but df_framecontainer is inherited from frame
if (frameContainer.bIsSizing) then
return
end
frameContainer.bIsSizing = true
frameContainer:StartSizing(resizerButton.sizingFrom)
end,
---run when the user click on the resizer
---@param resizerButton framecontainerresizer
---@param mouseButton string
OnResizerMouseUp = function(resizerButton, mouseButton)
---@type df_framecontainer
local frameContainer = resizerButton:GetParent() --Cannot assign `frame` to `df_framecontainer`. .. but df_framecontainer is inherited from frame
if (not frameContainer.bIsSizing) then
return
end
frameContainer:StopMovingOrSizing()
frameContainer.bIsSizing = false
end,
---hide resizer
---@param frameContainer df_framecontainer
HideResizer = function(frameContainer)
for i = 1, #frameContainer.cornerResizers do
frameContainer.cornerResizers[i]:Hide()
end
for i = 1, #frameContainer.sideResizers do
frameContainer.sideResizers[i]:Hide()
end
end,
---show resizer
---@param frameContainer df_framecontainer
ShowResizer = function(frameContainer)
--corner resizers
if (frameContainer.options.use_bottomleft_resizer) then
frameContainer.bottomLeftResizer:Show()
end
if (frameContainer.options.use_bottomright_resizer) then
frameContainer.bottomRightResizer:Show()
end
if (frameContainer.options.use_topleft_resizer) then
frameContainer.topRightResizer:Show()
end
if (frameContainer.options.use_topright_resizer) then
frameContainer.topRightResizer:Show()
end
--side resizers
if (frameContainer.options.use_top_resizer) then
frameContainer.topResizer:Show()
end
if (frameContainer.options.use_bottom_resizer) then
frameContainer.bottomResizer:Show()
end
if (frameContainer.options.use_left_resizer) then
frameContainer.leftResizer:Show()
end
if (frameContainer.options.use_right_resizer) then
frameContainer.rightResizer:Show()
end
end,
---check the lock state and show or hide the resizer, set the frame as movable or not, resizeable or not
---@param frameContainer df_framecontainer
CheckResizeLockedState = function(frameContainer)
if (frameContainer.options.is_locked) then
frameContainer:HideResizer()
frameContainer:SetResizable(false)
else
frameContainer:ShowResizer()
frameContainer:SetResizable(true)
end
end,
---check if the framecontainer can be moved and show or hide the mover
---@param frameContainer df_framecontainer
CheckMovableLockedState = function(frameContainer)
if (frameContainer.options.is_movement_locked) then
frameContainer:SetMovable(false)
frameContainer:EnableMouse(false)
frameContainer.moverFrame:Hide()
else
frameContainer:SetMovable(true)
frameContainer:EnableMouse(true)
frameContainer.moverFrame:Show()
end
end,
---set the lock state
---@param frameContainer df_framecontainer
---@param isLocked boolean
SetResizeLocked = function(frameContainer, isLocked)
frameContainer.options.is_locked = isLocked
frameContainer:SendSettingChangedCallback("is_locked", isLocked)
frameContainer:CheckResizeLockedState()
end,
---set the state of the mover frame
---@param frameContainer df_framecontainer
---@param isLocked boolean
SetMovableLocked = function(frameContainer, isLocked)
frameContainer.options.is_movement_locked = isLocked
frameContainer:SendSettingChangedCallback("is_movement_locked", isLocked)
frameContainer:CheckMovableLockedState()
end,
---create a mover to move the frame
---@param frameContainer df_framecontainer
CreateMover = function(frameContainer)
local mover = CreateFrame("button", nil, frameContainer)
frameContainer.moverFrame = mover
mover:SetAllPoints(frameContainer)
mover:EnableMouse(false)
mover:SetMovable(true)
mover:SetScript("OnMouseDown", function(self, mouseButton)
if (mouseButton ~= "LeftButton" or frameContainer.options.is_movement_locked) then
return
end
frameContainer:StartMoving()
end)
mover:SetScript("OnMouseUp", function(self, mouseButton)
if (mouseButton ~= "LeftButton" or frameContainer.options.is_movement_locked) then
return
end
frameContainer:StopMovingOrSizing()
end)
end,
---create four corner resizer and four side resizer
---@param frameContainer df_framecontainer
CreateResizers = function(frameContainer)
local parent = frameContainer:GetParent()
--create resizers for the container corners
local bottomLeftResizer, bottomRightResizer = detailsFramework:CreateResizeGrips(frameContainer, nil, parent:GetName() .. "BottomLeftResizer", parent:GetName() .. "BottomRightResizer")
frameContainer.bottomLeftResizer = bottomLeftResizer
frameContainer.bottomRightResizer = bottomRightResizer
local topLeftResizer, topRightResizer = detailsFramework:CreateResizeGrips(frameContainer, nil, parent:GetName() .. "TopLeftResizer", parent:GetName() .. "TopRightResizer")
frameContainer.topLeftResizer = topLeftResizer
frameContainer.topRightResizer = topRightResizer
local topResizer, bottomResizer = detailsFramework:CreateResizeGrips(frameContainer, nil, parent:GetName() .. "TopResizer", parent:GetName() .. "BottomResizer")
frameContainer.topResizer = topResizer
frameContainer.bottomResizer = bottomResizer
local leftResizer, rightResizer = detailsFramework:CreateResizeGrips(frameContainer, nil, parent:GetName() .. "LeftResizer", parent:GetName() .. "RightResizer")
frameContainer.leftResizer = leftResizer
frameContainer.rightResizer = rightResizer
frameContainer.cornerResizers = {
bottomLeftResizer,
bottomRightResizer,
topLeftResizer,
topRightResizer,
}
frameContainer.sideResizers = {
topResizer,
bottomResizer,
leftResizer,
rightResizer,
}
--add all resizers to the frameContainer.components table
for i = 1, #frameContainer.cornerResizers do
frameContainer.components[frameContainer.cornerResizers[i]] = true
end
for i = 1, #frameContainer.sideResizers do
frameContainer.components[frameContainer.sideResizers[i]] = true
end
--hide all resizers
frameContainer:HideResizer()
end,
---run when the container is created
---@param frameContainer df_framecontainer
OnInitialize = function(frameContainer) --õninit ~init ~oninit
--set the default members
frameContainer.bIsSizing = false
frameContainer:SetSize(frameContainer.options.width, frameContainer.options.height)
--iterate among the corner resizers and set the mouse down and up scripts
for i = 1, #frameContainer.cornerResizers do
frameContainer.cornerResizers[i]:SetScript("OnMouseDown", frameContainer.OnResizerMouseDown)
frameContainer.cornerResizers[i]:SetScript("OnMouseUp", frameContainer.OnResizerMouseUp)
end
local sideResizeThickness = 2
--iterate among the side resizers and set the mouse down and up scripts; set the texture color; clear all points; set the thickness
for i = 1, #frameContainer.sideResizers do
frameContainer.sideResizers[i]:SetScript("OnMouseDown", frameContainer.OnResizerMouseDown)
frameContainer.sideResizers[i]:SetScript("OnMouseUp", frameContainer.OnResizerMouseUp)
frameContainer.sideResizers[i]:GetNormalTexture():SetColorTexture(1, 1, 1, 0.6)
frameContainer.sideResizers[i]:GetHighlightTexture():SetColorTexture(detailsFramework:ParseColors("aqua"))
frameContainer.sideResizers[i]:GetPushedTexture():SetColorTexture(1, 1, 1, 1)
frameContainer.sideResizers[i]:ClearAllPoints()
--can use SetSize here because the width or height are set by the point, e.g. 'topleft' to 'topright' overwrite the width set here
frameContainer.sideResizers[i]:SetSize(sideResizeThickness, sideResizeThickness)
end
--flip the corner resizers texturess
frameContainer.topLeftResizer:GetNormalTexture():SetTexCoord(1, 0, 1, 0)
frameContainer.topLeftResizer:GetHighlightTexture():SetTexCoord(1, 0, 1, 0)
frameContainer.topLeftResizer:GetPushedTexture():SetTexCoord(1, 0, 1, 0)
frameContainer.topRightResizer:GetNormalTexture():SetTexCoord(0, 1, 1, 0)
frameContainer.topRightResizer:GetHighlightTexture():SetTexCoord(0, 1, 1, 0)
frameContainer.topRightResizer:GetPushedTexture():SetTexCoord(0, 1, 1, 0)
frameContainer.topLeftResizer:ClearAllPoints()
frameContainer.topLeftResizer:SetPoint("topleft", frameContainer, "topleft", 0, 0)
frameContainer.topRightResizer:ClearAllPoints()
frameContainer.topRightResizer:SetPoint("topright", frameContainer, "topright", 0, 0)
--resize from for the corner resizers
frameContainer.bottomLeftResizer.sizingFrom = "bottomleft"
frameContainer.bottomRightResizer.sizingFrom = "bottomright"
frameContainer.topLeftResizer.sizingFrom = "topleft"
frameContainer.topRightResizer.sizingFrom = "topright"
--resize from for the side resizers
frameContainer.topResizer.sizingFrom = "top"
frameContainer.bottomResizer.sizingFrom = "bottom"
frameContainer.leftResizer.sizingFrom = "left"
frameContainer.rightResizer.sizingFrom = "right"
--set the side resizer points
frameContainer.topResizer:SetPoint("topleft", frameContainer, "topleft", 0, 2)
frameContainer.topResizer:SetPoint("topright", frameContainer, "topright", 0, 2)
frameContainer.bottomResizer:SetPoint("bottomleft", frameContainer, "bottomleft", 0, -2)
frameContainer.bottomResizer:SetPoint("bottomright", frameContainer, "bottomright", 0, -2)
frameContainer.leftResizer:SetPoint("topleft", frameContainer, "topleft", -2, 0)
frameContainer.leftResizer:SetPoint("bottomleft", frameContainer, "bottomleft", -2, 0)
frameContainer.rightResizer:SetPoint("topright", frameContainer, "topright", 2, 0)
frameContainer.rightResizer:SetPoint("bottomright", frameContainer, "bottomright", 2, 0)
if (frameContainer.options.is_locked) then
frameContainer:HideResizer()
else
frameContainer:ShowResizer()
end
frameContainer:CheckResizeLockedState()
frameContainer:CheckMovableLockedState()
frameContainer:SetResizeBounds(50, 50, 1000, 1000)
end,
---run when the container has its size changed
---@param frameContainer df_framecontainer
OnSizeChanged = function(frameContainer)
---@type frame[]
local children = {frameContainer:GetChildren()}
---@type number
local childrenAmount = #children
--get the container size before its size was changed and calculate the percent of the difference between the old size and the new size
--adding +1 to the width and height difference to prevent the child from shrinking to 0, so it is scaled by 1
---@type number
local widthDifference = 1 + (frameContainer:GetWidth() - frameContainer.currentWidth) / frameContainer.currentWidth
---@type number
local heightDifference = 1 + (frameContainer:GetHeight() - frameContainer.currentHeight) / frameContainer.currentHeight
for i = 1, childrenAmount do
---@type frame
local child = children[i]
--if the child is a component, skip it
if (not frameContainer.components[child]) then
child:SetWidth(child:GetWidth() * widthDifference)
child:SetHeight(child:GetHeight() * heightDifference)
end
end
--update the current size of the container
frameContainer.currentWidth = frameContainer:GetWidth()
frameContainer.currentHeight = frameContainer:GetHeight()
frameContainer:SendSettingChangedCallback("width", frameContainer.currentWidth)
frameContainer:SendSettingChangedCallback("height", frameContainer.currentHeight)
end,
OnChildDragStop = function(child)
child:StopMovingOrSizing()
child:SetScript("OnUpdate", nil)
end,
---@param child frame
OnChildDragStart = function(child)
---@type df_framecontainer
local frameContainer = child:GetParent()
---get the coordinates for the frame container, which is called 'boundingBox' for convenience
---@type objectcoordinates
local boundingBox = detailsFramework:GetObjectCoordinates(frameContainer)
child:StartMoving()
--save the current point of the child, so it can be restored if the child is dragged outside the container
local childPoints = {}
for pointIndex = 1, child:GetNumPoints() do
childPoints[pointIndex] = {child:GetPoint(pointIndex)}
end
child:SetScript("OnUpdate", function(self)
---@type objectcoordinates
local childPos = detailsFramework:GetObjectCoordinates(self)
--check if the borders of the rectangle 'rec' collided with the borders of the rectangle 'bbox'
if ((childPos.left < boundingBox.left or childPos.right > boundingBox.right) or (childPos.top > boundingBox.top or childPos.bottom < boundingBox.bottom)) then
child:ClearAllPoints()
for pointIndex = 1, #childPoints do
child:SetPoint(unpack(childPoints[pointIndex]))
end
else
wipe(childPoints)
for pointIndex = 1, child:GetNumPoints() do
childPoints[pointIndex] = {child:GetPoint(pointIndex)}
end
end
end)
end,
---check if the children can be moved and set the properties on thisFrame
---@param frameContainer df_framecontainer
RefreshChildrenState = function(frameContainer)
frameContainer:EnableMouse(true)
if (frameContainer.options.can_move_children) then
for child, _ in pairs(frameContainer.movableChildren) do
child:EnableMouse(true)
child:SetMovable(true)
child:RegisterForDrag("LeftButton")
child:SetScript("OnDragStart", detailsFramework.FrameContainerMixin.OnChildDragStart)
child:SetScript("OnDragStop", detailsFramework.FrameContainerMixin.OnChildDragStop)
end
else
for child, _ in pairs(frameContainer.movableChildren) do
child:EnableMouse(false)
child:SetMovable(false)
child:RegisterForDrag("")
child:SetScript("OnDragStart", nil)
child:SetScript("OnDragStop", nil)
end
end
end,
---@param frameContainer df_framecontainer
---@param child frame
RegisterChildForDrag = function(frameContainer, child)
frameContainer.movableChildren[child] = true
frameContainer:RefreshChildrenState()
child:SetFrameStrata(frameContainer:GetFrameStrata())
child:SetFrameLevel(frameContainer:GetFrameLevel() + 1)
end,
---@param frameContainer df_framecontainer
---@param child frame
UnregisterChildForDrag = function(frameContainer, child)
frameContainer.movableChildren[child] = nil
frameContainer:RefreshChildrenState()
end,
---@param frameContainer df_framecontainer
---@param callback function
SetSettingChangedCallback = function(frameContainer, callback)
frameContainer.settingChangedCallback = callback
end,
---send a callback to the setting changed callback
---@param frameContainer df_framecontainer
---@param key string
---@param value any
SendSettingChangedCallback = function(frameContainer, key, value)
if (type(frameContainer.settingChangedCallback) == "function") then
detailsFramework:Dispatch(frameContainer.settingChangedCallback, frameContainer, key, value)
end
end,
}
---these are the default settings for the frame container; these keys can be accessed by df_framecontainer.options[key]
---@type table<string, any>
local frameContainerOptions = {
--default settings
width = 300,
height = 150,
is_locked = true, --can or not be resized
is_movement_locked = true, --can or not be moved
can_move_children = true,
use_topleft_resizer = false,
use_topright_resizer = false,
use_bottomleft_resizer = false,
use_bottomright_resizer = false,
use_top_resizer = false,
use_bottom_resizer = false,
use_left_resizer = false,
use_right_resizer = false,
}
---create a frame container, which is a frame that envelops another frame, and can be moved, resized, etc.
---@param parent frame
---@param options table|nil
---@param frameName string|nil
---@return df_framecontainer
function DF:CreateFrameContainer(parent, options, frameName)
---@type df_framecontainer
local frameContainer = CreateFrame("frame", frameName or ("$parentFrameContainer" .. math.random(10000, 99999)), parent, "BackdropTemplate")
frameContainer.components = {}
frameContainer.movableChildren = {}
frameContainer:EnableMouse(false)
detailsFramework:Mixin(frameContainer, detailsFramework.FrameContainerMixin)
detailsFramework:Mixin(frameContainer, detailsFramework.OptionsFunctions)
frameContainer:CreateResizers()
frameContainer:CreateMover()
frameContainer:BuildOptionsTable(frameContainerOptions, options)
frameContainer:OnInitialize()
frameContainer.currentWidth = frameContainer:GetWidth()
frameContainer.currentHeight = frameContainer:GetHeight()
frameContainer:SetScript("OnSizeChanged", frameContainer.OnSizeChanged)
return frameContainer
end
function DF:CreateFrameContainerTest(parent, options, frameName)
local container = DF:CreateFrameContainer(parent, options, frameName)
container:SetSize(400, 400)
container:SetPoint("center", _G.UIParent, "center", 0, 0)
detailsFramework:ApplyStandardBackdrop(container)
local verticalLastBox = nil
for i = 1, 4 do
local lastBox = nil
for o = 1, 4 do
local frame = CreateFrame("frame", "$parentFrame" .. i .. o, container, "BackdropTemplate")
container:RegisterChildForDrag(frame)
frame:SetBackdrop({edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true})
frame:SetBackdropColor(0, 0, 0, 0.5)
frame:SetBackdropBorderColor(1, 1, 1, 0.5)
frame:SetSize(98, 98)
if (lastBox) then
frame:SetPoint("TOPLEFT", lastBox, "topright", 1, 0)
else
if (verticalLastBox) then
frame:SetPoint("TOPLEFT", verticalLastBox, "bottomleft", 0, -1)
verticalLastBox = frame
else
local x = 1 + (o - 1) * 99
local y = -10 - (i - 1) * 99
frame:SetPoint("TOPLEFT", container, "TOPLEFT", x, y)
verticalLastBox = frame
end
end
lastBox = frame
end
end
C_Timer.After(2, function()
--container:SetResizeLocked(true)
end)
end
--C_Timer.After(2, function()
-- DetailsFramework:CreateFrameContainerTest(UIParent)
--end)
--[=[
/run DetailsFramework:CreateFrameContainerTest(UIParent)
C_Timer.After(2, function()
DetailsFramework:CreateFrameContainerTest(UIParent)
end)
--]=]
+15 -16
View File
@@ -1,6 +1,6 @@
local dversion = 421
local dversion = 422
local major, minor = "DetailsFramework-1.0", dversion
local DF, oldminor = LibStub:NewLibrary(major, minor)
@@ -827,35 +827,34 @@ end
---@param value number
---@return string
function DF:IntegerToTimer(value) --~formattime
return "" .. floor(value/60) .. ":" .. format("%02.f", value%60)
return "" .. math.floor(value/60) .. ":" .. string.format("%02.f", value%60)
end
---remove the realm name from a name
---@param name string
---@return string
---@return string, number
function DF:RemoveRealmName(name)
return name:gsub(("%-.*"), "")
end
---remove the realm name from a name
---@param name string
---@return string
---@return string, number
function DF:RemoveRealName(name)
return name:gsub(("%-.*"), "")
end
---get the UIObject of type 'FontString' named fontString and set the font size to the maximum value of the arguments
---@param fontString FontString
---@param fontString fontstring
---@vararg number
function DF:SetFontSize(fontString, ...)
local font, _, flags = fontString:GetFont()
fontString:SetFont(font, max(...), flags)
fontString:SetFont(font, math.max(...), flags)
end
---get the UIObject of type 'FontString' named fontString and set the font to the argument fontface
---@param fontString FontString
---@param fontString fontstring
---@param fontface string
---@return nil
function DF:SetFontFace(fontString, fontface)
local font = SharedMedia:Fetch("font", fontface, true)
if (font) then
@@ -867,26 +866,24 @@ function DF:SetFontFace(fontString, fontface)
end
---get the FontString passed and set the font color
---@param fontString FontString
---@param fontString fontstring
---@param r any
---@param g number|nil
---@param b number|nil
---@param a number|nil
---@return nil
function DF:SetFontColor(fontString, r, g, b, a)
r, g, b, a = DF:ParseColors(r, g, b, a)
fontString:SetTextColor(r, g, b, a)
end
---get the FontString passed and set the font shadow color and offset
---@param fontString FontString
---@param fontString fontstring
---@param r number
---@param g number
---@param b number
---@param a number
---@param x number
---@param y number
---@return nil
function DF:SetFontShadow(fontString, r, g, b, a, x, y)
r, g, b, a = DF:ParseColors(r, g, b, a)
fontString:SetShadowColor(r, g, b, a)
@@ -899,9 +896,8 @@ function DF:SetFontShadow(fontString, r, g, b, a, x, y)
end
---get the FontString object passed and set the rotation of the text shown
---@param fontString FontString
---@param fontString fontstring
---@param degrees number
---@return nil
function DF:SetFontRotation(fontString, degrees)
if (type(degrees) == "number") then
if (not fontString.__rotationAnimation) then
@@ -3343,8 +3339,11 @@ function DF:OpenInterfaceProfile()
end
-----------------------------
--safe copy from blizz api
function DF:Mixin(object, ...)
---copy all members from #2 ... to #1 object
---@param object table
---@param ... any
---@return any
function DF:Mixin(object, ...) --safe copy from blizz api
for i = 1, select("#", ...) do
local mixin = select(i, ...)
for key, value in pairs(mixin) do
+634
View File
@@ -0,0 +1,634 @@
local detailsFramework = DetailsFramework
if (not detailsFramework or not DetailsFrameworkCanLoad) then
return
end
local unpack = unpack
local CreateFrame = CreateFrame
local geterrorhandler = geterrorhandler
local wipe = wipe
--definitions
---@class df_headerchild : uiobject
---@field FramesToAlign table
---@class df_headerframe : frame, df_headermixin, df_optionsmixin
---@field columnHeadersCreated df_headercolumnframe[]
---@field options table
---@field HeaderTable table
---@field columnSelected number
---@class df_headermixin : table
---@field NextHeader number
---@field HeaderWidth number
---@field HeaderHeight number
---@field OnColumnSettingChangeCallback function
---@field GetColumnWidth fun(self: df_headerframe, columnId: number)
---@field SetHeaderTable fun(self: df_headerframe, newTable)
---@field GetSelectedColumn fun(self: df_headerframe) : number, string, string
---@field Refresh fun(self: df_headerframe)
---@field UpdateSortArrow fun(self: df_headerframe, columnHeader: df_headercolumnframe, defaultShown: boolean|nil, defaultOrder: string|nil)
---@field UpdateColumnHeader fun(self: df_headerframe, columnHeader: df_headercolumnframe, headerIndex)
---@field ResetColumnHeaderBackdrop fun(self: df_headerframe, columnHeader: df_headercolumnframe)
---@field SetBackdropColorForSelectedColumnHeader fun(self: df_headerframe, columnHeader: df_headercolumnframe)
---@field ClearColumnHeader fun(self: df_headerframe, columnHeader: df_headercolumnframe)
---@field GetNextHeader fun(self: df_headerframe) : df_headercolumnframe
---@field SetColumnSettingChangedCallback fun(self: df_headerframe, func: function) : boolean
---@class df_headercolumnframe : frame
---@field Icon texture
---@field Text fontstring
---@field Arrow texture
---@field Separator texture
---@field resizerButton df_headerresizer
---@field bIsRezising boolean
---@field bInUse boolean
---@field columnData table
---@field order string
---@field columnIndex number
---@field columnAlign string
---@field XPosition number
---@field columnOffset number
---@field key string used to sort the values
---@class df_headerresizer : button
---@field texture texture
--mixed functions
---@class df_headerfunctions : table
detailsFramework.HeaderFunctions = {
---comment
---@param self df_headerchild
---@param frame uiobject
AddFrameToHeaderAlignment = function(self, frame)
self.FramesToAlign = self.FramesToAlign or {}
table.insert(self.FramesToAlign, frame)
end,
---comment
---@param self df_headerchild
ResetFramesToHeaderAlignment = function(self)
wipe(self.FramesToAlign)
end,
SetFramesToHeaderAlignment = function(self, ...)
---@cast self df_headerchild
wipe(self.FramesToAlign)
self.FramesToAlign = {...}
end,
GetFramesFromHeaderAlignment = function(self, frame)
return self.FramesToAlign or {}
end,
---@param self uiobject
---@param headerFrame df_headerframe
---@param anchor string
AlignWithHeader = function(self, headerFrame, anchor)
local columnHeaderFrames = headerFrame.columnHeadersCreated
anchor = anchor or "topleft"
---@cast self df_headerchild
for i = 1, #self.FramesToAlign do
local frame = self.FramesToAlign[i]
frame:ClearAllPoints()
---@type df_headercolumnframe
local columnHeader = columnHeaderFrames[i]
if (columnHeader) then
local offset = 0
if (columnHeader.columnAlign == "right") then
offset = columnHeader:GetWidth()
if (frame:GetObjectType() == "FontString") then
frame:SetJustifyH("right")
end
end
frame:SetPoint(columnHeader.columnAlign, self, anchor, columnHeader.XPosition + columnHeader.columnOffset + offset, 0)
end
end
end,
---comment
---@param columnHeader df_headercolumnframe
---@param buttonClicked string
OnClick = function(columnHeader, buttonClicked)
--get the header main frame
---@type df_headerframe
local headerFrame = columnHeader:GetParent()
--if this header does not have a clickable header, just ignore
if (not headerFrame.columnSelected) then
return
end
--check if this column has 'canSort' key, otherwise ignore the click
if (not columnHeader.columnData.canSort) then
return
end
--get the latest column header selected
---@type df_headercolumnframe
local previousColumnHeader = headerFrame.columnHeadersCreated[headerFrame.columnSelected]
previousColumnHeader.Arrow:Hide()
headerFrame:ResetColumnHeaderBackdrop(previousColumnHeader)
headerFrame:SetBackdropColorForSelectedColumnHeader(columnHeader)
if (headerFrame.columnSelected == columnHeader.columnIndex) then
columnHeader.order = columnHeader.order ~= "ASC" and "ASC" or "DESC"
end
headerFrame.columnOrder = columnHeader.order
--set the new column header selected
headerFrame.columnSelected = columnHeader.columnIndex
headerFrame:UpdateSortArrow(columnHeader)
if (headerFrame.options.header_click_callback) then
--callback with the main header frame, column header, column index and column order as payload
local okay, errortext = pcall(headerFrame.options.header_click_callback, headerFrame, columnHeader, columnHeader.columnIndex, columnHeader.order)
if (not okay) then
print("DF: Header onClick callback error:", errortext)
end
end
end,
---comment
---@param self button
---@param buttonClicked string
OnMouseDown = function(self, buttonClicked)
if (buttonClicked == "LeftButton") then
end
end,
---comment
---@param self button
---@param buttonClicked string
OnMouseUp = function(self, buttonClicked)
if (buttonClicked == "LeftButton") then
end
end,
}
---@class df_headermixin : table
detailsFramework.HeaderMixin = {
---@param self df_headerframe
---@param columnId number
---@return number
GetColumnWidth = function(self, columnId)
return self.HeaderTable[columnId].width
end,
---@param self df_headerframe
---@param newTable table
SetHeaderTable = function(self, newTable)
self.columnHeadersCreated = self.columnHeadersCreated or {}
self.HeaderTable = newTable
self.NextHeader = 1
self.HeaderWidth = 0
self.HeaderHeight = 0
self:Refresh()
end,
---@param self df_headerframe
---@param func function
---@return boolean
SetColumnSettingChangedCallback = function(self, func)
if (type(func) ~= "function") then
self.OnColumnSettingChangeCallback = nil
return false
end
self.OnColumnSettingChangeCallback = func
return true
end,
--return which header is current selected and the the order ASC DESC
---@param self df_headerframe
---@return number, string
GetSelectedColumn = function(self)
---@type number
local columnSelected = self.columnSelected
---@type df_headercolumnframe
local columnHeader = self.columnHeadersCreated[columnSelected or 1]
return columnSelected, columnHeader.order, columnHeader.key
end,
--clean up and rebuild the header following the header options
--@self: main header frame
---@param self df_headerframe
Refresh = function(self)
--refresh background frame
self:SetBackdrop(self.options.backdrop)
self:SetBackdropColor(unpack(self.options.backdrop_color))
self:SetBackdropBorderColor(unpack(self.options.backdrop_border_color))
--reset all header frames
for i = 1, #self.columnHeadersCreated do
local columnHeader = self.columnHeadersCreated[i]
columnHeader.bInUse = false
columnHeader:Hide()
end
local previousColumnHeader
local growDirection = string.lower(self.options.grow_direction)
--amount of headers to be updated
local headerSize = #self.HeaderTable
--update header frames
for i = 1, headerSize do
--get the header button, a new one is created if it doesn't exists yet
local columnHeader = self:GetNextHeader()
self:UpdateColumnHeader(columnHeader, i)
--grow direction
if (not previousColumnHeader) then
columnHeader:SetPoint("topleft", self, "topleft", 0, 0)
if (growDirection == "right") then
if (self.options.use_line_separators) then
columnHeader.Separator:Show()
columnHeader.Separator:SetWidth(self.options.line_separator_width)
columnHeader.Separator:SetColorTexture(unpack(self.options.line_separator_color))
columnHeader.Separator:ClearAllPoints()
if (self.options.line_separator_gap_align) then
columnHeader.Separator:SetPoint("topleft", columnHeader, "topright", 0, 0)
else
columnHeader.Separator:SetPoint("topright", columnHeader, "topright", 0, 0)
end
columnHeader.Separator:SetHeight(self.options.line_separator_height)
end
end
else
if (growDirection == "right") then
columnHeader:SetPoint("topleft", previousColumnHeader, "topright", self.options.padding, 0)
if (self.options.use_line_separators) then
columnHeader.Separator:Show()
columnHeader.Separator:SetWidth(self.options.line_separator_width)
columnHeader.Separator:SetColorTexture(unpack(self.options.line_separator_color))
columnHeader.Separator:ClearAllPoints()
if (self.options.line_separator_gap_align) then
columnHeader.Separator:SetPoint("topleft", columnHeader, "topright", 0, 0)
else
columnHeader.Separator:SetPoint("topleft", columnHeader, "topright", 0, 0)
end
columnHeader.Separator:SetHeight(self.options.line_separator_height)
if (headerSize == i) then
columnHeader.Separator:Hide()
end
end
elseif (growDirection == "left") then
columnHeader:SetPoint("topright", previousColumnHeader, "topleft", -self.options.padding, 0)
elseif (growDirection == "bottom") then
columnHeader:SetPoint("topleft", previousColumnHeader, "bottomleft", 0, -self.options.padding)
elseif (growDirection == "top") then
columnHeader:SetPoint("bottomleft", previousColumnHeader, "topleft", 0, self.options.padding)
end
end
previousColumnHeader = columnHeader
end
self:SetSize(self.HeaderWidth, self.HeaderHeight)
end,
---@param self df_headerframe
---@param columnHeader df_headercolumnframe
---@param defaultShown boolean
---@param defaultOrder string
UpdateSortArrow = function(self, columnHeader, defaultShown, defaultOrder)
local options = self.options
local order = defaultOrder or columnHeader.order
local arrowIcon = columnHeader.Arrow
if (type(defaultShown) ~= "boolean") then
arrowIcon:Show()
else
arrowIcon:SetShown(defaultShown)
if (defaultShown) then
self:SetBackdropColorForSelectedColumnHeader(columnHeader)
end
end
arrowIcon:SetAlpha(options.arrow_alpha)
if (order == "ASC") then
arrowIcon:SetTexture(options.arrow_up_texture)
arrowIcon:SetTexCoord(unpack(options.arrow_up_texture_coords))
arrowIcon:SetSize(unpack(options.arrow_up_size))
elseif (order == "DESC") then
arrowIcon:SetTexture(options.arrow_down_texture)
arrowIcon:SetTexCoord(unpack(options.arrow_down_texture_coords))
arrowIcon:SetSize(unpack(options.arrow_down_size))
end
end,
---@param self df_headerframe
---@param columnHeader df_headercolumnframe
---@param headerIndex number
UpdateColumnHeader = function(self, columnHeader, headerIndex)
--this is the data to update the columnHeader
local columnData = self.HeaderTable[headerIndex]
columnHeader.key = columnData.key or "total"
if (columnData.icon) then
columnHeader.Icon:SetTexture(columnData.icon)
if (columnData.texcoord) then
columnHeader.Icon:SetTexCoord(unpack(columnData.texcoord))
else
columnHeader.Icon:SetTexCoord(0, 1, 0, 1)
end
columnHeader.Icon:SetPoint("left", columnHeader, "left", self.options.padding, 0)
columnHeader.Icon:Show()
end
if (columnData.text) then
columnHeader.Text:SetText(columnData.text)
--text options
detailsFramework:SetFontColor(columnHeader.Text, self.options.text_color)
detailsFramework:SetFontSize(columnHeader.Text, self.options.text_size)
detailsFramework:SetFontOutline(columnHeader.Text, self.options.text_shadow)
--point
if (not columnData.icon) then
columnHeader.Text:SetPoint("left", columnHeader, "left", self.options.padding, 0)
else
columnHeader.Text:SetPoint("left", columnHeader.Icon, "right", self.options.padding, 0)
end
columnHeader.Text:Show()
end
--column header index
columnHeader.columnIndex = headerIndex
if (columnData.canSort) then
columnHeader.order = "DESC"
columnHeader.Arrow:SetTexture(self.options.arrow_up_texture)
else
columnHeader.Arrow:Hide()
end
if (columnData.selected) then
columnHeader.Arrow:Show()
columnHeader.Arrow:SetAlpha(.843)
self:UpdateSortArrow(columnHeader, true, columnHeader.order)
self.columnSelected = headerIndex
else
if (columnData.canSort) then
self:UpdateSortArrow(columnHeader, false, columnHeader.order)
end
end
--size
if (columnData.width) then
columnHeader:SetWidth(columnData.width)
end
if (columnData.height) then
columnHeader:SetHeight(columnData.height)
end
columnHeader.XPosition = self.HeaderWidth -- + self.options.padding
columnHeader.YPosition = self.HeaderHeight -- + self.options.padding
columnHeader.columnAlign = columnData.align or "left"
columnHeader.columnOffset = columnData.offset or 0
--add the header piece size to the total header size
local growDirection = string.lower(self.options.grow_direction)
if (growDirection == "right" or growDirection == "left") then
self.HeaderWidth = self.HeaderWidth + columnHeader:GetWidth() + self.options.padding
self.HeaderHeight = math.max(self.HeaderHeight, columnHeader:GetHeight())
elseif (growDirection == "top" or growDirection == "bottom") then
self.HeaderWidth = math.max(self.HeaderWidth, columnHeader:GetWidth())
self.HeaderHeight = self.HeaderHeight + columnHeader:GetHeight() + self.options.padding
end
local bShowColumnHeaderReziser = self.options.reziser_shown
if (bShowColumnHeaderReziser) then
local resizerButton = columnHeader.resizerButton
resizerButton:Show()
resizerButton.texture:SetVertexColor(unpack(self.options.reziser_color))
resizerButton:SetWidth(self.options.reziser_width)
resizerButton:SetHeight(columnHeader:GetHeight())
else
columnHeader.resizerButton:Hide()
end
columnHeader:Show()
columnHeader.bInUse = true
columnHeader.columnData = columnData
end,
---reset column header backdrop
---@param self df_headerframe
---@param columnHeader df_headercolumnframe
ResetColumnHeaderBackdrop = function(self, columnHeader)
columnHeader:SetBackdrop(self.options.header_backdrop)
columnHeader:SetBackdropColor(unpack(self.options.header_backdrop_color))
columnHeader:SetBackdropBorderColor(unpack(self.options.header_backdrop_border_color))
end,
---@param self df_headerframe
---@param columnHeader df_headercolumnframe
SetBackdropColorForSelectedColumnHeader = function(self, columnHeader)
columnHeader:SetBackdropColor(unpack(self.options.header_backdrop_color_selected))
end,
---clear the column header
---@param self df_headerframe
---@param columnHeader df_headercolumnframe
ClearColumnHeader = function(self, columnHeader)
columnHeader:SetSize(self.options.header_width, self.options.header_height)
self:ResetColumnHeaderBackdrop(columnHeader)
columnHeader:ClearAllPoints()
columnHeader.Icon:SetTexture("")
columnHeader.Icon:Hide()
columnHeader.Text:SetText("")
columnHeader.Text:Hide()
end,
---get the next column header, create one if doesn't exists
---@param self df_headerframe
GetNextHeader = function(self)
local nextHeader = self.NextHeader
local columnHeader = self.columnHeadersCreated[nextHeader]
if (not columnHeader) then
--create a new column header
---@type df_headercolumnframe
columnHeader = CreateFrame("button", "$parentHeaderIndex" .. nextHeader, self, "BackdropTemplate")
columnHeader:SetScript("OnClick", detailsFramework.HeaderFunctions.OnClick)
columnHeader:SetMovable(true)
columnHeader:SetResizable(true)
--header icon
detailsFramework:CreateImage(columnHeader, "", self.options.header_height, self.options.header_height, "ARTWORK", nil, "Icon", "$parentIcon")
--header separator
detailsFramework:CreateImage(columnHeader, "", 1, 1, "ARTWORK", nil, "Separator", "$parentSeparator")
--header name text
detailsFramework:CreateLabel(columnHeader, "", self.options.text_size, self.options.text_color, "GameFontNormal", "Text", "$parentText", "ARTWORK")
--header selected and order icon
detailsFramework:CreateImage(columnHeader, self.options.arrow_up_texture, 12, 12, "ARTWORK", nil, "Arrow", "$parentArrow")
---rezise button
---@type df_headerresizer
local resizerButton = CreateFrame("button", "$parentResizer", columnHeader)
resizerButton:SetWidth(4)
resizerButton:SetFrameLevel(columnHeader:GetFrameLevel()+2)
resizerButton:SetPoint("topright", columnHeader, "topright", -1, -1)
resizerButton:SetPoint("bottomright", columnHeader, "bottomright", -1, 1)
resizerButton:EnableMouse(true)
resizerButton:RegisterForClicks("LeftButtonDown", "LeftButtonUp")
columnHeader.resizerButton = resizerButton
resizerButton:SetScript("OnEnter", function()
resizerButton.texture:SetVertexColor(1, 1, 1, 0.9)
end)
resizerButton:SetScript("OnLeave", function()
resizerButton.texture:SetVertexColor(unpack(self.options.reziser_color))
end)
resizerButton:SetScript("OnMouseDown", function() --move this to a single function
if (not columnHeader.bIsRezising) then
--get the string length to know the min size
local textLength = columnHeader.Text:GetStringWidth() + 6
columnHeader:SetResizeBounds(math.max(textLength, self.options.reziser_min_width), columnHeader:GetHeight(), self.options.reziser_max_width, columnHeader:GetHeight())
columnHeader.bIsRezising = true
columnHeader:StartSizing("right")
end
end)
resizerButton:SetScript("OnMouseUp", function()
if (columnHeader.bIsRezising) then
columnHeader.bIsRezising = false
columnHeader:StopMovingOrSizing()
--callback or modify into a passed by table?
if (self.OnColumnSettingChangeCallback) then --need to get the header name
local columnName = columnHeader.columnData.name
xpcall(self.OnColumnSettingChangeCallback, geterrorhandler(), self, "width", columnName, columnHeader:GetWidth())
end
end
end)
resizerButton:SetScript("OnHide", function()
if (columnHeader.bIsRezising) then
columnHeader:StopMovingOrSizing()
columnHeader.bIsRezising = false
end
end)
resizerButton.texture = resizerButton:CreateTexture(nil, "overlay")
resizerButton.texture:SetAllPoints()
resizerButton.texture:SetColorTexture(1, 1, 1, 1)
local xOffset = self.options.reziser_shown and -5 or -1
columnHeader.Arrow:SetPoint("right", columnHeader, "right", xOffset, 0)
columnHeader.Separator:Hide()
columnHeader.Arrow:Hide()
self:UpdateSortArrow(columnHeader, false, "DESC")
table.insert(self.columnHeadersCreated, columnHeader)
columnHeader = columnHeader
end
self:ClearColumnHeader(columnHeader)
self.NextHeader = self.NextHeader + 1
return columnHeader
end,
NextHeader = 1,
HeaderWidth = 0,
HeaderHeight = 0,
}
local default_header_options = {
backdrop = {edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true},
backdrop_color = {0, 0, 0, 0.2},
backdrop_border_color = {0.1, 0.1, 0.1, .2},
text_color = {1, 1, 1, 1},
text_size = 10,
text_shadow = false,
grow_direction = "RIGHT",
padding = 2,
reziser_shown = false, --make sure to set the callback function with: header:SetOnColumnResizeScript(callbackFunction)
reziser_width = 2,
reziser_color = {1, 0.6, 0, 0.6},
reziser_min_width = 16,
reziser_max_width = 200,
--each piece of the header
header_backdrop = {bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true},
header_backdrop_color = {0, 0, 0, 0.5},
header_backdrop_color_selected = {0.3, 0.3, 0.3, 0.5},
header_backdrop_border_color = {0, 0, 0, 0},
header_width = 120,
header_height = 20,
arrow_up_texture = [[Interface\Buttons\Arrow-Up-Down]],
arrow_up_texture_coords = {0, 1, 6/16, 1},
arrow_up_size = {12, 11},
arrow_down_texture = [[Interface\Buttons\Arrow-Down-Down]],
arrow_down_texture_coords = {0, 1, 0, 11/16},
arrow_down_size = {12, 11},
arrow_alpha = 0.659,
use_line_separators = false,
line_separator_color = {.1, .1, .1, .6},
line_separator_width = 1,
line_separator_height = 200,
line_separator_gap_align = false,
}
---create a header frame
---@param parent frame
---@param headerTable table
---@param options table|nil
---@param frameName string|nil
---@return df_headerframe
function detailsFramework:CreateHeader(parent, headerTable, options, frameName)
---@type df_headerframe
local newHeader = CreateFrame("frame", frameName or "$parentHeaderLine", parent, "BackdropTemplate")
detailsFramework:Mixin(newHeader, detailsFramework.OptionsFunctions)
detailsFramework:Mixin(newHeader, detailsFramework.HeaderMixin)
newHeader:BuildOptionsTable(default_header_options, options)
newHeader:SetBackdrop(newHeader.options.backdrop)
newHeader:SetBackdropColor(unpack(newHeader.options.backdrop_color))
newHeader:SetBackdropBorderColor(unpack(newHeader.options.backdrop_border_color))
newHeader:SetHeaderTable(headerTable)
return newHeader
end
+2
View File
@@ -4,6 +4,8 @@
<Script file="fw.lua"/>
<Script file="mixins.lua"/>
<Script file="util.lua"/>
<Script file="header.lua"/>
<Script file="containers.lua"/>
<Script file="iteminfo.lua"/>
<Script file="addon.lua"/>
<Script file="colors.lua"/>
+50
View File
@@ -121,6 +121,56 @@ function DF:Round(num, numDecimalPlaces)
return math.floor(num * mult + 0.5) / mult
end
local BoundingBox = {}
BoundingBox.CoordinatesData = {
["topleft"] = {["x"] = 'number', ["y"] = 'number'},
["topright"] = {["x"] = 'number', ["y"] = 'number'},
["bottomleft"] = {["x"] = 'number', ["y"] = 'number'},
["bottomright"] = {["x"] = 'number', ["y"] = 'number'},
["center"] = {["x"] = 'number', ["y"] = 'number'},
["width"] = 'number',
["height"] = 'number',
}
---@class objectcoordinates
---@field topleft {["x"]: number, ["y"]: number}
---@field topright {["x"]: number, ["y"]: number}
---@field bottomleft {["x"]: number, ["y"]: number}
---@field bottomright {["x"]: number, ["y"]: number}
---@field center {["x"]: number, ["y"]: number}
---@field width number
---@field height number
---@field left number
---@field right number
---@field top number
---@field bottom number
---return the coordinates of the four corners of an object
---@param object uiobject
---@return objectcoordinates
function DF:GetObjectCoordinates(object)
local centerX, centerY = object:GetCenter()
local width = object:GetWidth()
local height = object:GetHeight()
local halfWidth = width / 2
local halfHeight = height / 2
return {
["width"] = width,
["height"] = height,
["left"] = centerX - halfWidth,
["right"] = centerX + halfWidth,
["top"] = centerY + halfHeight,
["bottom"] = centerY - halfHeight,
["center"] = {x = centerX, y = centerY},
["topleft"] = {x = centerX - halfWidth, y = centerY + halfHeight},
["topright"] = {x = centerX + halfWidth, y = centerY + halfHeight},
["bottomleft"] = {x = centerX - halfWidth, y = centerY - halfHeight},
["bottomright"] = {x = centerX + halfWidth, y = centerY - halfHeight},
}
end
function DF:ScaleBack()
end
+9 -3
View File
@@ -267,7 +267,8 @@ detailsFramework.SetPointMixin = {
end,
}
--mixin for options functions
---mixin for options
---@class df_optionsmixin
detailsFramework.OptionsFunctions = {
SetOption = function(self, optionName, optionValue)
if (self.options) then
@@ -417,7 +418,7 @@ detailsFramework.ScriptHookMixin = {
---mixin to use with DetailsFramework:Mixin(table, detailsFramework.SortFunctions)
---add methods to be used on scrollframes
---@class DetailsFramework.ScrollBoxFunctions
---@class df_scrollboxmixin
detailsFramework.ScrollBoxFunctions = {
---refresh the scrollbox by resetting all lines created with :CreateLine(), then calling the refresh_func which was set at :CreateScrollBox()
---@param self table
@@ -426,7 +427,9 @@ detailsFramework.ScrollBoxFunctions = {
--hide all frames and tag as not in use
self._LinesInUse = 0
for index, frame in ipairs(self.Frames) do
frame:Hide()
if (not self.DontHideChildrenOnPreRefresh) then
frame:Hide()
end
frame._InUse = nil
end
@@ -684,6 +687,9 @@ detailsFramework.ScrollBoxFunctions = {
end,
}
--back compatibility, can be removed in the future (28/04/2023)
---@class DetailsFramework.ScrollBoxFunctions : df_scrollboxmixin
local SortMember = ""
local SortByMember = function(t1, t2)
return t1[SortMember] > t2[SortMember]
+41 -431
View File
@@ -3889,6 +3889,7 @@ function detailsFramework:CreateScrollBox(parent, name, refreshFunc, data, width
scroll.Frames = {}
scroll.ReajustNumFrames = autoAmount
scroll.CreateLineFunc = createLineFunc
scroll.DontHideChildrenOnPreRefresh = false
detailsFramework:Mixin(scroll, detailsFramework.SortFunctions)
detailsFramework:Mixin(scroll, detailsFramework.ScrollBoxFunctions)
@@ -3906,31 +3907,53 @@ end
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- ~resizers
function detailsFramework:CreateResizeGrips (parent)
if (parent) then
local parentName = parent:GetName()
--these options are copied to the object with object:BuildOptionsTable()
local rezieGripOptions = {
width = 32,
height = 32,
should_mirror_left_texture = true,
normal_texture = [[Interface\CHATFRAME\UI-ChatIM-SizeGrabber-Up]],
highlight_texture = [[Interface\CHATFRAME\UI-ChatIM-SizeGrabber-Highlight]],
pushed_texture = [[Interface\CHATFRAME\UI-ChatIM-SizeGrabber-Down]],
}
local leftResizer = CreateFrame("button", parentName and parentName .. "LeftResizer" or nil, parent, "BackdropTemplate")
local rightResizer = CreateFrame("button", parentName and parentName .. "RightResizer" or nil, parent, "BackdropTemplate")
---create the two resize grips for a frame, one in the bottom left and another in the bottom right
---@param parent frame
---@param options table|nil
---@param leftResizerName string|nil
---@param rightResizerName string|nil
---@return frame, frame
function detailsFramework:CreateResizeGrips(parent, options, leftResizerName, rightResizerName)
local parentName = parent:GetName()
leftResizer:SetPoint("bottomleft", parent, "bottomleft")
rightResizer:SetPoint("bottomright", parent, "bottomright")
leftResizer:SetSize(16, 16)
rightResizer:SetSize(16, 16)
local leftResizer = _G.CreateFrame("button", leftResizerName or (parentName and "$parentLeftResizer"), parent, "BackdropTemplate")
local rightResizer = _G.CreateFrame("button", rightResizerName or (parentName and "$parentRightResizer"), parent, "BackdropTemplate")
rightResizer:SetNormalTexture([[Interface\CHATFRAME\UI-ChatIM-SizeGrabber-Up]])
rightResizer:SetHighlightTexture([[Interface\CHATFRAME\UI-ChatIM-SizeGrabber-Highlight]])
rightResizer:SetPushedTexture([[Interface\CHATFRAME\UI-ChatIM-SizeGrabber-Down]])
leftResizer:SetNormalTexture([[Interface\CHATFRAME\UI-ChatIM-SizeGrabber-Up]])
leftResizer:SetHighlightTexture([[Interface\CHATFRAME\UI-ChatIM-SizeGrabber-Highlight]])
leftResizer:SetPushedTexture([[Interface\CHATFRAME\UI-ChatIM-SizeGrabber-Down]])
detailsFramework:Mixin(leftResizer, detailsFramework.OptionsFunctions)
detailsFramework:Mixin(rightResizer, detailsFramework.OptionsFunctions)
leftResizer:BuildOptionsTable(rezieGripOptions, options)
rightResizer:BuildOptionsTable(rezieGripOptions, options)
leftResizer:SetPoint("bottomleft", parent, "bottomleft", 0, 0)
rightResizer:SetPoint("bottomright", parent, "bottomright", 0, 0)
leftResizer:SetSize(leftResizer.options.width, leftResizer.options.height)
rightResizer:SetSize(leftResizer.options.width, leftResizer.options.height)
rightResizer:SetNormalTexture(rightResizer.options.normal_texture)
rightResizer:SetHighlightTexture(rightResizer.options.highlight_texture)
rightResizer:SetPushedTexture(rightResizer.options.pushed_texture)
leftResizer:SetNormalTexture(leftResizer.options.normal_texture)
leftResizer:SetHighlightTexture(leftResizer.options.highlight_texture)
leftResizer:SetPushedTexture(leftResizer.options.pushed_texture)
if (leftResizer.options.should_mirror_left_texture) then
leftResizer:GetNormalTexture():SetTexCoord(1, 0, 0, 1)
leftResizer:GetHighlightTexture():SetTexCoord(1, 0, 0, 1)
leftResizer:GetPushedTexture():SetTexCoord(1, 0, 0, 1)
return leftResizer, rightResizer
end
return leftResizer, rightResizer
end
@@ -5054,7 +5077,7 @@ local default_icon_row_options = {
}
function detailsFramework:CreateIconRow (parent, name, options)
local f = CreateFrame("frame", name, parent, "BackdropTemplate")
local f = _G.CreateFrame("frame", name, parent, "BackdropTemplate")
f.IconPool = {}
f.NextIcon = 1
f.AuraCache = {}
@@ -5073,419 +5096,6 @@ function detailsFramework:CreateIconRow (parent, name, options)
return f
end
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--~header
--mixed functions
detailsFramework.HeaderFunctions = {
AddFrameToHeaderAlignment = function(self, frame)
self.FramesToAlign = self.FramesToAlign or {}
tinsert(self.FramesToAlign, frame)
end,
GetFramesFromHeaderAlignment = function(self, frame)
return self.FramesToAlign or {}
end,
--@self: an object like a line
--@headerFrame: the main header frame
--@anchor: which side the columnHeaders are attach
AlignWithHeader = function(self, headerFrame, anchor)
local columnHeaderFrames = headerFrame.columnHeadersCreated
anchor = anchor or "topleft"
for i = 1, #self.FramesToAlign do
local frame = self.FramesToAlign[i]
frame:ClearAllPoints()
local columnHeader = columnHeaderFrames[i]
local offset = 0
if (columnHeader.columnAlign == "right") then
offset = columnHeader:GetWidth()
if (frame:GetObjectType() == "FontString") then
frame:SetJustifyH("right")
end
end
frame:SetPoint(columnHeader.columnAlign, self, anchor, columnHeader.XPosition + columnHeader.columnOffset + offset, 0)
end
end,
--@self: column header button
OnClick = function(self, buttonClicked)
--get the header main frame
local headerFrame = self:GetParent()
--if this header does not have a clickable header, just ignore
if (not headerFrame.columnSelected) then
return
end
--get the latest column header selected
local previousColumnHeader = headerFrame.columnHeadersCreated[headerFrame.columnSelected]
previousColumnHeader.Arrow:Hide()
headerFrame:ResetColumnHeaderBackdrop(previousColumnHeader)
headerFrame:SetBackdropColorForSelectedColumnHeader(self)
if (headerFrame.columnSelected == self.columnIndex) then
self.order = self.order ~= "ASC" and "ASC" or "DESC"
end
headerFrame.columnOrder = self.order
--set the new column header selected
headerFrame.columnSelected = self.columnIndex
headerFrame:UpdateSortArrow(self)
if (headerFrame.options.header_click_callback) then
--callback with the main header frame, column header, column index and column order as payload
local okay, errortext = pcall(headerFrame.options.header_click_callback, headerFrame, self, self.columnIndex, self.order)
if (not okay) then
print("DF: Header onClick callback error:", errortext)
end
end
end,
}
detailsFramework.HeaderCoreFunctions = {
GetColumnWidth = function(self, columnId)
return self.HeaderTable[columnId].width
end,
SetHeaderTable = function(self, newTable)
self.columnHeadersCreated = self.columnHeadersCreated or {}
self.HeaderTable = newTable
self.NextHeader = 1
self.HeaderWidth = 0
self.HeaderHeight = 0
self:Refresh()
end,
--return which header is current selected and the the order ASC DESC
GetSelectedColumn = function(self)
return self.columnSelected, self.columnHeadersCreated[self.columnSelected or 1].order
end,
--clean up and rebuild the header following the header options
--@self: main header frame
Refresh = function(self)
--refresh background frame
self:SetBackdrop(self.options.backdrop)
self:SetBackdropColor(unpack(self.options.backdrop_color))
self:SetBackdropBorderColor(unpack(self.options.backdrop_border_color))
--reset all header frames
for i = 1, #self.columnHeadersCreated do
local columnHeader = self.columnHeadersCreated[i]
columnHeader.InUse = false
columnHeader:Hide()
end
local previousColumnHeader
local growDirection = string.lower(self.options.grow_direction)
--update header frames
local headerSize = #self.HeaderTable
for i = 1, headerSize do
--get the header button, a new one is created if it doesn't exists yet
local columnHeader = self:GetNextHeader()
self:UpdateColumnHeader(columnHeader, i)
--grow direction
if (not previousColumnHeader) then
columnHeader:SetPoint("topleft", self, "topleft", 0, 0)
if (growDirection == "right") then
if (self.options.use_line_separators) then
columnHeader.Separator:Show()
columnHeader.Separator:SetWidth(self.options.line_separator_width)
columnHeader.Separator:SetColorTexture(unpack(self.options.line_separator_color))
columnHeader.Separator:ClearAllPoints()
if (self.options.line_separator_gap_align) then
columnHeader.Separator:SetPoint("topleft", columnHeader, "topright", 0, 0)
else
columnHeader.Separator:SetPoint("topright", columnHeader, "topright", 0, 0)
end
columnHeader.Separator:SetHeight(self.options.line_separator_height)
end
end
else
if (growDirection == "right") then
columnHeader:SetPoint("topleft", previousColumnHeader, "topright", self.options.padding, 0)
if (self.options.use_line_separators) then
columnHeader.Separator:Show()
columnHeader.Separator:SetWidth(self.options.line_separator_width)
columnHeader.Separator:SetColorTexture(unpack(self.options.line_separator_color))
columnHeader.Separator:ClearAllPoints()
if (self.options.line_separator_gap_align) then
columnHeader.Separator:SetPoint("topleft", columnHeader, "topright", 0, 0)
else
columnHeader.Separator:SetPoint("topleft", columnHeader, "topright", 0, 0)
end
columnHeader.Separator:SetHeight(self.options.line_separator_height)
if (headerSize == i) then
columnHeader.Separator:Hide()
end
end
elseif (growDirection == "left") then
columnHeader:SetPoint("topright", previousColumnHeader, "topleft", -self.options.padding, 0)
elseif (growDirection == "bottom") then
columnHeader:SetPoint("topleft", previousColumnHeader, "bottomleft", 0, -self.options.padding)
elseif (growDirection == "top") then
columnHeader:SetPoint("bottomleft", previousColumnHeader, "topleft", 0, self.options.padding)
end
end
previousColumnHeader = columnHeader
end
self:SetSize(self.HeaderWidth, self.HeaderHeight)
end,
--@self: main header frame
UpdateSortArrow = function(self, columnHeader, defaultShown, defaultOrder)
local options = self.options
local order = defaultOrder or columnHeader.order
local arrowIcon = columnHeader.Arrow
if (type(defaultShown) ~= "boolean") then
arrowIcon:Show()
else
arrowIcon:SetShown(defaultShown)
if (defaultShown) then
self:SetBackdropColorForSelectedColumnHeader(columnHeader)
end
end
arrowIcon:SetAlpha(options.arrow_alpha)
if (order == "ASC") then
arrowIcon:SetTexture(options.arrow_up_texture)
arrowIcon:SetTexCoord(unpack(options.arrow_up_texture_coords))
arrowIcon:SetSize(unpack(options.arrow_up_size))
elseif (order == "DESC") then
arrowIcon:SetTexture(options.arrow_down_texture)
arrowIcon:SetTexCoord(unpack(options.arrow_down_texture_coords))
arrowIcon:SetSize(unpack(options.arrow_down_size))
end
end,
--@self: main header frame
UpdateColumnHeader = function(self, columnHeader, headerIndex)
local headerData = self.HeaderTable[headerIndex]
if (headerData.icon) then
columnHeader.Icon:SetTexture(headerData.icon)
if (headerData.texcoord) then
columnHeader.Icon:SetTexCoord(unpack(headerData.texcoord))
else
columnHeader.Icon:SetTexCoord(0, 1, 0, 1)
end
columnHeader.Icon:SetPoint("left", columnHeader, "left", self.options.padding, 0)
columnHeader.Icon:Show()
end
if (headerData.text) then
columnHeader.Text:SetText(headerData.text)
--text options
detailsFramework:SetFontColor(columnHeader.Text, self.options.text_color)
detailsFramework:SetFontSize(columnHeader.Text, self.options.text_size)
detailsFramework:SetFontOutline(columnHeader.Text, self.options.text_shadow)
--point
if (not headerData.icon) then
columnHeader.Text:SetPoint("left", columnHeader, "left", self.options.padding, 0)
else
columnHeader.Text:SetPoint("left", columnHeader.Icon, "right", self.options.padding, 0)
end
columnHeader.Text:Show()
end
--column header index
columnHeader.columnIndex = headerIndex
if (headerData.canSort) then
columnHeader.order = "DESC"
columnHeader.Arrow:SetTexture(self.options.arrow_up_texture)
else
columnHeader.Arrow:Hide()
end
if (headerData.selected) then
columnHeader.Arrow:Show()
columnHeader.Arrow:SetAlpha(.843)
self:UpdateSortArrow(columnHeader, true, columnHeader.order)
self.columnSelected = headerIndex
else
if (headerData.canSort) then
self:UpdateSortArrow(columnHeader, false, columnHeader.order)
end
end
--size
if (headerData.width) then
columnHeader:SetWidth(headerData.width)
end
if (headerData.height) then
columnHeader:SetHeight(headerData.height)
end
columnHeader.XPosition = self.HeaderWidth -- + self.options.padding
columnHeader.YPosition = self.HeaderHeight -- + self.options.padding
columnHeader.columnAlign = headerData.align or "left"
columnHeader.columnOffset = headerData.offset or 0
--add the header piece size to the total header size
local growDirection = string.lower(self.options.grow_direction)
if (growDirection == "right" or growDirection == "left") then
self.HeaderWidth = self.HeaderWidth + columnHeader:GetWidth() + self.options.padding
self.HeaderHeight = math.max(self.HeaderHeight, columnHeader:GetHeight())
elseif (growDirection == "top" or growDirection == "bottom") then
self.HeaderWidth = math.max(self.HeaderWidth, columnHeader:GetWidth())
self.HeaderHeight = self.HeaderHeight + columnHeader:GetHeight() + self.options.padding
end
columnHeader:Show()
columnHeader.InUse = true
end,
--reset column header backdrop
--@self: main header frame
ResetColumnHeaderBackdrop = function(self, columnHeader)
columnHeader:SetBackdrop(self.options.header_backdrop)
columnHeader:SetBackdropColor(unpack(self.options.header_backdrop_color))
columnHeader:SetBackdropBorderColor(unpack(self.options.header_backdrop_border_color))
end,
--@self: main header frame
SetBackdropColorForSelectedColumnHeader = function(self, columnHeader)
columnHeader:SetBackdropColor(unpack(self.options.header_backdrop_color_selected))
end,
--clear the column header
--@self: main header frame
ClearColumnHeader = function(self, columnHeader)
columnHeader:SetSize(self.options.header_width, self.options.header_height)
self:ResetColumnHeaderBackdrop(columnHeader)
columnHeader:ClearAllPoints()
columnHeader.Icon:SetTexture("")
columnHeader.Icon:Hide()
columnHeader.Text:SetText("")
columnHeader.Text:Hide()
end,
--get the next column header, create one if doesn't exists
--@self: main header frame
GetNextHeader = function(self)
local nextHeader = self.NextHeader
local columnHeader = self.columnHeadersCreated[nextHeader]
if (not columnHeader) then
--create a new column header
local newHeader = CreateFrame("button", "$parentHeaderIndex" .. nextHeader, self, "BackdropTemplate")
newHeader:SetScript("OnClick", detailsFramework.HeaderFunctions.OnClick)
--header icon
detailsFramework:CreateImage(newHeader, "", self.options.header_height, self.options.header_height, "ARTWORK", nil, "Icon", "$parentIcon")
--header separator
detailsFramework:CreateImage(newHeader, "", 1, 1, "ARTWORK", nil, "Separator", "$parentSeparator")
--header name text
detailsFramework:CreateLabel(newHeader, "", self.options.text_size, self.options.text_color, "GameFontNormal", "Text", "$parentText", "ARTWORK")
--header selected and order icon
detailsFramework:CreateImage(newHeader, self.options.arrow_up_texture, 12, 12, "ARTWORK", nil, "Arrow", "$parentArrow")
newHeader.Arrow:SetPoint("right", newHeader, "right", -1, 0)
newHeader.Separator:Hide()
newHeader.Arrow:Hide()
self:UpdateSortArrow(newHeader, false, "DESC")
tinsert(self.columnHeadersCreated, newHeader)
columnHeader = newHeader
end
self:ClearColumnHeader(columnHeader)
self.NextHeader = self.NextHeader + 1
return columnHeader
end,
NextHeader = 1,
HeaderWidth = 0,
HeaderHeight = 0,
}
local default_header_options = {
backdrop = {edgeFile = [[Interface\Buttons\WHITE8X8]], edgeSize = 1, bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true},
backdrop_color = {0, 0, 0, 0.2},
backdrop_border_color = {0.1, 0.1, 0.1, .2},
text_color = {1, 1, 1, 1},
text_size = 10,
text_shadow = false,
grow_direction = "RIGHT",
padding = 2,
--each piece of the header
header_backdrop = {bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true},
header_backdrop_color = {0, 0, 0, 0.5},
header_backdrop_color_selected = {0.3, 0.3, 0.3, 0.5},
header_backdrop_border_color = {0, 0, 0, 0},
header_width = 120,
header_height = 20,
arrow_up_texture = [[Interface\Buttons\Arrow-Up-Down]],
arrow_up_texture_coords = {0, 1, 6/16, 1},
arrow_up_size = {12, 11},
arrow_down_texture = [[Interface\Buttons\Arrow-Down-Down]],
arrow_down_texture_coords = {0, 1, 0, 11/16},
arrow_down_size = {12, 11},
arrow_alpha = 0.659,
use_line_separators = false,
line_separator_color = {.1, .1, .1, .6},
line_separator_width = 1,
line_separator_height = 200,
line_separator_gap_align = false,
}
function detailsFramework:CreateHeader(parent, headerTable, options, frameName)
local newHeader = CreateFrame("frame", frameName or "$parentHeaderLine", parent, "BackdropTemplate")
detailsFramework:Mixin(newHeader, detailsFramework.OptionsFunctions)
detailsFramework:Mixin(newHeader, detailsFramework.HeaderCoreFunctions)
newHeader:BuildOptionsTable(default_header_options, options)
newHeader:SetBackdrop(newHeader.options.backdrop)
newHeader:SetBackdropColor(unpack(newHeader.options.backdrop_color))
newHeader:SetBackdropBorderColor(unpack(newHeader.options.backdrop_border_color))
newHeader:SetHeaderTable(headerTable)
return newHeader
end
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--radio group
+4 -2
View File
@@ -37,7 +37,7 @@ if (WOW_PROJECT_ID ~= WOW_PROJECT_MAINLINE and not isExpansion_Dragonflight()) t
end
local major = "LibOpenRaid-1.0"
local CONST_LIB_VERSION = 98
local CONST_LIB_VERSION = 99
if (not LIB_OPEN_RAID_MAX_VERSION) then
LIB_OPEN_RAID_MAX_VERSION = CONST_LIB_VERSION
@@ -1688,7 +1688,9 @@ openRaidLib.internalCallback.RegisterCallback("onLeaveCombat", openRaidLib.UnitI
dataToSend = dataToSend .. playerGearInfo[3] .. "," --weapon enchant
dataToSend = dataToSend .. openRaidLib.PackTable(playerGearInfo[4]) .. "," --slots without enchant
dataToSend = dataToSend .. openRaidLib.PackTable(playerGearInfo[5]) .. "," -- slots with empty gem sockets
dataToSend = dataToSend .. openRaidLib.PackTableAndSubTables(playerGearInfo[6]) --full equipped equipment
dataToSend = dataToSend .. openRaidLib.PackTableAndSubTables(playerGearInfo[6]) .. "," --full equipped equipment
dataToSend = dataToSend .. playerGearInfo[7] .. "," --main hand weapon enchant
dataToSend = dataToSend .. playerGearInfo[8] --off hand weapon enchant
--send the data
openRaidLib.commHandler.SendCommData(dataToSend)
@@ -154,9 +154,33 @@ do
--/dump GetWeaponEnchantInfo()
LIB_OPEN_RAID_WEAPON_ENCHANT_IDS = {
--need update to dragonflight
[5400] = true, --flametongue
[5401] = true, --windfury
[5401] = {spell=33757}, -- Windfury
[5400] = {spell=318038}, -- Flametongue
[6498] = {spell=382021}, -- Earthliving
-- Runes, whetstones, weightstones
[6512] = {tier = 1, item=194823},
[6513] = {tier = 2, item=194823},
[6514] = {tier = 3, item=194823},
[6515] = {tier = 1, item=194826},
[6694] = {tier = 2, item=194826},
[6695] = {tier = 3, item=194826},
[6516] = {tier = 1, item=194820},
[6517] = {tier = 2, item=194820},
[6518] = {tier = 3, item=194820},
[6529] = {tier = 1, item=198162},
[6530] = {tier = 2, item=198162},
[6531] = {tier = 3, item=198162},
[6379] = {tier = 1, item=191940},
[6380] = {tier = 2, item=191940},
[6381] = {tier = 3, item=191940},
[6696] = {tier = 1, item=191945},
[6697] = {tier = 2, item=191945},
[6698] = {tier = 3, item=191945},
}
--buff spellId, the value of the food is the tier level
+5 -2
View File
@@ -2,6 +2,7 @@
--global name declaration
--local _StartDebugTime = debugprofilestop() print(debugprofilestop() - _StartDebugTime)
--test if the packager will deploy to wago
--https://github.com/LuaLS/lua-language-server/wiki/Annotations#documenting-types
--make an option to show death in the order of newest to oldest
@@ -15,7 +16,7 @@
_detalhes.dont_open_news = true
_detalhes.game_version = version
_detalhes.userversion = version .. " " .. _detalhes.build_counter
_detalhes.realversion = 148 --core version, this is used to check API version for scripts and plugins (see alias below)
_detalhes.realversion = 149 --core version, this is used to check API version for scripts and plugins (see alias below)
_detalhes.APIVersion = _detalhes.realversion --core version
_detalhes.version = _detalhes.userversion .. " (core " .. _detalhes.realversion .. ")" --simple stirng to show to players
@@ -87,6 +88,7 @@
Details222.Perf = {}
Details222.Cooldowns = {}
Details222.GarbageCollector = {}
Details222.BreakdownWindow = {}
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--initialization stuff
@@ -777,8 +779,9 @@ do
local UIParent = UIParent --api locals
--Info Window
_detalhes.playerDetailWindow = CreateFrame("Frame", "DetailsPlayerDetailsWindow", UIParent, "BackdropTemplate")
_detalhes.playerDetailWindow = CreateFrame("Frame", "DetailsBreakdownWindow", UIParent, "BackdropTemplate")
_detalhes.PlayerDetailsWindow = _detalhes.playerDetailWindow
Details.BreakdownWindow = _detalhes.playerDetailWindow
--Event Frame
_detalhes.listener = CreateFrame("Frame", nil, UIParent)
+69
View File
@@ -180,6 +180,75 @@
return self.alternate_power
end
---return the amount of casts of a spells from an actor
---@param actorName string
---@param spellId number
---@return number
function combate:GetSpellCastAmount(actorName, spellId)
---@type actorcontainer
local utilityContainer = self:GetContainer(DETAILS_ATTRIBUTE_MISC)
---@type actor
local actorObject = utilityContainer:GetActor(actorName)
if (actorObject) then
if (actorObject.spell_cast) then
return actorObject.spell_cast[spellId] or 0
else
return 0
end
else
return 0
end
end
---return the uptime of a buff from an actor
---@param actorName string
---@param spellId number
---@param auraType string|nil if nil get 'buff'
---@return number
function combate:GetSpellUptime(actorName, spellId, auraType)
---@type actorcontainer
local utilityContainer = self:GetContainer(DETAILS_ATTRIBUTE_MISC)
---@type actor
local actorObject = utilityContainer:GetActor(actorName)
if (actorObject) then
if (auraType) then
---@type spellcontainer
local buffUptimeContainer = actorObject:GetSpellContainer(auraType)
if (buffUptimeContainer) then
---@type spelltable
local spellTable = buffUptimeContainer:GetSpell(spellId)
if (spellTable) then
return spellTable.uptime or 0
end
end
else
do --if not auraType passed, attempt to get the uptime from debuffs first, if it fails, get from buffs
---@type spellcontainer
local debuffContainer = actorObject:GetSpellContainer("debuff")
if (debuffContainer) then
---@type spelltable
local spellTable = debuffContainer:GetSpell(spellId)
if (spellTable) then
return spellTable.uptime or 0
end
end
end
do
---@type spellcontainer
local buffContainer = actorObject:GetSpellContainer("buff")
if (buffContainer) then
---@type spelltable
local spellTable = buffContainer:GetSpell(spellId)
if (spellTable) then
return spellTable.uptime or 0
end
end
end
end
end
return 0
end
--return the name of the encounter or enemy
function combate:GetCombatName(try_find)
if (self.is_pvp) then
+15 -15
View File
@@ -1748,7 +1748,7 @@
desc = Loc ["STRING_CUSTOM_MYSPELLS_DESC"],
source = false,
target = false,
script_version = 8,
script_version = 9,
script = [[
--get the parameters passed
local combat, instance_container, instance = ...
@@ -1820,7 +1820,7 @@
local role = DetailsFramework.UnitGroupRolesAssigned("player")
if (spell.n_dmg) then
if (spell.n_total) then
local spellschool, schooltext = spell.spellschool, ""
if (spellschool) then
@@ -1885,12 +1885,12 @@
GC:AddLine("Normal Hits: ", spell.n_amt .. " (" ..floor( spell.n_amt/total_hits*100) .. "%)")
GC:AddStatusBar (100, 1, R, G, B, A)
local n_average = spell.n_dmg / spell.n_amt
local T = (combat_time*spell.n_dmg)/spell.total
local n_average = spell.n_total / spell.n_amt
local T = (combat_time*spell.n_total)/spell.total
local P = average/n_average*100
T = P*T/100
GC:AddLine("Average / E-Dps: ", _detalhes:ToK (n_average) .. " / " .. format("%.1f",spell.n_dmg / T ))
GC:AddLine("Average / E-Dps: ", _detalhes:ToK (n_average) .. " / " .. format("%.1f",spell.n_total / T ))
GC:AddStatusBar (100, 1, R, G, B, A)
--GC:AddLine(" ")
@@ -1899,11 +1899,11 @@
GC:AddStatusBar (100, 1, R, G, B, A)
if (spell.c_amt > 0) then
local c_average = spell.c_dmg/spell.c_amt
local T = (combat_time*spell.c_dmg)/spell.total
local c_average = spell.c_total/spell.c_amt
local T = (combat_time*spell.c_total)/spell.total
local P = average/c_average*100
T = P*T/100
local crit_dps = spell.c_dmg / T
local crit_dps = spell.c_total / T
GC:AddLine("Average / E-Dps: ", _detalhes:ToK (c_average) .. " / " .. _detalhes:comma_value (crit_dps))
else
@@ -1913,7 +1913,7 @@
GC:AddStatusBar (100, 1, R, G, B, A)
elseif (spell.n_curado) then
elseif (spell.n_total) then
local spellschool, schooltext = spell.spellschool, ""
if (spellschool) then
@@ -1945,12 +1945,12 @@
GC:AddLine("Normal Hits: ", spell.n_amt .. " (" ..floor( spell.n_amt/total_hits*100) .. "%)")
GC:AddStatusBar (100, 1, R, G, B, A)
local n_average = spell.n_curado / spell.n_amt
local T = (combat_time*spell.n_curado)/spell.total
local n_average = spell.n_total / spell.n_amt
local T = (combat_time*spell.n_total)/spell.total
local P = average/n_average*100
T = P*T/100
GC:AddLine("Average / E-Dps: ", _detalhes:ToK (n_average) .. " / " .. format("%.1f",spell.n_curado / T ))
GC:AddLine("Average / E-Dps: ", _detalhes:ToK (n_average) .. " / " .. format("%.1f",spell.n_total / T ))
GC:AddStatusBar (100, 1, R, G, B, A)
--GC:AddLine(" ")
@@ -1959,11 +1959,11 @@
GC:AddStatusBar (100, 1, R, G, B, A)
if (spell.c_amt > 0) then
local c_average = spell.c_curado/spell.c_amt
local T = (combat_time*spell.c_curado)/spell.total
local c_average = spell.c_total/spell.c_amt
local T = (combat_time*spell.c_total)/spell.total
local P = average/c_average*100
T = P*T/100
local crit_dps = spell.c_curado / T
local crit_dps = spell.c_total / T
GC:AddLine("Average / E-Hps: ", _detalhes:ToK (c_average) .. " / " .. _detalhes:comma_value (crit_dps))
else
+350 -225
View File
@@ -102,6 +102,41 @@
[73967] = true, --xuen
}
--damage mixin
local damageClassMixin = {
---check which data is shown in the instance and call a function to build the data for a broker
---@param actor actor
---@param instance instance
BuildSpellDetails = function(actor, instance, spellId)
local mainSection, subSection = instance:GetDisplay()
local combatObject = instance:GetCombat()
if (subSection == 1 or subSection == 2) then
return actor:BuildSpellDamageDoneDetails(instance, combatObject, spellId)
elseif (subSection == 3) then
return self:MontaDetalhesDamageTaken (spellid, barra, instancia)
elseif (subSection == 4) then
return self:MontaDetalhesFriendlyFire (spellid, barra, instancia)
elseif (subSection == 6) then
if (bitBand(self.flag_original, 0x00000400) ~= 0) then -- um jogador
return self:MontaDetalhesDamageDone (spellid, barra, instancia)
end
return self:MontaDetalhesEnemy (spellid, barra, instancia)
end
end,
}
---prepare data to send to a broker to show details about a spell
---@param actor actor
---@param combat combat
---@param spellId number
damageClassMixin.BuildSpellDamageDoneDetails = function(actor, combat, spellId)
end
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--exported functions
@@ -492,6 +527,7 @@ end
setmetatable(newDamageActor, atributo_damage)
detailsFramework:Mixin(newDamageActor, Details222.Mixins.ActorMixin)
detailsFramework:Mixin(newDamageActor, damageClassMixin)
return newDamageActor
end
@@ -3090,7 +3126,11 @@ end
end
end
--@self: actor object
---set the icon of the actor spec, class, pet, enemy, custom icom, spellicon, etc.
---@param self actor
---@param texture texture
---@param instance instance
---@param class string
function Details:SetClassIcon(texture, instance, class) --[[ exported]]
local customIcon
if (Details.immersion_unit_special_icons) then
@@ -4431,135 +4471,214 @@ local getSpellDetails = function(unitGUID, spellName)
end
end
--[=[
current: passando todas as spells para o breakdown, até mesmo as spells que não tem merge é enviado a spell total e a a spellTable logo em seguida
isso forma uma array com o dobro do tamanho e spells duplicadas
passar as spells repetidas em uma segunda array?
não passar nada e deixar o sistema aprender sozinho, como o sistema vai saber que precisa por uma arrow na linha? (para expandi-la)
--]=]
------ Damage Done & Dps
function atributo_damage:MontaInfoDamageDone()
function atributo_damage:MontaInfoDamageDone() --I guess this fills the list of spells in the topleft scrollBar in the summary tab
--the goal of this function is to build a list of spells the actor used and send the data to Details! which will delivery to the summary tab actived
--so the script only need to build the list of spells and send it to Details!
---@type actor
local actorObject = self
local allLines = info.barras1
---@type instance
local instance = info.instancia
--damage rank
local combatObject = instance:GetShowingCombat()
---@type combat
local combatObject = instance:GetCombat()
---@type number
local diff = combatObject:GetDifficulty()
---@type string
local playerName = actorObject:Name()
local attribute, subAttribute = instance:GetDisplay()
--guild ranking on a boss
--check if is a raid encounter and if is heroic or mythic
if (diff and (diff == 15 or diff == 16)) then
local db = Details.OpenStorage()
if (db) then
local bestRank, encounterTable = Details.storage:GetBestFromPlayer (diff, combatObject:GetBossInfo().id, "damage", self.nome, true)
if (bestRank) then
--discover which are the player position in the guild rank
local playerTable, onEncounter, rankPosition = Details.storage:GetPlayerGuildRank (diff, combatObject:GetBossInfo().id, "damage", self.nome, true)
local text1 = self.nome .. " Guild Rank on " .. (combatObject:GetBossInfo().name or "") .. ": |cFFFFFF00" .. (rankPosition or "x") .. "|r Best Dps: |cFFFFFF00" .. Details:ToK2((bestRank[1] or 0) / encounterTable.elapsed) .. "|r (" .. encounterTable.date:gsub(".*%s", "") .. ")"
info:SetStatusbarText (text1, 10, "gray")
do
if (diff and (diff == 15 or diff == 16)) then
local db = Details.OpenStorage()
if (db) then
local bestRank, encounterTable = Details.storage:GetBestFromPlayer(diff, combatObject:GetBossInfo().id, "damage", playerName, true)
if (bestRank) then
--discover which are the player position in the guild rank
local playerTable, onEncounter, rankPosition = Details.storage:GetPlayerGuildRank (diff, combatObject:GetBossInfo().id, "damage", playerName, true)
local text1 = playerName .. " Guild Rank on " .. (combatObject:GetBossInfo().name or "") .. ": |cFFFFFF00" .. (rankPosition or "x") .. "|r Best Dps: |cFFFFFF00" .. Details:ToK2((bestRank[1] or 0) / encounterTable.elapsed) .. "|r (" .. encounterTable.date:gsub(".*%s", "") .. ")"
info:SetStatusbarText (text1, 10, "gray")
else
info:SetStatusbarText()
end
else
info:SetStatusbarText()
end
else
info:SetStatusbarText()
end
else
info:SetStatusbarText()
end
---@type breakdownspelldatalist
local breakdownSpellDataList = {}
---@type number
local totalDamageWithoutPet = actorObject.total_without_pet
local actorTotalDamage = actorObject.total
local actorSpellsSorted = {}
---@type number
local actorTotal = actorObject.total
---@type table<number, spelltable>
local actorSpells = actorObject:GetSpellList()
local bShouldMergePlayerAbilities = Details.merge_player_abilities
local bShouldMergePetAbilities = Details.merge_pet_abilities
wipeSpellCache()
--get time type
--get time
local actorCombatTime
if (Details.time_type == 1 or not self.grupo) then
actorCombatTime = self:Tempo()
if (Details.time_type == 1 or not actorObject.grupo) then
actorCombatTime = actorObject:Tempo()
elseif (Details.time_type == 2) then
actorCombatTime = info.instancia.showing:GetCombatTime()
end
--actor spells
---@type table<string, number>
local alreadyAdded = {}
---@type number, spelltable
for spellId, spellTable in pairs(actorSpells) do
local spellName, _, spellIcon = _GetSpellInfo(spellId)
spellTable.ChartData = nil
---@type string
local spellName = _GetSpellInfo(spellId)
if (spellName) then
local spellTotal = spellTable.total
local spellPercent = spellTable.total / actorTotalDamage * 100
local nameString = spellName
--problem: will show the first ability found when hovering over the spell
if (bShouldMergePlayerAbilities) then
local bAlreadyAdded = false
for i = 1, #actorSpellsSorted do
local thisSpell = actorSpellsSorted[i]
if (thisSpell[4] == nameString) then
bAlreadyAdded = true
thisSpell[2] = thisSpell[2] + spellTotal
end
end
if (not bAlreadyAdded) then
tinsert(actorSpellsSorted, {spellId, spellTotal, spellPercent, nameString, spellIcon, nil, spellTable.spellschool})
end
addToSpellCache(actorObject:GetGUID(), spellName, spellTable)
---@type number in which index the spell with the same name was stored
local index = alreadyAdded[spellName]
if (index) then
---@type spelltableadv
local bkSpellData = breakdownSpellDataList[index]
bkSpellData.spellIds[#bkSpellData.spellIds+1] = spellId
bkSpellData.spellTables[#bkSpellData.spellTables+1] = spellTable
bkSpellData.petNames[#bkSpellData.petNames+1] = ""
bkSpellData.bCanExpand = true
else
tinsert(actorSpellsSorted, {spellId, spellTotal, spellPercent, nameString, spellIcon, nil, spellTable.spellschool})
---@type spelltableadv
local bkSpellData = {
id = spellId,
spellschool = spellTable.spellschool,
bIsExpanded = Details222.BreakdownWindow.IsSpellExpanded(spellId),
bCanExpand = false,
spellIds = {spellId},
spellTables = {spellTable}, --sub spell tables to show if the spell is expanded
petNames = {""},
}
detailsFramework:Mixin(bkSpellData, Details.SpellTableMixin)
breakdownSpellDataList[#breakdownSpellDataList+1] = bkSpellData
alreadyAdded[spellName] = #breakdownSpellDataList
end
end
end
--show damage percentille within item level bracket
--add pets
local actorPets = self.pets
--local class_color = RAID_CLASS_COLORS [self.classe] and RAID_CLASS_COLORS [self.classe].colorStr
local classColor = "FFCCBBBB"
--local class_color = "FFDDDD44"
--pets spells
local actorPets = actorObject:GetPets()
for _, petName in ipairs(actorPets) do
---@type actor
local petActor = combatObject(DETAILS_ATTRIBUTE_DAMAGE, petName)
if (petActor) then
if (petActor) then --PET
local spells = petActor:GetSpellList()
for spellId, spellTable in pairs(spells) do --da foreach em cada spellid do container
local spellName, _, spellIcon = _GetSpellInfo(spellId)
--tinsert(ActorSkillsSortTable, {_spellid, _skill.total, _skill.total/ActorTotalDamage*100, nome .. " |TInterface\\AddOns\\Details\\images\\classes_small_alpha:12:12:0:0:128:128:33:64:96:128|t|c" .. class_color .. PetName:gsub((" <.*"), "") .. "|r", icone, PetActor, _skill.spellschool})
for spellId, spellTable in pairs(spells) do
---@cast spellId number
---@cast spellTable spelltable
spellTable.ChartData = nil
--PET
---@type string
local spellName = _GetSpellInfo(spellId)
if (spellName) then
local spellTotal = spellTable.total
local spellPercent = spellTable.total / actorTotalDamage * 100
local nameString = spellName .. " (|c" .. classColor .. petName:gsub((" <.*"), "") .. "|r)"
---@type number in which index the spell with the same name was stored
local index = alreadyAdded[spellName]
if (index) then --PET
---@type spelltableadv
local bkSpellData = breakdownSpellDataList[index]
bkSpellData.spellIds[#bkSpellData.spellIds+1] = spellId
bkSpellData.spellTables[#bkSpellData.spellTables+1] = spellTable
bkSpellData.petNames[#bkSpellData.petNames+1] = petName
bkSpellData.bCanExpand = true
else --PET
---@type spelltableadv
local bkSpellData = {
id = spellId,
spellschool = spellTable.spellschool,
expanded = Details222.BreakdownWindow.IsSpellExpanded(spellId),
bCanExpand = false,
if (bShouldMergePetAbilities) then
local bAlreadyAdded = false
for i = 1, #actorSpellsSorted do
local thisPetSpellTable = actorSpellsSorted[i]
if (thisPetSpellTable[1] == spellId) then
bAlreadyAdded = true
thisPetSpellTable[2] = thisPetSpellTable[2] + spellTotal
end
end
spellIds = {spellId},
spellTables = {spellTable},
petNames = {petName},
}
detailsFramework:Mixin(bkSpellData, Details.SpellTableMixin)
if (not bAlreadyAdded) then
tinsert(actorSpellsSorted, {spellId, spellTotal, spellPercent, nameString, spellIcon, petActor, spellTable.spellschool})
end
addToSpellCache(actorObject:GetGUID(), spellName, spellTable) --all pet spells are added to later be combined and shown in the spell details
else
tinsert(actorSpellsSorted, {spellId, spellTotal, spellPercent, nameString, spellIcon, petActor, spellTable.spellschool})
breakdownSpellDataList[#breakdownSpellDataList+1] = bkSpellData
alreadyAdded[spellName] = #breakdownSpellDataList
end
end
end
end
end
_table_sort(actorSpellsSorted, Details.Sort2)
--copy the keys from the spelltable and add them to the spelltableadv
--repeated spells will be summed
for i = 1, #breakdownSpellDataList do
---@type spelltableadv
local bkSpellData = breakdownSpellDataList[i]
Details.SpellTableMixin.SumSpellTables(bkSpellData.spellTables, bkSpellData)
end
gump:JI_AtualizaContainerBarras (#actorSpellsSorted + 1)
breakdownSpellDataList.totalValue = actorTotal
breakdownSpellDataList.combatTime = actorCombatTime
local max_ = actorSpellsSorted[1] and actorSpellsSorted[1][2] or 0 --dano que a primeiro magia vez
--cleanup
table.wipe(alreadyAdded)
--send to the breakdown window
Details222.BreakdownWindow.SendSpellData(breakdownSpellDataList, actorObject, combatObject, instance)
--targets
---an array of breakdowntargettable
---@type breakdowntargettablelist
local targetList = {}
local targetTotalValue = 0
local targetsTable = self:GetTargets()
for targetName, amount in pairs(targetsTable) do
---@class breakdowntargettable
local bkTargetData = {
name = targetName,
total = amount,
overheal = 0,
}
targetTotalValue = targetTotalValue + amount
tinsert(targetList, bkTargetData)
end
targetList.totalValue = targetTotalValue
targetList.combatTime = actorCombatTime
Details222.BreakdownWindow.SendTargetData(targetList, actorObject, combatObject, instance)
if 1 then return end
--to be deprecated and removed:
--gump:JI_AtualizaContainerBarras (#actorSpellsSorted + 1)
local max_ = breakdownSpellDataList[1] and breakdownSpellDataList[1][2] or 0 --dano que a primeiro magia vez
local barra
--aura bar
@@ -4573,7 +4692,7 @@ function atributo_damage:MontaInfoDamageDone()
end
--spell bars
for index, tabela in ipairs(actorSpellsSorted) do
for index, tabela in ipairs(breakdownSpellDataList) do
--index = index + 1 --with the aura bar
index = index
@@ -4727,7 +4846,7 @@ function atributo_damage:MontaInfoDamageDone()
if (targetActorObject) then
local npcId = DetailsFramework:GetNpcIdFromGuid(targetActorObject:GetGUID())
local portraitTexture = Details222.Textures.GetPortraitTextureForNpcID(npcId)
local portraitTexture -- = Details222.Textures.GetPortraitTextureForNpcID(npcId) disabled
if (portraitTexture) then
Details222.Textures.FormatPortraitAsTexture(portraitTexture, barra.icone)
else
@@ -4752,12 +4871,9 @@ function atributo_damage:MontaInfoDamageDone()
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, instance)) then
return
end
--GameTooltip:Show()
end
end
@@ -5074,8 +5190,11 @@ local MontaDetalhesBuffProcs = function(actor, row, instance)
end
--this build p the 6 rectangle boxes in the right side of the breakdown window summary tab
function atributo_damage:MontaDetalhesDamageDone (spellId, spellLine, instance) --this should be ~deprecated with the new breakdown tab
print("MontaDetalhesDamageDone - deprecated", debugstack())
function atributo_damage:MontaDetalhesDamageDone (spellId, spellLine, instance)
local spellTable
if (spellLine.other_actor) then
spellTable = spellLine.other_actor.spells._ActorTable [spellId]
@@ -5198,7 +5317,7 @@ function atributo_damage:MontaDetalhesDamageDone (spellId, spellLine, instance)
--NORMAL
local normal_hits = spellTable.n_amt
if (normal_hits > 0) then
local normal_dmg = spellTable.n_dmg
local normal_dmg = spellTable.n_total
local media_normal = normal_dmg/normal_hits
local T = (meu_tempo*normal_dmg)/ max(spellTable.total, 0.001)
local P = media/media_normal*100
@@ -5221,11 +5340,11 @@ function atributo_damage:MontaDetalhesDamageDone (spellId, spellLine, instance)
--CRITICO
if (spellTable.c_amt > 0) then
local media_critico = spellTable.c_dmg/spellTable.c_amt
local T = (meu_tempo*spellTable.c_dmg)/spellTable.total
local media_critico = spellTable.c_total/spellTable.c_amt
local T = (meu_tempo*spellTable.c_total)/spellTable.total
local P = media/max(media_critico, 0.0001)*100
T = P*T/100
local crit_dps = spellTable.c_dmg/T
local crit_dps = spellTable.c_total/T
if (not crit_dps) then
crit_dps = 0
end
@@ -5339,146 +5458,150 @@ function atributo_damage:MontaDetalhesDamageDone (spellId, spellLine, instance)
local spellTable = spellTable
local blockId = 6
local thatRectangle66 = Details222.BreakdownWindow.GetBlockIndex(blockId)
thatRectangle66 = thatRectangle66:GetFrame()
--hide all textures created
if (thatRectangle66.ChartTextures) then
for i = 1, #thatRectangle66.ChartTextures do
thatRectangle66.ChartTextures[i]:Hide()
end
end
if false then --debug the stuff for the chart damage done in the 6th spellblock
--GetBlockIndex doesn't exists anymore
local thatRectangle66 = Details222.BreakdownWindow.GetBlockIndex(blockId)
thatRectangle66 = thatRectangle66:GetFrame()
local chartData = Details222.TimeCapture.GetChartDataFromSpell(spellTable)
if (chartData and instance) then
local width, height = thatRectangle66:GetSize()
--reset which texture is the next to be used
thatRectangle66.nextChartTextureId = 1
local amountOfTimeStamps = 12
if (not thatRectangle66.timeStamps) then
thatRectangle66.timeStamps = {}
for i = 1, amountOfTimeStamps do
thatRectangle66.timeStamps[i] = thatRectangle66:CreateFontString(nil, "overlay", "GameFontNormal")
thatRectangle66.timeStamps[i]:SetPoint("topleft", thatRectangle66, "topleft", 2 + (i - 1) * (width / amountOfTimeStamps), -2)
DetailsFramework:SetFontSize(thatRectangle66.timeStamps[i], 9)
--hide all textures created
if (thatRectangle66.ChartTextures) then
for i = 1, #thatRectangle66.ChartTextures do
thatRectangle66.ChartTextures[i]:Hide()
end
end
if (not thatRectangle66.bloodLustIndicators) then
thatRectangle66.bloodLustIndicators = {}
for i = 1, 5 do
local thisIndicator = thatRectangle66:CreateTexture(nil, "artwork", nil, 4)
thisIndicator:SetColorTexture(0.0980392, 0.0980392, 0.439216)
thatRectangle66.bloodLustIndicators[#thatRectangle66.bloodLustIndicators+1] = thisIndicator
end
end
local chartData = Details222.TimeCapture.GetChartDataFromSpell(spellTable)
if (chartData and instance) then
local width, height = thatRectangle66:GetSize()
--reset which texture is the next to be used
thatRectangle66.nextChartTextureId = 1
for i = 1, #thatRectangle66.bloodLustIndicators do
thatRectangle66.bloodLustIndicators[i]:Hide()
end
local amountOfTimeStamps = 12
if (not thatRectangle66.ChartTextures) then
thatRectangle66.ChartTextures = {}
function thatRectangle66:GetChartTexture()
local thisTexture = thatRectangle66.ChartTextures[thatRectangle66.nextChartTextureId]
if (not thisTexture) then
thisTexture = thatRectangle66:CreateTexture(nil, "artwork", nil, 5)
thisTexture:SetColorTexture(1, 1, 1, 0.65)
thatRectangle66.ChartTextures[thatRectangle66.nextChartTextureId] = thisTexture
if (not thatRectangle66.timeStamps) then
thatRectangle66.timeStamps = {}
for i = 1, amountOfTimeStamps do
thatRectangle66.timeStamps[i] = thatRectangle66:CreateFontString(nil, "overlay", "GameFontNormal")
thatRectangle66.timeStamps[i]:SetPoint("topleft", thatRectangle66, "topleft", 2 + (i - 1) * (width / amountOfTimeStamps), -2)
DetailsFramework:SetFontSize(thatRectangle66.timeStamps[i], 9)
end
thatRectangle66.nextChartTextureId = thatRectangle66.nextChartTextureId + 1
return thisTexture
end
end
--elapsed combat time
local combatObject = instance:GetShowingCombat()
local combatTime = math.floor(combatObject:GetCombatTime())
thatRectangle66.timeStamps[1]:SetText(DetailsFramework:IntegerToTimer(0))
for i = 2, #thatRectangle66.timeStamps do
local timePerSegment = combatTime / #thatRectangle66.timeStamps
thatRectangle66.timeStamps[i]:SetText(DetailsFramework:IntegerToTimer(i * timePerSegment))
end
--compute the width oif each texture
local textureWidth = width / combatTime
--compute the max height of a texture can have
local maxValue = 0
local numData = 0
--need to put the data in order FIRST
--each damage then need to be parsed
local dataInOrder = {}
local CONST_INDEX_TIMESTAMP = 1
local CONST_INDEX_DAMAGEDONE = 2
local CONST_INDEX_EVENTDAMAGE = 3
for timeStamp, value in pairs(chartData) do
dataInOrder[#dataInOrder+1] = {timeStamp, value}
dataInOrder[#dataInOrder+1] = {timeStamp, value}
dataInOrder[#dataInOrder+1] = {timeStamp, value}
numData = numData + 1
end
table.sort(dataInOrder, function(t1, t2) return t1[CONST_INDEX_TIMESTAMP] < t2[CONST_INDEX_TIMESTAMP] end)
local damageDoneByTime = dataInOrder
--parser the damage done
local currentTotalDamage = 0
for i = 1, #damageDoneByTime do
local damageEvent = damageDoneByTime[i]
local atTime = damageEvent[CONST_INDEX_TIMESTAMP]
local totalDamageUntilHere = damageEvent[CONST_INDEX_DAMAGEDONE] --raw damage
local spellDamage = totalDamageUntilHere - currentTotalDamage
currentTotalDamage = currentTotalDamage + spellDamage
damageEvent[CONST_INDEX_EVENTDAMAGE] = spellDamage
maxValue = math.max(spellDamage, maxValue)
end
--build the chart
for i = 1, #damageDoneByTime do
--for timeStamp, value in pairs(chartData) do --as it is pairs the data is scattered
local damageEvent = damageDoneByTime[i]
local timeStamp = damageEvent[CONST_INDEX_TIMESTAMP]
local damageDone = damageEvent[CONST_INDEX_EVENTDAMAGE]
local thisTexture = thatRectangle66:GetChartTexture()
thisTexture:SetWidth(textureWidth)
local texturePosition = textureWidth * timeStamp
thisTexture:SetPoint("bottomleft", thatRectangle66, "bottomleft", 1 + texturePosition, 1)
local percentFromPeak = damageDone / maxValue --normalized
thisTexture:SetHeight(math.min(percentFromPeak * height, height - 15))
thisTexture:Show()
--print("DEBUG", 7 , "Peak:", percentFromPeak, "position:", texturePosition, "damage done:", damageDone) --debug
end
--show bloodlust indicators, member .bloodlust is not guarantted
if (combatObject.bloodlust) then
--bloodlust not being added into the combat object, probably a bug on Parser
local bloodlustDuration = 40
for i = 1, #combatObject.bloodlust do
thatRectangle66.bloodLustIndicators[i]:Show()
thatRectangle66.bloodLustIndicators[i]:SetAlpha(0.46)
thatRectangle66.bloodLustIndicators[i]:SetSize(bloodlustDuration / combatTime * width, height - 2)
thatRectangle66.bloodLustIndicators[i]:SetPoint("bottomleft", thatRectangle66, "bottomleft", 0, 0)
if (not thatRectangle66.bloodLustIndicators) then
thatRectangle66.bloodLustIndicators = {}
for i = 1, 5 do
local thisIndicator = thatRectangle66:CreateTexture(nil, "artwork", nil, 4)
thisIndicator:SetColorTexture(0.0980392, 0.0980392, 0.439216)
thatRectangle66.bloodLustIndicators[#thatRectangle66.bloodLustIndicators+1] = thisIndicator
end
end
end
DetailsPlayerDetailsWindow_DetalheInfoBG_bg_end6:Hide()
thatRectangle66:SetShown(true)
for i = 1, #thatRectangle66.bloodLustIndicators do
thatRectangle66.bloodLustIndicators[i]:Hide()
end
if (not thatRectangle66.ChartTextures) then
thatRectangle66.ChartTextures = {}
function thatRectangle66:GetChartTexture()
local thisTexture = thatRectangle66.ChartTextures[thatRectangle66.nextChartTextureId]
if (not thisTexture) then
thisTexture = thatRectangle66:CreateTexture(nil, "artwork", nil, 5)
thisTexture:SetColorTexture(1, 1, 1, 0.65)
thatRectangle66.ChartTextures[thatRectangle66.nextChartTextureId] = thisTexture
end
thatRectangle66.nextChartTextureId = thatRectangle66.nextChartTextureId + 1
return thisTexture
end
end
--elapsed combat time
local combatObject = instance:GetShowingCombat()
local combatTime = math.floor(combatObject:GetCombatTime())
thatRectangle66.timeStamps[1]:SetText(DetailsFramework:IntegerToTimer(0))
for i = 2, #thatRectangle66.timeStamps do
local timePerSegment = combatTime / #thatRectangle66.timeStamps
thatRectangle66.timeStamps[i]:SetText(DetailsFramework:IntegerToTimer(i * timePerSegment))
end
--compute the width oif each texture
local textureWidth = width / combatTime
--compute the max height of a texture can have
local maxValue = 0
local numData = 0
--need to put the data in order FIRST
--each damage then need to be parsed
local dataInOrder = {}
local CONST_INDEX_TIMESTAMP = 1
local CONST_INDEX_DAMAGEDONE = 2
local CONST_INDEX_EVENTDAMAGE = 3
for timeStamp, value in pairs(chartData) do
dataInOrder[#dataInOrder+1] = {timeStamp, value}
dataInOrder[#dataInOrder+1] = {timeStamp, value}
dataInOrder[#dataInOrder+1] = {timeStamp, value}
numData = numData + 1
end
table.sort(dataInOrder, function(t1, t2) return t1[CONST_INDEX_TIMESTAMP] < t2[CONST_INDEX_TIMESTAMP] end)
local damageDoneByTime = dataInOrder
--parser the damage done
local currentTotalDamage = 0
for i = 1, #damageDoneByTime do
local damageEvent = damageDoneByTime[i]
local atTime = damageEvent[CONST_INDEX_TIMESTAMP]
local totalDamageUntilHere = damageEvent[CONST_INDEX_DAMAGEDONE] --raw damage
local spellDamage = totalDamageUntilHere - currentTotalDamage
currentTotalDamage = currentTotalDamage + spellDamage
damageEvent[CONST_INDEX_EVENTDAMAGE] = spellDamage
maxValue = math.max(spellDamage, maxValue)
end
--build the chart
for i = 1, #damageDoneByTime do
--for timeStamp, value in pairs(chartData) do --as it is pairs the data is scattered
local damageEvent = damageDoneByTime[i]
local timeStamp = damageEvent[CONST_INDEX_TIMESTAMP]
local damageDone = damageEvent[CONST_INDEX_EVENTDAMAGE]
local thisTexture = thatRectangle66:GetChartTexture()
thisTexture:SetWidth(textureWidth)
local texturePosition = textureWidth * timeStamp
thisTexture:SetPoint("bottomleft", thatRectangle66, "bottomleft", 1 + texturePosition, 1)
local percentFromPeak = damageDone / maxValue --normalized
thisTexture:SetHeight(math.min(percentFromPeak * height, height - 15))
thisTexture:Show()
--print("DEBUG", 7 , "Peak:", percentFromPeak, "position:", texturePosition, "damage done:", damageDone) --debug
end
--show bloodlust indicators, member .bloodlust is not guarantted
if (combatObject.bloodlust) then
--bloodlust not being added into the combat object, probably a bug on Parser
local bloodlustDuration = 40
for i = 1, #combatObject.bloodlust do
thatRectangle66.bloodLustIndicators[i]:Show()
thatRectangle66.bloodLustIndicators[i]:SetAlpha(0.46)
thatRectangle66.bloodLustIndicators[i]:SetSize(bloodlustDuration / combatTime * width, height - 2)
thatRectangle66.bloodLustIndicators[i]:SetPoint("bottomleft", thatRectangle66, "bottomleft", 0, 0)
end
end
DetailsBreakdownWindow_DetalheInfoBG_bg_end6:Hide()
thatRectangle66:SetShown(true)
end
end
_table_sort(data, Details.Sort1)
@@ -5488,9 +5611,8 @@ function atributo_damage:MontaDetalhesDamageDone (spellId, spellLine, instance)
end
for i = #data+2, 5 do
gump:HidaDetalheInfo (i)
gump:HidaDetalheInfo(i)
end
end
function Details:BuildPlayerDetailsSpellChart()
@@ -5577,7 +5699,6 @@ function Details:BuildPlayerDetailsSpellChart()
end
function atributo_damage:MontaTooltipDamageTaken (thisLine, index)
local aggressor = info.instancia.showing [1]:PegarCombatente (_, thisLine.nome_inimigo)
local container = aggressor.spells._ActorTable
local habilidades = {}
@@ -5613,7 +5734,7 @@ function atributo_damage:MontaTooltipDamageTaken (thisLine, index)
end
function atributo_damage:MontaTooltipAlvos (thisLine, index, instancia)
function atributo_damage:MontaTooltipAlvos (thisLine, index, instancia) --~deprecated
local inimigo = thisLine.nome_inimigo
local habilidades = {}
@@ -5980,6 +6101,8 @@ end
habilidade_shadow.extra [spellId] = (habilidade_shadow.extra [spellId] or 0) + amount
end
habilidade_shadow.spellschool = habilidade.spellschool
--soma todos os demais valores
for key, value in pairs(habilidade) do
if (type(value) == "number") then
@@ -6319,6 +6442,8 @@ end
function Details.refresh:r_atributo_damage (este_jogador, shadow)
--restaura metas do ator
detailsFramework:Mixin(este_jogador, Details222.Mixins.ActorMixin)
detailsFramework:Mixin(este_jogador, damageClassMixin)
setmetatable(este_jogador, Details.atributo_damage)
este_jogador.__index = Details.atributo_damage
--restaura as metas dos containers
+193 -11
View File
@@ -122,11 +122,6 @@ end
--tooltip function
local function RefreshNpcHealingTakenBar(tabela, barra, instancia)
atributo_damage:UpdateNpcHealingTaken(tabela, tabela.minha_barra, barra.colocacao, instancia)
end
local on_switch_NHT_show = function(instance) --npc healing taken
instance:TrocaTabela(instance, true, 1, 8)
return true
@@ -1868,8 +1863,193 @@ function atributo_heal:MontaInfoOverHealing()
end
function atributo_heal:MontaInfoHealingDone()
---@type actor
local actorObject = self
---@type instance
local instance = info.instancia
---@type combat
local combatObject = instance:GetCombat()
---@type string
local playerName = actorObject:Name()
--pegar as habilidade de dar sort no heal
---@type number
local actorTotal = actorObject.total
---@type table
local actorSpellsSorted = {}
---@type table<number, spelltable>
local actorSpells = actorObject:GetSpellList()
--get time
local actorCombatTime
if (Details.time_type == 1 or not actorObject.grupo) then
actorCombatTime = actorObject:Tempo()
elseif (Details.time_type == 2) then
actorCombatTime = info.instancia.showing:GetCombatTime()
end
--actor spells
---@type table<string, number>
local alreadyAdded = {}
for spellId, spellTable in pairs(actorSpells) do
---@cast spellId number
---@cast spellTable spelltable
spellTable.ChartData = nil
---@type string
local spellName = _GetSpellInfo(spellId)
if (spellName) then
---@type number in which index the spell with the same name was stored
local index = alreadyAdded[spellName]
if (index) then
---@type spelltableadv
local bkSpellData = actorSpellsSorted[index]
bkSpellData.spellIds[#bkSpellData.spellIds+1] = spellId
bkSpellData.spellTables[#bkSpellData.spellTables+1] = spellTable
bkSpellData.petNames[#bkSpellData.petNames+1] = ""
bkSpellData.bCanExpand = true
else
---@type spelltableadv
local bkSpellData = {
id = spellId,
spellschool = spellTable.spellschool,
bIsExpanded = Details222.BreakdownWindow.IsSpellExpanded(spellId),
bCanExpand = false,
spellIds = {spellId},
spellTables = {spellTable}, --sub spell tables to show if the spell is expanded
petNames = {""},
}
detailsFramework:Mixin(bkSpellData, Details.SpellTableMixin)
actorSpellsSorted[#actorSpellsSorted+1] = bkSpellData
alreadyAdded[spellName] = #actorSpellsSorted
end
end
end
--pets spells
local actorPets = actorObject:GetPets()
for _, petName in ipairs(actorPets) do
---@type actor
local petActor = combatObject(DETAILS_ATTRIBUTE_HEAL, petName)
if (petActor) then --PET
local spells = petActor:GetSpellList()
for spellId, spellTable in pairs(spells) do
---@cast spellId number
---@cast spellTable spelltable
spellTable.ChartData = nil
--PET
---@type string
local spellName = _GetSpellInfo(spellId)
if (spellName) then
---@type number in which index the spell with the same name was stored
local index = alreadyAdded[spellName]
if (index) then --PET
---@type spelltableadv
local bkSpellData = actorSpellsSorted[index]
bkSpellData.spellIds[#bkSpellData.spellIds+1] = spellId
bkSpellData.spellTables[#bkSpellData.spellTables+1] = spellTable
bkSpellData.petNames[#bkSpellData.petNames+1] = petName
bkSpellData.bCanExpand = true
else --PET
---@type spelltableadv
local bkSpellData = {
id = spellId,
spellschool = spellTable.spellschool,
expanded = Details222.BreakdownWindow.IsSpellExpanded(spellId),
bCanExpand = false,
spellIds = {spellId},
spellTables = {spellTable},
petNames = {petName},
}
detailsFramework:Mixin(bkSpellData, Details.SpellTableMixin)
actorSpellsSorted[#actorSpellsSorted+1] = bkSpellData
alreadyAdded[spellName] = #actorSpellsSorted
end
end
end
end
end
for i = 1, #actorSpellsSorted do
---@type spelltableadv
local bkSpellData = actorSpellsSorted[i]
Details.SpellTableMixin.SumSpellTables(bkSpellData.spellTables, bkSpellData)
end
--table.sort(actorSpellsSorted, Details.Sort2)
table.sort(actorSpellsSorted, function(t1, t2)
return t1.total > t2.total
end)
actorSpellsSorted.totalValue = actorTotal
actorSpellsSorted.combatTime = actorCombatTime
--actorSpellsSorted has the spell infomation, need to pass to the summary tab
--cleanup
table.wipe(alreadyAdded)
--send to the breakdown window
Details222.BreakdownWindow.SendSpellData(actorSpellsSorted, actorObject, combatObject, instance)
--targets
---an array of breakdowntargettable
---@type breakdowntargettable[]
local targetList = {}
--get the targets table: in the class heal, an actor has two targets table, one for normal healing and one for overheal
---@type targettable
local normalTargetsTable = self:GetTargets("targets")
---@type targettable
local overhealTargetsTable = self:GetTargets("targets_overheal")
local targetTotalValue = 0
local targetOverhealTotalValue = 0
--build the data required by the breakdown window
for targetName, amount in pairs(normalTargetsTable) do
if (amount > 0) then
local overhealAmount = overhealTargetsTable[targetName] or 0
---@type breakdowntargettable
local bkTargetData = {
name = targetName,
total = amount,
overheal = overhealAmount,
}
targetTotalValue = targetTotalValue + amount
targetOverhealTotalValue = targetOverhealTotalValue + (overhealAmount)
tinsert(targetList, bkTargetData)
end
end
for targetName, amount in pairs(overhealTargetsTable) do
if (amount > 0) then
if (not normalTargetsTable[targetName]) then
---@type breakdowntargettable
local bkTargetData = {
name = targetName,
total = 0,
overheal = amount,
}
targetOverhealTotalValue = targetOverhealTotalValue + (amount)
tinsert(targetList, bkTargetData)
end
end
end
targetList.totalValue = targetTotalValue
targetList.totalValueOverheal = targetOverhealTotalValue
targetList.combatTime = actorCombatTime
Details222.BreakdownWindow.SendTargetData(targetList, actorObject, combatObject, instance)
if 1 then return end
local instancia = info.instancia
local total = self.total
@@ -2306,7 +2486,7 @@ function atributo_heal:MontaDetalhesHealingDone (spellid, barra)
--NORMAL
local normal_hits = esta_magia.n_amt
if (normal_hits > 0) then
local normal_curado = esta_magia.n_curado
local normal_curado = esta_magia.n_total
local media_normal = normal_curado/normal_hits
media_normal = max(media_normal, 0.000001)
@@ -2337,11 +2517,11 @@ function atributo_heal:MontaDetalhesHealingDone (spellid, barra)
--CRITICO
if (esta_magia.c_amt > 0) then
local media_critico = esta_magia.c_curado/esta_magia.c_amt
local T = (meu_tempo*esta_magia.c_curado)/esta_magia.total
local media_critico = esta_magia.c_total/esta_magia.c_amt
local T = (meu_tempo*esta_magia.c_total)/esta_magia.total
local P = media/max(media_critico, 0.0001)*100
T = P*T/100
local crit_hps = esta_magia.c_curado/T
local crit_hps = esta_magia.c_total/T
if (not crit_hps) then
crit_hps = 0
end
@@ -2731,10 +2911,12 @@ end
end
end
habilidade_shadow.spellschool = habilidade.spellschool
--soma todos os demais valores
for key, value in pairs(habilidade) do
if (type(value) == "number") then
if (key ~= "id") then
if (key ~= "id" and key ~= "spellschool") then
if (not habilidade_shadow [key]) then
habilidade_shadow [key] = 0
end
+19 -18
View File
@@ -270,10 +270,9 @@ local instanceMixins = {
end,
---call a refresh in the data shown in the instance
---@param instance instance
---@param bForceRefresh boolean|nil
RefreshData = function(instance, bForceRefresh) --deprecates Details:RefreshAllMainWindows()
local combatObject = instance.showing
local combatObject = instance:GetCombat()
--check if the combat object exists, if not, freeze the window
if (not combatObject) then
@@ -283,24 +282,26 @@ local instanceMixins = {
return
end
local needRefresh = combatObject[instance.atributo].need_refresh
local mainAttribute, subAttribute = instance:GetDisplay()
local needRefresh = combatObject:GetContainer(mainAttribute).need_refresh
if (not needRefresh and not bForceRefresh) then
return
end
if (instance.atributo == 1) then --damage
if (mainAttribute == 1) then --damage
Details.atributo_damage:RefreshWindow(instance, combatObject, bForceRefresh, nil, needRefresh)
elseif (instance.atributo == 2) then --heal
elseif (mainAttribute == 2) then --heal
Details.atributo_heal:RefreshWindow(instance, combatObject, bForceRefresh, nil, needRefresh)
elseif (instance.atributo == 3) then --energy
elseif (mainAttribute == 3) then --energy
Details.atributo_energy:RefreshWindow(instance, combatObject, bForceRefresh, nil, needRefresh)
elseif (instance.atributo == 4) then --utility
elseif (mainAttribute == 4) then --utility
Details.atributo_misc:RefreshWindow(instance, combatObject, bForceRefresh, nil, needRefresh)
elseif (instance.atributo == 5) then --custom
elseif (mainAttribute == 5) then --custom
Details.atributo_custom:RefreshWindow(instance, combatObject, bForceRefresh, nil, needRefresh)
end
end,
@@ -330,11 +331,11 @@ local instanceMixins = {
end
--update player breakdown window if opened
if (not bForceRefresh) then
--if (not bForceRefresh) then
if (Details:IsBreakdownWindowOpen()) then
return Details:GetPlayerObjectFromBreakdownWindow():MontaInfo()
return Details:GetActorObjectFromBreakdownWindow():MontaInfo()
end
end
--end
end
end,
@@ -519,9 +520,9 @@ local instanceMixins = {
Details:CloseBreakdownWindow()
else
---@type actor
local actorObject = Details:GetPlayerObjectFromBreakdownWindow()
local actorObject = Details:GetActorObjectFromBreakdownWindow()
if (actorObject) then
Details:OpenPlayerBreakdown(instance, actorObject, true)
Details:OpenBreakdownWindow(instance, actorObject, true)
else
Details:CloseBreakdownWindow()
end
@@ -2832,13 +2833,13 @@ function _detalhes:TrocaTabela(instance, segmentId, attributeId, subAttributeId,
if (Details.playerDetailWindow:IsShown() and instance == Details.playerDetailWindow.instancia) then
if (not instance.showing or instance.atributo > 4) then
Details:FechaJanelaInfo()
Details:CloseBreakdownWindow()
else
local actor = instance.showing (instance.atributo, Details.playerDetailWindow.jogador.nome)
if (actor) then
instance:AbreJanelaInfo (actor, true)
local actorObject = instance.showing (instance.atributo, Details.playerDetailWindow.jogador.nome)
if (actorObject) then
Details:OpenBreakdownWindow(instance, actorObject, true)
else
Details:FechaJanelaInfo()
Details:CloseBreakdownWindow()
end
end
end
+8 -5
View File
@@ -34,17 +34,20 @@
id = id, --spellid
successful_casted = 0, --successful casted times (only for enemies)
--normal hits
--min damage made by normal hits
n_min = 0,
--max damage made by normal hits
n_max = 0,
--amount normal hits
n_amt = 0,
n_dmg = 0,
--total damage of normal hits
n_total = 0,
--critical hits
c_min = 0,
c_max = 0,
c_amt = 0,
c_dmg = 0,
c_total = 0,
--glacing hits
g_amt = 0,
@@ -114,7 +117,7 @@
self.g_amt = self.g_amt+1 --amount o total de dano
elseif (critical) then
self.c_dmg = self.c_dmg+amount --amount o total de dano
self.c_total = self.c_total+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
@@ -124,7 +127,7 @@
end
else
self.n_dmg = self.n_dmg+amount
self.n_total = self.n_total+amount
self.n_amt = self.n_amt+1
if (amount > self.n_max) then
self.n_max = amount
+37 -49
View File
@@ -1,96 +1,86 @@
-- heal ability file
local _detalhes = _G._detalhes
local Details = _G._detalhes
local _
local addonName, Details222 = ...
local healingAbility = Details.habilidade_cura
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--constants
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
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--internals
function habilidade_cura:NovaTabela (id, link)
local _newHealSpell = {
function healingAbility:NovaTabela(id)
---@type spelltable
local spellTable = {
--spellId
id = id,
--total amount of hits
counter = 0,
--totals
total = 0,
--healing done total (healing done by normal hits + healing done by critical hits)
total = 0,
--absorbs total
totalabsorb = 0,
absorbed = 0,
--overheal total
overheal = 0,
--heal denied
totaldenied = 0,
--normal hits
n_min = 0,
n_max = 0,
n_amt = 0,
n_curado = 0,
--critical hits
c_min = 0,
c_max = 0,
c_amt = 0,
c_curado = 0,
--healing done by normal hits
n_amt = 0, --amount of hits
n_min = 0, --min healing done by normal hits (non critical)
n_max = 0, --max healing done by normal hits (non critical)
n_total = 0, --total healing done by normal hits (non critical)
--healing done by critical hits
c_amt = 0, --amount of hits
c_min = 0, --min healing done by critical hits
c_max = 0, --max healing done by critical hits
c_total = 0, --total healing done by critical hits
--targets containers
targets = {},
targets_overheal = {},
targets_absorbs = {}
}
return _newHealSpell
return spellTable
end
function habilidade_cura:Add (serial, nome, flag, amount, extraSpellID, absorbed, critical, overhealing, is_shield)
function healingAbility:Add(serial, nome, flag, amount, extraSpellID, absorbed, critical, overhealing, bIsShield)
amount = amount or 0
self.targets [nome] = (self.targets [nome] or 0) + amount
if (absorbed == "SPELL_HEAL_ABSORBED") then
self.counter = self.counter + 1
self.totaldenied = self.totaldenied + amount
local healerName = critical
--create the denied table spells, on the fly
if (not self.heal_denied) then
self.heal_denied = {}
self.heal_denied_healers = {}
end
self.heal_denied [extraSpellID] = (self.heal_denied [extraSpellID] or 0) + amount
self.heal_denied_healers [healerName] = (self.heal_denied_healers [healerName] or 0) + amount
else
self.total = self.total + amount
self.counter = self.counter + 1
if (absorbed and absorbed > 0) then
self.absorbed = self.absorbed + absorbed
end
if (overhealing and overhealing > 0) then
self.overheal = self.overheal + overhealing
self.targets_overheal [nome] = (self.targets_overheal [nome] or 0) + overhealing
end
if (is_shield) then
if (bIsShield) then
self.totalabsorb = self.totalabsorb + amount
self.targets_absorbs [nome] = (self.targets_absorbs [nome] or 0) + amount
end
if (critical) then
self.c_curado = self.c_curado+amount --amount o total de dano
self.c_total = self.c_total+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
@@ -99,7 +89,7 @@
self.c_min = amount
end
else
self.n_curado = self.n_curado+amount
self.n_total = self.n_total+amount
self.n_amt = self.n_amt+1
if (amount > self.n_max) then
self.n_max = amount
@@ -108,8 +98,6 @@
self.n_min = amount
end
end
end
end
+104
View File
@@ -0,0 +1,104 @@
local addonName, Details222 = ...
local Details = Details
local detailsFramework = DetailsFramework
--this are the fields from spellTable that can be summed
local spellTable_FieldsToSum = {
["counter"] = true,
["total"] = true,
["c_amt"] = true,
["c_min"] = true,
["c_max"] = true,
["c_total"] = true,
["n_amt"] = true,
["n_total"] = true,
["n_min"] = true,
["n_max"] = true,
["successful_casted"] = true,
["g_amt"] = true,
["g_dmg"] = true,
["r_amt"] = true,
["r_dmg"] = true,
["b_amt"] = true,
["b_dmg"] = true,
["a_amt"] = true,
["a_dmg"] = true,
["totalabsorb"] = true,
["absorbed"] = true,
["overheal"] = true,
["totaldenied"] = true,
}
---@class spelltablemixin
---@field GetCritPercent fun(spellTable: spelltable) : number
---@field GetCritAverage fun(spellTable: spelltable) : number
---@field GetCastAmount fun(spellTable: spelltable, actorName: string, combatObject: combat)
---@field GetCastAverage fun(spellTable: spelltable, castAmount: number)
---@field SumSpellTables fun(spellTables: spelltable[], targetTable: table)
Details.SpellTableMixin = {
---return the critical hits percent
---@param spellTable spelltable
---@return number
GetCritPercent = function(spellTable)
return (spellTable.c_amt / math.max(spellTable.counter, 0.0001)) * 100
end,
---return the average value of critical hits
---@param spellTable spelltable
---@return number
GetCritAverage = function(spellTable)
return spellTable.c_total / math.max(spellTable.c_amt, 0.0001)
end,
---return the amount of casts the spell had
---@param spellTable spelltable
---@param actorName string
---@param combatObject combat
---@return number
GetCastAmount = function(spellTable, actorName, combatObject)
return combatObject:GetSpellCastAmount(actorName, spellTable.id)
end,
---return the average damage per cast
---@param spellTable spelltable
---@param castAmount number
---@return number
GetCastAverage = function(spellTable, castAmount)
if (castAmount > 0) then
return spellTable.total / castAmount
end
return 0
end,
---get the array of spelltables and sum each spellTable with the first spellTable found or on targetTable
---only sum the keys found in the spellTable_FieldsToSum table
---@param spellTables spelltable[]
---@param targetTable table
SumSpellTables = function(spellTables, targetTable)
local amtSpellTables = #spellTables
if (amtSpellTables == 0) then
return
end
targetTable = targetTable or spellTables[1]
for i = 1, amtSpellTables do
local spellTable = spellTables[i]
if (spellTable) then
for key, value in pairs(spellTable) do
---@cast key string
---@cast value number
if (spellTable_FieldsToSum[key]) then
targetTable[key] = (targetTable[key] or 0) + value
end
end
end
end
end,
}
--detailsFramework:Mixin(Details, Details.SpellTableMixin)
+2 -2
View File
@@ -451,7 +451,7 @@ function segmentClass:resetar_overall()
-- _detalhes.schedule_remove_overall = true
--else
--fecha a janela de informaes do jogador
Details:FechaJanelaInfo()
Details:CloseBreakdownWindow()
Details.tabela_overall = combatClass:NovaTabela()
@@ -498,7 +498,7 @@ function segmentClass:resetar()
--_detalhes.schedule_remove_overall = nil
--fecha a janela de informaes do jogador
Details:FechaJanelaInfo()
Details:CloseBreakdownWindow()
--empty temporary tables
Details.atributo_damage:ClearTempTables()
+2 -1
View File
@@ -40,7 +40,7 @@ local addonName, Details222 = ...
---get the spellTable for the passed spellId
---@param spellId number
---@return table
function container_habilidades:GetSpell (spellId)
function container_habilidades:GetSpell(spellId)
return self._ActorTable[spellId]
end
@@ -56,6 +56,7 @@ local addonName, Details222 = ...
end
---return an iterator for all spellTables in this container
---@param self spellcontainer
---@return fun(table: table<<K>, <V>>, index?: <K>):<K>, <V>
function container_habilidades:ListActors()
return pairs(self._ActorTable)
+17 -12
View File
@@ -42,6 +42,14 @@
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--details api functions
---for a number to the current selected abbreviation
---@param number number
---@return string
function Details:Format(number)
return Details.ToKFunctions[Details.ps_abbreviation](nil, number)
end
--try to find the opponent of last fight, can be called during a fight as well
function Details:FindEnemy()
@@ -1840,17 +1848,17 @@
self:RefreshMainWindow(true)
end
function Details:RefreshMainWindow(instance, bForceRefresh)
if (not instance or type(instance) == "boolean") then
bForceRefresh = instance
instance = self
function Details:RefreshMainWindow(instanceObject, bForceRefresh)
if (not instanceObject or type(instanceObject) == "boolean") then
bForceRefresh = instanceObject
instanceObject = self
end
if (not bForceRefresh) then
Details.LastUpdateTick = Details._tempo
end
if (instance == -1) then
if (instanceObject == -1) then
--update
for index, thisInstance in ipairs(Details.tabela_instancias) do
if (thisInstance.ativa) then
@@ -1876,19 +1884,16 @@
return info.jogador:MontaInfo()
end
end
return
else
if (not instance.ativa) then
--print("instance not actived", instance.RefreshMainWindow, 1+nil)
if (not instanceObject.ativa) then
return
end
end
if (instance.modo == modo_ALL or instance.modo == modo_GROUP) then
--print("updating all instances...")
return instance:RefreshAllMainWindows(bForceRefresh)
local currentMode = instanceObject:GetMode()
if (currentMode == DETAILS_MODE_ALL or currentMode == DETAILS_MODE_GROUP) then
return instanceObject:RefreshAllMainWindows(bForceRefresh)
end
end
+10 -3
View File
@@ -322,8 +322,12 @@
[45284] = 188196, --shaman lightining bolt overloaded
[228361] = 228360, --shadow priest void erruption
}
--all totem
--377461 382133
--377458 377459
end
local bitfield_debuffs = {}
@@ -2308,6 +2312,9 @@
if (bIsShield) then
spellTable.is_shield = true
end
spellTable.spellschool = spellType
if (_current_combat.is_boss and sourceFlags and bitBand(sourceFlags, OBJECT_TYPE_ENEMY) ~= 0) then
_detalhes.spell_school_cache[spellName] = spellType
end
@@ -5823,10 +5830,10 @@ local SPELL_POWER_PAIN = SPELL_POWER_PAIN or (PowerEnum and PowerEnum.Pain) or 1
_detalhes.logoff_saving_data = true
--close info window
if (_detalhes.FechaJanelaInfo) then
if (_detalhes.CloseBreakdownWindow) then
tinsert(_detalhes_global.exit_log, "1 - Closing Janela Info.")
currentStep = "Fecha Janela Info"
xpcall(_detalhes.FechaJanelaInfo, saver_error)
xpcall(_detalhes.CloseBreakdownWindow, saver_error)
end
--do not save window pos
+10
View File
@@ -518,6 +518,7 @@
local left,num,right = _string_match (n,'^([^%d]*%d)(%d*)(.-)$')
return left..(num:reverse():gsub('(%d%d%d)','%1,'):reverse())..right
end
function _detalhes:comma_value_raw (n)
local left,num,right = string.match(n,'^([^%d]*%d)(%d*)(.-)$')
return left..(num:reverse():gsub('(%d%d%d)','%1,'):reverse())..right
@@ -677,6 +678,15 @@
return _detalhes.ToKFunctions [_detalhes.ps_abbreviation]
end
--alias
---transfor an integer into a string separating thousands with a comma
---@param number number
---@return string
function Details:CommaValue(number)
return Details:comma_value(number)
end
------------------------------------------------------------------------------------------------------------
--numerical system
+19 -16
View File
@@ -1950,19 +1950,22 @@ local lineScript_Onmousedown = function(self, button)
end
local lineScript_Onmouseup = function(self, button)
local is_shift_down = _IsShiftKeyDown()
local is_control_down = _IsControlKeyDown()
local bIsShiftDown = _IsShiftKeyDown()
local bIsControlDown = _IsControlKeyDown()
if (self._instance.baseframe.isMoving) then
move_janela(self._instance.baseframe, false, self._instance)
self._instance:SaveMainWindowPosition()
---@type instance
local instanceObject = self._instance
if (self._instance:MontaTooltip(self, self.row_id)) then
if (instanceObject.baseframe.isMoving) then
move_janela(instanceObject.baseframe, false, instanceObject)
instanceObject:SaveMainWindowPosition()
if (instanceObject:MontaTooltip(self, self.row_id)) then
GameCooltip:Show (self, 1)
end
end
self._instance:HandleTextsOnMouseClick (self, "up")
instanceObject:HandleTextsOnMouseClick (self, "up")
local x, y = _GetCursorPosition()
x = floor(x)
@@ -1970,14 +1973,14 @@ local lineScript_Onmouseup = function(self, button)
if (self.mouse_down and (self.mouse_down+0.4 > GetTime() and (x == self.x and y == self.y)) or (x == self.x and y == self.y)) then
if (self.button == "LeftButton" or self.button == "MiddleButton") then
if (self._instance.atributo == 5 or is_shift_down) then
if (instanceObject.atributo == 5 or bIsShiftDown) then
--report
if (self._instance.atributo == 5 and is_shift_down) then
local custom = self._instance:GetCustomObject()
if (instanceObject.atributo == 5 and bIsShiftDown) then
local custom = instanceObject:GetCustomObject()
if (custom and custom.on_shift_click) then
local func = loadstring (custom.on_shift_click)
local func = loadstring(custom.on_shift_click)
if (func) then
local successful, errortext = pcall(func, self, self.minha_tabela, self._instance)
local successful, errortext = pcall(func, self, self.minha_tabela, instanceObject)
if (not successful) then
Details:Msg("error occurred custom script shift+click:", errortext)
end
@@ -1986,18 +1989,18 @@ local lineScript_Onmouseup = function(self, button)
end
end
if (Details.row_singleclick_overwrite [self._instance.atributo] and type(Details.row_singleclick_overwrite [self._instance.atributo][self._instance.sub_atributo]) == "function") then
return Details.row_singleclick_overwrite [self._instance.atributo][self._instance.sub_atributo] (_, self.minha_tabela, self._instance, is_shift_down, is_control_down)
if (Details.row_singleclick_overwrite [instanceObject.atributo] and type(Details.row_singleclick_overwrite [instanceObject.atributo][instanceObject.sub_atributo]) == "function") then
return Details.row_singleclick_overwrite [instanceObject.atributo][instanceObject.sub_atributo] (_, self.minha_tabela, instanceObject, bIsShiftDown, bIsControlDown)
end
return Details:ReportSingleLine (self._instance, self)
return Details:ReportSingleLine (instanceObject, self)
end
if (not self.minha_tabela) then
return Details:Msg("this bar is waiting update.")
end
self._instance:AbreJanelaInfo (self.minha_tabela, nil, nil, is_shift_down, is_control_down)
Details:OpenBreakdownWindow(instanceObject, self.minha_tabela, nil, nil, bIsShiftDown, bIsControlDown)
end
end
end
File diff suppressed because it is too large Load Diff
+4 -4
View File
@@ -30,7 +30,7 @@
}
function breakdownWindowPlayerList.CreatePlayerListFrame()
local f = _G.DetailsPlayerDetailsWindow
local f = _G.DetailsBreakdownWindow
local refreshPlayerList = function(self, data, offset, totalLines)
--update the scroll
@@ -57,8 +57,8 @@
end
local lineOnClick = function(self)
if (self.playerObject ~= Details:GetPlayerObjectFromBreakdownWindow()) then
Details:OpenPlayerBreakdown(Details:GetActiveWindowFromBreakdownWindow(), self.playerObject)
if (self.playerObject ~= Details:GetActorObjectFromBreakdownWindow()) then
Details:OpenBreakdownWindow(Details:GetActiveWindowFromBreakdownWindow(), self.playerObject)
f.playerScrollBox:Refresh()
end
end
@@ -80,7 +80,7 @@
end
local updatePlayerLine = function(self, topResult, encounterId, difficultyId) --~update
local playerSelected = Details:GetPlayerObjectFromBreakdownWindow()
local playerSelected = Details:GetActorObjectFromBreakdownWindow()
if (playerSelected and playerSelected == self.playerObject) then
self:SetBackdropColor(unpack(scrollbox_line_backdrop_color_selected))
self.isSelected = true
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,278 @@
local Details = Details
local DF = DetailsFramework
--create the main frame for the options panel
local createOptionsPanel = function()
local startX = 5
local startY = -24
local heightSize = 540
local DetailsSpellBreakdownTab = DetailsSpellBreakdownTab
local UIParent = UIParent
local options_text_template = DF:GetTemplate("font", "OPTIONS_FONT_TEMPLATE")
local options_dropdown_template = DF:GetTemplate("dropdown", "OPTIONS_DROPDOWN_TEMPLATE")
local options_switch_template = DF:GetTemplate("switch", "OPTIONS_CHECKBOX_TEMPLATE")
local options_slider_template = DF:GetTemplate("slider", "OPTIONS_SLIDER_TEMPLATE")
local options_button_template = DF:GetTemplate("button", "OPTIONS_BUTTON_TEMPLATE")
local optionsFrame = DF:CreateSimplePanel(UIParent, 550, 500, "Details! Breakdown Options", "DetailsSpellBreakdownOptionsPanel")
optionsFrame:SetFrameStrata("HIGH")
optionsFrame:SetPoint("topleft", UIParent, "topleft", 2, -40)
optionsFrame:Show()
local subSectionTitleTextTemplate = DF:GetTemplate("font", "ORANGE_FONT_TEMPLATE")
local optionsTable = {
{type = "label", get = function() return "Spell Details Block" end, text_template = subSectionTitleTextTemplate},
{--width
type = "range",
get = function() return Details.breakdown_spell_tab.blockcontainer_width end,
set = function(self, fixedparam, value)
Details.breakdown_spell_tab.blockcontainer_width = value
DetailsSpellBreakdownTab.GetSpellBlockFrame():UpdateBlocks()
end,
min = 150,
max = 450,
step = 1,
name = "Width",
desc = "Width",
hidden = true,
},
{--height
type = "range",
get = function() return Details.breakdown_spell_tab.blockcontainer_height end,
set = function(self, fixedparam, value)
Details.breakdown_spell_tab.blockcontainer_height = value
DetailsSpellBreakdownTab.GetSpellBlockFrame():UpdateBlocks()
end,
min = 150,
max = 450,
step = 1,
name = "Height",
desc = "Height",
hidden = true,
},
{--block height
type = "range",
get = function() return Details.breakdown_spell_tab.blockspell_height end,
set = function(self, fixedparam, value)
Details.breakdown_spell_tab.blockspell_height = value
DetailsSpellBreakdownTab.GetSpellBlockFrame():UpdateBlocks()
end,
min = 50,
max = 80,
step = 1,
name = "Block Height",
desc = "Block Height",
},
{--line height
type = "range",
get = function() return Details.breakdown_spell_tab.blockspellline_height end,
set = function(self, fixedparam, value)
Details.breakdown_spell_tab.blockspellline_height = value
DetailsSpellBreakdownTab.GetSpellBlockFrame():UpdateBlocks()
end,
min = 10,
max = 30,
step = 1,
name = "Line Height",
desc = "Line Height",
},
{--show spark
type = "toggle",
get = function() return Details.breakdown_spell_tab.blockspell_spark_show end,
set = function(self, fixedparam, value)
Details.breakdown_spell_tab.blockspell_spark_show = value
DetailsSpellBreakdownTab.GetSpellBlockFrame():UpdateBlocks()
end,
name = "Show Spark",
desc = "Show Spark",
},
{--spark width
type = "range",
get = function() return Details.breakdown_spell_tab.blockspell_spark_width end,
set = function(self, fixedparam, value)
Details.breakdown_spell_tab.blockspell_spark_width = value
DetailsSpellBreakdownTab.GetSpellBlockFrame():UpdateBlocks()
end,
min = 1,
max = 24,
step = 1,
name = "Spark Width",
desc = "Spark Width",
},
{--spark offset
type = "range",
get = function() return Details.breakdown_spell_tab.blockspell_spark_offset end,
set = function(self, fixedparam, value)
Details.breakdown_spell_tab.blockspell_spark_offset = value
DetailsSpellBreakdownTab.GetSpellBlockFrame():UpdateBlocks()
DetailsSpellBreakdownTab.UpdateShownSpellBlock()
end,
min = -12,
max = 12,
step = 1,
name = "Spark Offset",
desc = "Spark Offset",
},
{--spark color
type = "color",
get = function()
return Details.breakdown_spell_tab.blockspell_spark_color
end,
set = function(self, r, g, b, a)
Details.breakdown_spell_tab.blockspell_spark_color[1] = r
Details.breakdown_spell_tab.blockspell_spark_color[2] = g
Details.breakdown_spell_tab.blockspell_spark_color[3] = b
Details.breakdown_spell_tab.blockspell_spark_color[4] = a
DetailsSpellBreakdownTab.GetSpellBlockFrame():UpdateBlocks()
end,
name = "Spark Color",
desc = "Spark Color",
},
{type = "blank"},
{type = "blank"},
{type = "label", get = function() return "Spell Header Options" end, text_template = subSectionTitleTextTemplate},
{ --per second
type = "toggle",
get = function() return Details.breakdown_spell_tab.spellcontainer_headers["persecond"].enabled end,
set = function(self, fixedparam, value)
Details.breakdown_spell_tab.spellcontainer_headers["persecond"].enabled = value
DetailsSpellBreakdownTab.UpdateHeadersSettings("spells")
end,
name = "Per Second",
desc = "Per Second",
},
{ --amount of casts
type = "toggle",
get = function() return Details.breakdown_spell_tab.spellcontainer_headers["casts"].enabled end,
set = function(self, fixedparam, value)
Details.breakdown_spell_tab.spellcontainer_headers["casts"].enabled = value
DetailsSpellBreakdownTab.UpdateHeadersSettings("spells")
end,
name = "Casts",
desc = "Casts",
},
{ --critical hits percent
type = "toggle",
get = function() return Details.breakdown_spell_tab.spellcontainer_headers["critpercent"].enabled end,
set = function(self, fixedparam, value)
Details.breakdown_spell_tab.spellcontainer_headers["critpercent"].enabled = value
DetailsSpellBreakdownTab.UpdateHeadersSettings("spells")
end,
name = "Critical Hits Percent",
desc = "Critical Hits Percent",
},
{ --amount of hits
type = "toggle",
get = function() return Details.breakdown_spell_tab.spellcontainer_headers["hits"].enabled end,
set = function(self, fixedparam, value)
Details.breakdown_spell_tab.spellcontainer_headers["hits"].enabled = value
DetailsSpellBreakdownTab.UpdateHeadersSettings("spells")
end,
name = "Hits Amount",
desc = "Hits Amount",
},
{ --average damage of healing per cast amount
type = "toggle",
get = function() return Details.breakdown_spell_tab.spellcontainer_headers["castavg"].enabled end,
set = function(self, fixedparam, value)
Details.breakdown_spell_tab.spellcontainer_headers["castavg"].enabled = value
DetailsSpellBreakdownTab.UpdateHeadersSettings("spells")
end,
name = "Cast Average",
desc = "Cast Average",
},
{ --debuff uptime
type = "toggle",
get = function() return Details.breakdown_spell_tab.spellcontainer_headers["uptime"].enabled end,
set = function(self, fixedparam, value)
Details.breakdown_spell_tab.spellcontainer_headers["uptime"].enabled = value
DetailsSpellBreakdownTab.UpdateHeadersSettings("spells")
end,
name = "Uptime",
desc = "Uptime",
},
{ --overheal
type = "toggle",
get = function() return Details.breakdown_spell_tab.spellcontainer_headers["overheal"].enabled end,
set = function(self, fixedparam, value)
Details.breakdown_spell_tab.spellcontainer_headers["overheal"].enabled = value
DetailsSpellBreakdownTab.UpdateHeadersSettings("spells")
end,
name = "Overheal",
desc = "Overheal",
},
{ --absorbed
type = "toggle",
get = function() return Details.breakdown_spell_tab.spellcontainer_headers["absorbed"].enabled end,
set = function(self, fixedparam, value)
Details.breakdown_spell_tab.spellcontainer_headers["absorbed"].enabled = value
DetailsSpellBreakdownTab.UpdateHeadersSettings("spells")
end,
name = "Heal Absorbed",
desc = "Heal Absorbed",
},
{type = "breakline"},
{type = "label", get = function() return "Scroll Options" end, text_template = subSectionTitleTextTemplate},
{ --locked
type = "toggle",
get = function() return Details.breakdown_spell_tab.spellcontainer_islocked end,
set = function(self, fixedparam, value)
---@type df_framecontainer
local container = DetailsSpellBreakdownTab.GetSpellScrollContainer()
container:SetResizeLocked(value)
local container = DetailsSpellBreakdownTab.GetTargetScrollContainer()
container:SetResizeLocked(value)
end,
name = "Is Locked",
desc = "Is Locked",
},
{--background alpha
type = "range",
get = function() return Details.breakdown_spell_tab.spellbar_background_alpha end,
set = function(self, fixedparam, value)
Details.breakdown_spell_tab.spellbar_background_alpha = value
DetailsSpellBreakdownTab.GetSpellScrollFrame():Refresh()
end,
min = 0,
max = 1,
step = 0.1,
usedecimals = true,
name = "Background Alpha",
desc = "Background Alpha",
},
}
--build the menu
optionsTable.always_boxfirst = true
DF:BuildMenu(optionsFrame, optionsTable, startX, startY, heightSize, false, options_text_template, options_dropdown_template, options_switch_template, true, options_slider_template, options_button_template)
end
function Details.OpenSpellBreakdownOptions()
if (DetailsSpellBreakdownOptionsPanel) then
DetailsSpellBreakdownOptionsPanel:RefreshOptions()
DetailsSpellBreakdownOptionsPanel:Show()
return
end
createOptionsPanel()
end
+4 -4
View File
@@ -964,11 +964,11 @@ function Details.UnitDamageSpellInfo (unitId, spellId, isLiteral, segment)
spellInfo.regularMin = spellObject.n_min
spellInfo.regularMax = spellObject.n_max
spellInfo.regularHits = spellObject.n_amt
spellInfo.regularDamage = spellObject.n_dmg
spellInfo.regularDamage = spellObject.n_total
spellInfo.criticalMin = spellObject.c_min
spellInfo.criticalMax = spellObject.c_max
spellInfo.criticalHits = spellObject.c_amt
spellInfo.criticalDamage = spellObject.c_dmg
spellInfo.criticalDamage = spellObject.c_total
end
return spellInfo
@@ -1695,11 +1695,11 @@ function Details.UnitHealingSpellInfo (unitId, spellId, isLiteral, segment)
spellInfo.regularMin = spellObject.n_min
spellInfo.regularMax = spellObject.n_max
spellInfo.regularHits = spellObject.n_amt
spellInfo.regularHealing = spellObject.n_dmg
spellInfo.regularHealing = spellObject.n_total
spellInfo.criticalMin = spellObject.c_min
spellInfo.criticalMax = spellObject.c_max
spellInfo.criticalHits = spellObject.c_amt
spellInfo.criticalHealing = spellObject.c_dmg
spellInfo.criticalHealing = spellObject.c_total
end
return spellInfo
+16 -9
View File
@@ -1,8 +1,10 @@
local Details = _G.Details
local addonName, Details222 = ...
local bIsEnabled = false
local testCharacterName = "Ditador"
--namespace
Details.CurrentDps = {
Dps = {},
@@ -41,27 +43,27 @@ currentDpsFrame.OnUpdateFunc = function(self, deltaTime)
--get the damage done on this tick
local totalDamageThisTick = actorObject.total - actorTable.latestDamageAmount
--add the damage to the cache
tinsert(actorTable.cache, 1, totalDamageThisTick)
table.insert(actorTable.cache, 1, totalDamageThisTick)
--set the latest damage amount
actorTable.latestDamageAmount = actorObject.total
--sum the total damage the actor inflicted
actorTable.totalDamage = actorTable.totalDamage + totalDamageThisTick
--cut the damage
local damageRemoved = tremove(actorTable.cache, cacheOverflowIndex)
local damageRemoved = table.remove(actorTable.cache, cacheOverflowIndex)
if (damageRemoved) then
actorTable.totalDamage = actorTable.totalDamage - damageRemoved
actorTable.totalDamage = max(0, actorTable.totalDamage) --safe guard
actorTable.totalDamage = math.max(0, actorTable.totalDamage) --safe guard
end
actorTable.currentDps = actorTable.totalDamage / dpsTime
if (actorObject.nome == "Ditador") then
if (actorObject.nome == testCharacterName) then --debug
local formatToKFunc = Details:GetCurrentToKFunction()
print(actorTable.totalDamage, #actorTable.cache, dpsTime, formatToKFunc(nil, actorTable.currentDps))
end
if (actorObject.nome == "Ditador") then
--print("Dps:", actorTable.currentDps)
if (actorObject.nome == testCharacterName) then --debug
print("Dps:", actorTable.currentDps)
end
end
end
@@ -94,8 +96,13 @@ end
--handle internal details! events
local eventListener = Details:CreateEventListener()
eventListener:RegisterEvent("COMBAT_PLAYER_ENTER", function()
--Details.CurrentDps.StartCurrentDpsTracker()
if (bIsEnabled) then
Details.CurrentDps.StartCurrentDpsTracker()
end
end)
eventListener:RegisterEvent("COMBAT_PLAYER_LEAVE", function()
--Details.CurrentDps.StopCurrentDpsTracker()
if (bIsEnabled) then
Details.CurrentDps.StopCurrentDpsTracker()
end
end)
+2
View File
@@ -26,6 +26,7 @@
["UNIT_SPEC"] = {},
["UNIT_TALENTS"] = {},
["PLAYER_TARGET"] = {},
["DETAILS_PROFILE_APPLYED"] = {},
--data
["DETAILS_DATA_RESET"] = {},
@@ -123,6 +124,7 @@ local common_events = {
["UNIT_SPEC"] = true,
["UNIT_TALENTS"] = true,
["PLAYER_TARGET"] = true,
["DETAILS_PROFILE_APPLYED"] = true,
}
+2 -2
View File
@@ -9,9 +9,9 @@ function Details:OpenPlayerDetails(window)
if (instance) then
local display, subDisplay = instance:GetDisplay()
if (display == 1) then
instance:AbreJanelaInfo (Details:GetPlayer(false, 1))
Details:OpenBreakdownWindow(instance, Details:GetPlayer(false, 1))
elseif (display == 2) then
instance:AbreJanelaInfo (Details:GetPlayer(false, 2))
Details:OpenBreakdownWindow(instance, Details:GetPlayer(false, 2))
end
end
end
+91 -1
View File
@@ -4,7 +4,6 @@ local detailsFramework = _G.DetailsFramework
local openRaidLib = LibStub:GetLibrary("LibOpenRaid-1.0", true)
local addonName, Details222 = ...
Details222.Mixins.ActorMixin = {
---return a spellContainer from an actor
---@param actor actor
@@ -39,4 +38,95 @@ Details222.Mixins.ActorMixin = {
return spellTable
end
end,
---return a table containing pet names
---@param actor actor
---@return table<number, string>
GetPets = function(actor)
return actor.pets
end,
---return a table containing the targets of the actor
---@param actor actor
---@param key string optional, if not provided, will use the default target table: 'targets'
---@return targettable
GetTargets = function(actor, key)
return actor[key or "targets"]
end,
---return a table containing spellTables
---@param actor actor
---@return table<number, spelltable>
GetSpellList = function(actor)
return actor.spells._ActorTable
end,
---this function sums all the targets of all spellTables conteining on a 'spelltableadv'
---@param actor actor
---@param bkSpellData spelltableadv
---@param targetTableName string
---@return table<string, number>
BuildSpellTargetFromBreakdownSpellData = function(actor, bkSpellData, targetTableName)
targetTableName = targetTableName or "targets"
local spellTables = bkSpellData.spellTables
---@type table<string, number> store the index of the target name in the result table
local cacheIndex = {}
---@type table<string, number> store the result which is returned by this function
local result = {}
for i = 1, #spellTables do
---@type spelltable
local spellTable = spellTables[i]
---@type table<string, number>
local targets = spellTable[targetTableName]
for targetName, value in pairs(targets) do
local index = cacheIndex[targetName]
if (index) then
result[index][2] = result[index][2] + value
else
result[#result+1] = {targetName, value}
cacheIndex[targetName] = #result
end
end
end
table.sort(result, function(t1, t2)
return t1[2] > t2[2]
end)
return result
end,
---this function receives a key for the name of the target table (usually is 'targets') and return a table containing the targets and the damage done in order of bigger to lower value
---@param actor actor
---@param spellTable spelltable
---@param targetKey string
---@return table<string, number>
BuildSpellTargetFromSpellTable = function(actor, spellTable, targetKey)
targetKey = targetKey or "targets"
---@type table<string, number>[] store the result which is returned by this function
local result = {}
---@type table<string, number>
local targets = spellTable[targetKey]
for targetName, value in pairs(targets) do
---@cast targetName string
---@cast value number
result[#result+1] = {targetName, value}
end
table.sort(result, function(t1, t2)
return t1[2] > t2[2]
end)
return result
end,
}
+165 -130
View File
@@ -1,5 +1,5 @@
local _detalhes = _G._detalhes
local Details = _G.Details
local Loc = LibStub("AceLocale-3.0"):GetLocale ( "Details" )
local _
local addonName, Details222 = ...
@@ -7,7 +7,7 @@ local detailsFramework = DetailsFramework
---return the current profile name
---@return string
function _detalhes:GetCurrentProfileName()
function Details:GetCurrentProfileName()
if (_detalhes_database.active_profile == "") then
local characterKey = UnitName ("player") .. "-" .. GetRealmName()
_detalhes_database.active_profile = characterKey
@@ -18,7 +18,7 @@ end
---create a new profile
---@param profileName string
---@return boolean|table
function _detalhes:CreateProfile(profileName)
function Details:CreateProfile(profileName)
if (not profileName or type(profileName) ~= "string" or profileName == "") then
return false
end
@@ -29,7 +29,7 @@ function _detalhes:CreateProfile(profileName)
end
--copy the default table
local newProfile = Details.CopyTable(_detalhes.default_profile)
local newProfile = Details.CopyTable(Details.default_profile)
newProfile.instances = {}
--add to global container
@@ -41,7 +41,7 @@ end
---return the list os all profiles
---@return table
function _detalhes:GetProfileList()
function Details:GetProfileList()
local profileList = {}
for profileName in pairs(_detalhes_global.__profiles) do
profileList[#profileList + 1] = profileName
@@ -96,12 +96,12 @@ function Details:GetProfile(profileName, create)
return profile
end
function _detalhes:SetProfileCProp (name, cprop, value)
function Details:SetProfileCProp (name, cprop, value)
if (not name) then
name = _detalhes:GetCurrentProfileName()
name = Details:GetCurrentProfileName()
end
local profile = _detalhes:GetProfile (name, false)
local profile = Details:GetProfile (name, false)
if (profile) then
if (type(value) == "table") then
@@ -117,37 +117,37 @@ end
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--Profiles:
--reset the profile
function _detalhes:ResetProfile (profile_name)
function Details:ResetProfile (profile_name)
--get the profile
local profile = _detalhes:GetProfile (profile_name, true)
local profile = Details:GetProfile (profile_name, true)
if (not profile) then
return false
end
--reset all already created instances
for index, instance in _detalhes:ListInstances() do
for index, instance in Details:ListInstances() do
if (not instance.baseframe) then
instance:AtivarInstancia()
end
instance.skin = ""
instance:ChangeSkin (_detalhes.default_skin_to_use)
instance:ChangeSkin (Details.default_skin_to_use)
end
for index, instance in pairs(_detalhes.unused_instances) do
for index, instance in pairs(Details.unused_instances) do
if (not instance.baseframe) then
instance:AtivarInstancia()
end
instance.skin = ""
instance:ChangeSkin(_detalhes.default_skin_to_use)
instance:ChangeSkin(Details.default_skin_to_use)
end
--reset the profile
table.wipe(profile.instances)
--export first instance
local instance = _detalhes:GetInstance(1)
local instance = Details:GetInstance(1)
local exported = instance:ExportSkin()
exported.__was_opened = instance:IsEnabled()
exported.__pos = Details.CopyTable(instance:GetPosition())
@@ -160,7 +160,7 @@ function _detalhes:ResetProfile (profile_name)
instance.verticalSnap = false
instance.snap = {}
_detalhes:ApplyProfile (profile_name, true)
Details:ApplyProfile (profile_name, true)
--end
return true
@@ -170,39 +170,39 @@ end
--Profiles:
--return the profile table requested
function _detalhes:CreatePanicWarning()
_detalhes.instance_load_failed = CreateFrame("frame", "DetailsPanicWarningFrame", UIParent,"BackdropTemplate")
_detalhes.instance_load_failed:SetHeight(80)
function Details:CreatePanicWarning()
Details.instance_load_failed = CreateFrame("frame", "DetailsPanicWarningFrame", UIParent,"BackdropTemplate")
Details.instance_load_failed:SetHeight(80)
--tinsert(UISpecialFrames, "DetailsPanicWarningFrame")
_detalhes.instance_load_failed.text = _detalhes.instance_load_failed:CreateFontString(nil, "overlay", "GameFontNormal")
_detalhes.instance_load_failed.text:SetPoint("center", _detalhes.instance_load_failed, "center")
_detalhes.instance_load_failed.text:SetTextColor(1, 0.6, 0)
_detalhes.instance_load_failed:SetBackdrop({bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true})
_detalhes.instance_load_failed:SetBackdropColor(1, 0, 0, 0.2)
_detalhes.instance_load_failed:SetPoint("topleft", UIParent, "topleft", 0, -250)
_detalhes.instance_load_failed:SetPoint("topright", UIParent, "topright", 0, -250)
Details.instance_load_failed.text = Details.instance_load_failed:CreateFontString(nil, "overlay", "GameFontNormal")
Details.instance_load_failed.text:SetPoint("center", Details.instance_load_failed, "center")
Details.instance_load_failed.text:SetTextColor(1, 0.6, 0)
Details.instance_load_failed:SetBackdrop({bgFile = [[Interface\Tooltips\UI-Tooltip-Background]], tileSize = 64, tile = true})
Details.instance_load_failed:SetBackdropColor(1, 0, 0, 0.2)
Details.instance_load_failed:SetPoint("topleft", UIParent, "topleft", 0, -250)
Details.instance_load_failed:SetPoint("topright", UIParent, "topright", 0, -250)
end
local safe_load = function(func, param1, ...)
local okey, errortext = pcall(func, param1, ...)
if (not okey) then
if (not _detalhes.instance_load_failed) then
_detalhes:CreatePanicWarning()
if (not Details.instance_load_failed) then
Details:CreatePanicWarning()
end
_detalhes.do_not_save_skins = true
_detalhes.instance_load_failed.text:SetText("Failed to load a Details! window.\n/reload or reboot the game client may fix the problem.\nIf the problem persist, try /details reinstall.\nError: " .. errortext .. "")
Details.do_not_save_skins = true
Details.instance_load_failed.text:SetText("Failed to load a Details! window.\n/reload or reboot the game client may fix the problem.\nIf the problem persist, try /details reinstall.\nError: " .. errortext .. "")
end
return okey
end
function _detalhes:ApplyProfile (profile_name, nosave, is_copy)
function Details:ApplyProfile (profile_name, nosave, is_copy)
--get the profile
local profile = _detalhes:GetProfile (profile_name, true)
local profile = Details:GetProfile (profile_name, true)
--if the profile doesn't exist, just quit
if (not profile) then
_detalhes:Msg("Profile Not Found.")
Details:Msg("Profile Not Found.")
return false
end
@@ -211,15 +211,15 @@ function _detalhes:ApplyProfile (profile_name, nosave, is_copy)
--always save the previous profile, except if nosave flag is up
if (not nosave) then
--salva o profile ativo no momento
_detalhes:SaveProfile()
Details:SaveProfile()
end
--update profile keys before go
for key, value in pairs(_detalhes.default_profile) do
for key, value in pairs(Details.default_profile) do
--the entire key doesn't exist
if (profile [key] == nil) then
if (type(value) == "table") then
profile [key] = Details.CopyTable(_detalhes.default_profile [key])
profile [key] = Details.CopyTable(Details.default_profile [key])
else
profile [key] = value
end
@@ -227,45 +227,45 @@ function _detalhes:ApplyProfile (profile_name, nosave, is_copy)
--the key exist and is a table, check for missing values on sub tables
elseif (type(value) == "table") then
--deploy only copy non existing data
_detalhes.table.deploy(profile [key], value)
Details.table.deploy(profile [key], value)
end
end
--apply the profile values
for key, _ in pairs(_detalhes.default_profile) do
for key, _ in pairs(Details.default_profile) do
local value = profile [key]
if (type(value) == "table") then
if (key == "class_specs_coords") then
value = Details.CopyTable(_detalhes.default_profile.class_specs_coords)
value = Details.CopyTable(Details.default_profile.class_specs_coords)
end
local ctable = Details.CopyTable(value)
_detalhes [key] = ctable
Details [key] = ctable
else
_detalhes [key] = value
Details [key] = value
end
end
--set the current profile
if (not is_copy) then
_detalhes.active_profile = profile_name
Details.active_profile = profile_name
_detalhes_database.active_profile = profile_name
end
--apply the skin
--first save the local instance configs
_detalhes:SaveLocalInstanceConfig()
Details:SaveLocalInstanceConfig()
local saved_skins = profile.instances
local instance_limit = _detalhes.instances_amount
local instance_limit = Details.instances_amount
--then close all opened instances
for index, instance in _detalhes:ListInstances() do
for index, instance in Details:ListInstances() do
if (not getmetatable(instance)) then
instance.iniciada = false
setmetatable(instance, _detalhes)
setmetatable(instance, Details)
end
if (instance:IsStarted()) then
if (instance:IsEnabled()) then
@@ -276,16 +276,16 @@ function _detalhes:ApplyProfile (profile_name, nosave, is_copy)
--check if there is a skin saved or this is a empty profile
if (#saved_skins == 0) then
local instance1 = _detalhes:GetInstance(1)
local instance1 = Details:GetInstance(1)
if (not instance1) then
instance1 = _detalhes:CreateInstance (1)
instance1 = Details:CreateInstance (1)
end
--apply default config on this instance (flat skin texture was 'ResetInstanceConfig' running).
instance1.modo = 2
instance1:ResetInstanceConfig()
instance1.skin = "no skin"
instance1:ChangeSkin (_detalhes.default_skin_to_use)
instance1:ChangeSkin (Details.default_skin_to_use)
--release the snap and lock
instance1:LoadLocalInstanceConfig()
@@ -294,11 +294,11 @@ function _detalhes:ApplyProfile (profile_name, nosave, is_copy)
instance1.verticalSnap = nil
instance1:LockInstance (false)
if (#_detalhes.tabela_instancias > 1) then
for i = #_detalhes.tabela_instancias, 2, -1 do
_detalhes.tabela_instancias [i].modo = 2
_detalhes.unused_instances [i] = _detalhes.tabela_instancias [i]
_detalhes.tabela_instancias [i] = nil
if (#Details.tabela_instancias > 1) then
for i = #Details.tabela_instancias, 2, -1 do
Details.tabela_instancias [i].modo = 2
Details.unused_instances [i] = Details.tabela_instancias [i]
Details.tabela_instancias [i] = nil
end
end
else
@@ -312,10 +312,10 @@ function _detalhes:ApplyProfile (profile_name, nosave, is_copy)
end
--get the instance
local instance = _detalhes:GetInstance(index)
local instance = Details:GetInstance(index)
if (not instance) then
--create a instance without creating its frames (not initializing)
instance = _detalhes:CreateDisabledInstance (index, skin)
instance = Details:CreateDisabledInstance (index, skin)
end
--copy skin
@@ -339,7 +339,7 @@ function _detalhes:ApplyProfile (profile_name, nosave, is_copy)
--load data saved for this character only
instance:LoadLocalInstanceConfig()
if (skin.__was_opened) then
if (not safe_load (_detalhes.AtivarInstancia, instance, nil, true)) then
if (not safe_load (Details.AtivarInstancia, instance, nil, true)) then
return
end
else
@@ -351,7 +351,7 @@ function _detalhes:ApplyProfile (profile_name, nosave, is_copy)
--load data saved again
instance:LoadLocalInstanceConfig()
--check window positioning
if (_detalhes.profile_save_pos) then
if (Details.profile_save_pos) then
--print("is profile save pos", skin.__pos.normal.x, skin.__pos.normal.y)
if (skin.__pos) then
instance.posicao = Details.CopyTable(skin.__pos)
@@ -385,14 +385,14 @@ function _detalhes:ApplyProfile (profile_name, nosave, is_copy)
instance:LockInstance (instance.isLocked)
--tinsert(_detalhes.resize_debug, #_detalhes.resize_debug+1, "libwindow X (427): " .. (instance.libwindow.x or 0))
--tinsert(Details.resize_debug, #Details.resize_debug+1, "libwindow X (427): " .. (instance.libwindow.x or 0))
instance:RestoreMainWindowPosition()
instance:ReajustaGump()
--instance:SaveMainWindowPosition()
--Load StatusBarSaved values and options.
instance.StatusBarSaved = skin.StatusBarSaved or {options = {}}
instance.StatusBar.options = instance.StatusBarSaved.options
_detalhes.StatusBar:UpdateChilds (instance)
Details.StatusBar:UpdateChilds (instance)
instance:ChangeSkin()
else
@@ -403,18 +403,18 @@ function _detalhes:ApplyProfile (profile_name, nosave, is_copy)
end
--move unused instances for unused container
if (#_detalhes.tabela_instancias > instances_loaded) then
for i = #_detalhes.tabela_instancias, instances_loaded+1, -1 do
_detalhes.unused_instances [i] = _detalhes.tabela_instancias [i]
_detalhes.tabela_instancias [i] = nil
if (#Details.tabela_instancias > instances_loaded) then
for i = #Details.tabela_instancias, instances_loaded+1, -1 do
Details.unused_instances [i] = Details.tabela_instancias [i]
Details.tabela_instancias [i] = nil
end
end
--check all snaps for invalid entries
for i = 1, instances_loaded do
local instance = _detalhes:GetInstance(i)
local previous_instance_id = _detalhes:GetInstance(i-1) and _detalhes:GetInstance(i-1):GetId() or 0
local next_instance_id = _detalhes:GetInstance(i+1) and _detalhes:GetInstance(i+1):GetId() or 0
local instance = Details:GetInstance(i)
local previous_instance_id = Details:GetInstance(i-1) and Details:GetInstance(i-1):GetId() or 0
local next_instance_id = Details:GetInstance(i+1) and Details:GetInstance(i+1):GetId() or 0
for snap_side, instance_id in pairs(instance.snap) do
if (instance_id < 1) then --invalid instance
@@ -426,18 +426,18 @@ function _detalhes:ApplyProfile (profile_name, nosave, is_copy)
end
--auto realign windows
if (not _detalhes.initializing) then
for _, instance in _detalhes:ListInstances() do
if (not Details.initializing) then
for _, instance in Details:ListInstances() do
if (instance:IsEnabled()) then
_detalhes.move_janela_func(instance.baseframe, true, instance)
_detalhes.move_janela_func(instance.baseframe, false, instance)
Details.move_janela_func(instance.baseframe, true, instance)
Details.move_janela_func(instance.baseframe, false, instance)
end
end
else
--is in startup
for _, instance in _detalhes:ListInstances() do
for _, instance in Details:ListInstances() do
for side, id in pairs(instance.snap) do
local window = _detalhes.tabela_instancias [id]
local window = Details.tabela_instancias [id]
if (not window.ativa) then
instance.snap [side] = nil
if ((side == 1 or side == 3) and (not instance.snap [1] and not instance.snap [3])) then
@@ -460,39 +460,38 @@ function _detalhes:ApplyProfile (profile_name, nosave, is_copy)
end
--check instance amount
_detalhes.opened_windows = 0
for index = 1, _detalhes.instances_amount do
local instance = _detalhes.tabela_instancias [index]
Details.opened_windows = 0
for index = 1, Details.instances_amount do
local instance = Details.tabela_instancias [index]
if (instance and instance.ativa) then
_detalhes.opened_windows = _detalhes.opened_windows + 1
Details.opened_windows = Details.opened_windows + 1
end
end
--update tooltip settings
_detalhes:SetTooltipBackdrop()
--update player detail window
_detalhes:ApplyPDWSkin()
Details:SetTooltipBackdrop()
--update the numerical system
_detalhes:SelectNumericalSystem()
Details:SelectNumericalSystem()
--refresh the update interval
_detalhes:RefreshUpdater()
Details:RefreshUpdater()
--refresh animation functions
_detalhes:RefreshAnimationFunctions()
Details:RefreshAnimationFunctions()
--refresh broadcaster tools
_detalhes:LoadFramesForBroadcastTools()
Details:LoadFramesForBroadcastTools()
--change the rogue spec combat icon to outlaw depending on the game version
Details:HandleRogueCombatSpecIconByGameVersion()
if (_detalhes.initializing) then
_detalhes.profile_loaded = true
if (Details.initializing) then
Details.profile_loaded = true
end
Details:SendEvent("DETAILS_PROFILE_APPLYED", profile_name)
return true
end
@@ -500,7 +499,7 @@ end
--Profiles:
--return the profile table requested
function _detalhes:SaveProfile (saveas)
function Details:SaveProfile (saveas)
--get the current profile
@@ -509,15 +508,15 @@ function _detalhes:SaveProfile (saveas)
if (saveas) then
profile_name = saveas
else
profile_name = _detalhes:GetCurrentProfileName()
profile_name = Details:GetCurrentProfileName()
end
local profile = _detalhes:GetProfile (profile_name, true)
local profile = Details:GetProfile (profile_name, true)
--save default keys
for key, _ in pairs(_detalhes.default_profile) do
for key, _ in pairs(Details.default_profile) do
local current_value = _detalhes [key]
local current_value = Details [key]
if (type(current_value) == "table") then
local ctable = Details.CopyTable(current_value)
@@ -529,9 +528,9 @@ function _detalhes:SaveProfile (saveas)
end
--save skins
if (not _detalhes.do_not_save_skins) then
if (not Details.do_not_save_skins) then
table.wipe(profile.instances)
for index, instance in ipairs(_detalhes.tabela_instancias) do
for index, instance in ipairs(Details.tabela_instancias) do
local exported = instance:ExportSkin()
exported.__was_opened = instance:IsEnabled()
exported.__pos = Details.CopyTable(instance:GetPosition())
@@ -542,8 +541,8 @@ function _detalhes:SaveProfile (saveas)
profile.instances[index] = exported
end
end
_detalhes.do_not_save_skins = nil
_detalhes:SaveLocalInstanceConfig()
Details.do_not_save_skins = nil
Details:SaveLocalInstanceConfig()
return profile
end
@@ -1071,7 +1070,7 @@ local default_profile = {
},
--streamer
-- _detalhes.streamer_config.
-- Details.streamer_config.
streamer_config = {
reset_spec_cache = false,
disable_mythic_dungeon = false,
@@ -1133,7 +1132,7 @@ local default_profile = {
auto_swap_to_dynamic_overall = false,
}
_detalhes.default_profile = default_profile
Details.default_profile = default_profile
-- aqui fica as propriedades do jogador que no sero armazenadas no profile
local default_player_data = {
@@ -1262,7 +1261,7 @@ local default_player_data = {
--information about this character
character_data = {logons = 0},
--version
last_realversion = _detalhes.realversion,
last_realversion = Details.realversion,
last_version = "v1.0.0",
--profile
active_profile = "",
@@ -1321,7 +1320,7 @@ local default_player_data = {
on_death_menu = false,
}
_detalhes.default_player_data = default_player_data
Details.default_player_data = default_player_data
local default_global_data = {
@@ -1407,6 +1406,42 @@ local default_global_data = {
},
},
--breakdown spell tab
breakdown_spell_tab = {
blockcontainer_width = 430,
blockcontainer_height = 270,
blockcontainer_islocked = true,
blockspell_height = 50,
blockspell_padding = 5,
blockspell_color = {0, 0, 0, 0.7},
blockspell_bordercolor = {0, 0, 0, 0.7},
blockspell_backgroundcolor = {0.1, 0.1, 0.1, 0.4},
blockspell_spark_offset = -2,
blockspell_spark_width = 2,
blockspell_spark_show = true,
blockspell_spark_color = {1, 1, 1, 0.7},
blockspellline_height = 13,
spellcontainer_width = 429,
spellcontainer_height = 311,
spellcontainer_islocked = true,
targetcontainer_width = 429,
targetcontainer_height = 140,
targetcontainer_islocked = true,
spellbar_background_alpha = 0.92,
spellcontainer_headers = {}, --store information about active headers and their sizes (spells)
targetcontainer_headers = {}, --store information about active headers and their sizes (target)
spellcontainer_header_height = 20,
spellcontainer_header_fontsize = 10,
spellcontainer_header_fontcolor = {1, 1, 1, 1},
},
--profile by spec
profile_by_spec = {},
@@ -1569,35 +1604,35 @@ local default_global_data = {
},
}
_detalhes.default_global_data = default_global_data
Details.default_global_data = default_global_data
function _detalhes:GetTutorialCVar(key, default)
function Details:GetTutorialCVar(key, default)
--is disabling all popups from the streamer options
if (_detalhes.streamer_config.no_alerts) then
if (Details.streamer_config.no_alerts) then
return true
end
local value = _detalhes.tutorial [key]
local value = Details.tutorial [key]
if (value == nil and default) then
_detalhes.tutorial [key] = default
Details.tutorial [key] = default
value = default
end
return value
end
function _detalhes:SetTutorialCVar (key, value)
_detalhes.tutorial [key] = value
function Details:SetTutorialCVar (key, value)
Details.tutorial [key] = value
end
function _detalhes:SaveProfileSpecial()
function Details:SaveProfileSpecial()
--get the current profile
local profile_name = _detalhes:GetCurrentProfileName()
local profile = _detalhes:GetProfile (profile_name, true)
local profile_name = Details:GetCurrentProfileName()
local profile = Details:GetProfile (profile_name, true)
--save default keys
for key, _ in pairs(_detalhes.default_profile) do
for key, _ in pairs(Details.default_profile) do
local current_value = _detalhes_database [key] or _detalhes_global [key] or _detalhes.default_player_data [key] or _detalhes.default_global_data [key]
local current_value = _detalhes_database [key] or _detalhes_global [key] or Details.default_player_data [key] or Details.default_global_data [key]
if (type(current_value) == "table") then
local ctable = Details.CopyTable(current_value)
@@ -1611,8 +1646,8 @@ function _detalhes:SaveProfileSpecial()
--save skins
table.wipe(profile.instances)
if (_detalhes.tabela_instancias) then
for index, instance in ipairs(_detalhes.tabela_instancias) do
if (Details.tabela_instancias) then
for index, instance in ipairs(Details.tabela_instancias) do
local exported = instance:ExportSkin()
profile.instances [index] = exported
end
@@ -1623,8 +1658,8 @@ function _detalhes:SaveProfileSpecial()
end
--save things for the mythic dungeon run
function _detalhes:SaveState_CurrentMythicDungeonRun (runID, zoneName, zoneID, startAt, segmentID, level, ejID, latestBossAt)
local savedTable = _detalhes.mythic_dungeon_currentsaved
function Details:SaveState_CurrentMythicDungeonRun (runID, zoneName, zoneID, startAt, segmentID, level, ejID, latestBossAt)
local savedTable = Details.mythic_dungeon_currentsaved
savedTable.started = true
savedTable.run_id = runID
savedTable.dungeon_name = zoneName
@@ -1636,8 +1671,8 @@ function _detalhes:SaveState_CurrentMythicDungeonRun (runID, zoneName, zoneID, s
savedTable.previous_boss_killed_at = latestBossAt
end
function _detalhes:UpdateState_CurrentMythicDungeonRun (stillOngoing, segmentID, latestBossAt)
local savedTable = _detalhes.mythic_dungeon_currentsaved
function Details:UpdateState_CurrentMythicDungeonRun (stillOngoing, segmentID, latestBossAt)
local savedTable = Details.mythic_dungeon_currentsaved
if (not stillOngoing) then
savedTable.started = false
@@ -1652,14 +1687,14 @@ function _detalhes:UpdateState_CurrentMythicDungeonRun (stillOngoing, segmentID,
end
end
function _detalhes:RestoreState_CurrentMythicDungeonRun()
function Details:RestoreState_CurrentMythicDungeonRun()
--no need to check for mythic+ if the user is playing on classic wow
if (DetailsFramework.IsTimewalkWoW()) then
return
end
local savedTable = _detalhes.mythic_dungeon_currentsaved
local savedTable = Details.mythic_dungeon_currentsaved
local mythicLevel = C_ChallengeMode.GetActiveKeystoneInfo()
local zoneName, _, _, _, _, _, _, currentZoneID = GetInstanceInfo()
local mapID = C_Map.GetBestMapForUnit ("player")
@@ -1682,21 +1717,21 @@ function _detalhes:RestoreState_CurrentMythicDungeonRun()
--is there a mythic run ongoing and the level is the same as the saved state?
if (mythicLevel and mythicLevel == savedTable.level) then
--restore the state
_detalhes.MythicPlus.Started = true
_detalhes.MythicPlus.DungeonName = zoneName
_detalhes.MythicPlus.DungeonID = currentZoneID
_detalhes.MythicPlus.StartedAt = savedTable.started_at
_detalhes.MythicPlus.SegmentID = savedTable.segment_id
_detalhes.MythicPlus.Level = mythicLevel
_detalhes.MythicPlus.ejID = ejID
_detalhes.MythicPlus.PreviousBossKilledAt = savedTable.previous_boss_killed_at
_detalhes.MythicPlus.IsRestoredState = true
Details.MythicPlus.Started = true
Details.MythicPlus.DungeonName = zoneName
Details.MythicPlus.DungeonID = currentZoneID
Details.MythicPlus.StartedAt = savedTable.started_at
Details.MythicPlus.SegmentID = savedTable.segment_id
Details.MythicPlus.Level = mythicLevel
Details.MythicPlus.ejID = ejID
Details.MythicPlus.PreviousBossKilledAt = savedTable.previous_boss_killed_at
Details.MythicPlus.IsRestoredState = true
DetailsMythicPlusFrame.IsDoingMythicDungeon = true
print("D! (debug) mythic dungeon state restored.")
C_Timer.After(2, function()
_detalhes:SendEvent("COMBAT_MYTHICDUNGEON_START")
Details:SendEvent("COMBAT_MYTHICDUNGEON_START")
end)
return
else
+2
View File
@@ -51,6 +51,8 @@
end
function Details222.Textures.SavePortraitTextureForUnitID(unitId)
if true then return end --portrait saving disabled atm
local npcId = detailsFramework:GetNpcIdFromGuid(UnitGUID(unitId) or "")
if (npcId and not Details222.Textures.GetPortraitTextureForNpcID(npcId)) then
local texture = getTextureForPortraitPool()
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

+6
View File
@@ -0,0 +1,6 @@
local L = LibStub("AceLocale-3.0"):NewLocale ("Details", "enUS", true)
if not L then return end
--------------------------------------------------------------------------------------------------------------------------------------------
@localization(locale="enUS", format="lua_additive_table")@
+5 -1
View File
@@ -15,6 +15,8 @@ function Details:StartMeUp()
end
Details.AndIWillNeverStop = true
--note: this runs after profile loaded
--set default time for arena and bg to be the Details! load time in case the client loads mid event
Details.lastArenaStartTime = GetTime()
Details.lastBattlegroundStartTime = GetTime()
@@ -77,6 +79,8 @@ function Details:StartMeUp()
Details:InitializePlaterIntegrationWindow()
Details:InitializeMacrosWindow()
Details.InitializeSpellBreakdownTab()
if (Details.ocd_tracker.show_options) then
Details:InitializeCDTrackerWindow()
end
@@ -92,7 +96,7 @@ function Details:StartMeUp()
Details.MicroButtonAlert:Hide()
--actor details window
Details.playerDetailWindow = Details.gump:CriaJanelaInfo()
Details.playerDetailWindow = Details:CreateBreakdownWindow()
Details.FadeHandler.Fader(Details.playerDetailWindow, 1)
--copy and paste window