@@ -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}
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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"/>
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
@@ -451,7 +451,7 @@ function segmentClass:resetar_overall()
|
||||
-- _detalhes.schedule_remove_overall = true
|
||||
--else
|
||||
--fecha a janela de informa��es 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 informa��es do jogador
|
||||
Details:FechaJanelaInfo()
|
||||
Details:CloseBreakdownWindow()
|
||||
|
||||
--empty temporary tables
|
||||
Details.atributo_damage:ClearTempTables()
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
+462
-2475
File diff suppressed because it is too large
Load Diff
@@ -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
@@ -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
|
||||
|
||||
@@ -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)
|
||||
@@ -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,
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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 n�o ser�o 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
|
||||
|
||||
@@ -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 |
@@ -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
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user