-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathGiuiceHunterPets.lua
425 lines (354 loc) · 15.1 KB
/
GiuiceHunterPets.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
local addonName, GHP = ...
-- Initialize addon table with necessary functions
GHP.utils = {}
GHP.frames = {}
-- Check for Hunter class first
if (select(3, UnitClass("player")) ~= 3) then return end
-- Check for required libraries
assert(LibStub, "GiuiceHunterPets requires LibStub")
local LDB = LibStub:GetLibrary("LibDataBroker-1.1", true)
assert(LDB, "GiuiceHunterPets requires LibDataBroker-1.1")
local LibDBIcon = LibStub:GetLibrary("LibDBIcon-1.0", true)
assert(LibDBIcon, "GiuiceHunterPets requires LibDBIcon-1.0")
local backgroundForPetSpec = {
[STABLE_PET_SPEC_CUNNING] = "hunter-stable-bg-art_cunning",
[STABLE_PET_SPEC_FEROCITY] = "hunter-stable-bg-art_ferocity",
[STABLE_PET_SPEC_TENACITY] = "hunter-stable-bg-art_tenacity",
};
-- Create the LibDataBroker object
local minimapLDB = LDB:NewDataObject("GiuiceHunterPets", {
type = "launcher",
icon = "Interface\\Icons\\Ability_Hunter_Pet_Devilsaur",
OnClick = function(self, button)
if button == "LeftButton" then
if GHP.frames.mainFrame:IsShown() then
GHP.frames.mainFrame:Hide()
else
GHP.frames.mainFrame:Show()
GHP.utils.UpdatePetList(GHP.frames.mainFrame)
end
elseif button == "RightButton" then
Settings.OpenToCategory(GHP.category_id)
end
end,
OnTooltipShow = function(tooltip)
tooltip:AddLine("GiuiceHunterPets", 1, 0.82, 0)
tooltip:AddLine("Left Click: Toggle pet window", 1, 1, 1)
tooltip:AddLine("Right Click: Open settings", 1, 1, 1)
end,
})
-- Function to initialize minimap button
local function InitializeMinimapButton()
LibDBIcon:Register("GiuiceHunterPets", minimapLDB, GHP_SavedVars.minimap)
end
local function CreateMainFrame()
local frame = CreateFrame("Frame", "GiuiceHunterPetsFrame", UIParent, "PortraitFrameTemplate")
frame:SetSize(1200, 700)
frame:SetFrameStrata("HIGH")
frame:EnableMouse(true)
frame:SetMovable(true)
-- Set saved position or default
if GHP_SavedVars.position then
frame:SetPoint(unpack(GHP_SavedVars.position))
else
frame:SetPoint("CENTER")
end
-- Add hunter icon
frame.portraitIcon = "Interface\\Icons\\ClassIcon_Hunter"
-- Portrait and title (correct method)
SetPortraitToTexture(frame.PortraitContainer.portrait, "Interface\\Icons\\ClassIcon_Hunter")
-- Title text
frame.TitleContainer.TitleText:SetText("Giuice's hunter pets viewer")
-- Movement handling
frame:RegisterForDrag("LeftButton")
frame:SetScript("OnDragStart", frame.StartMoving)
frame:SetScript("OnDragStop", function(self)
self:StopMovingOrSizing()
local point, relativeTo, relativePoint, xOfs, yOfs = self:GetPoint()
GHP_SavedVars.position = { point, relativeTo, relativePoint, xOfs, yOfs }
end)
local titleBar = CreateFrame("Frame", nil, frame)
titleBar:SetHeight(24)
titleBar:SetPoint("TOPLEFT", 0, 0)
titleBar:SetPoint("TOPRIGHT", 0, 0)
-- Create detail panel on right side
local detailPanel = CreateFrame("Frame", nil, frame, BackdropTemplateMixin and "BackdropTemplate")
detailPanel:SetPoint("TOPLEFT", 450, -32)
detailPanel:SetPoint("BOTTOMRIGHT", -8, 8)
detailPanel:SetBackdrop({
bgFile = "Interface/Tooltips/UI-Tooltip-Background",
edgeFile = "Interface/Tooltips/UI-Tooltip-Border",
edgeSize = 16,
insets = { left = 4, right = 4, top = 4, bottom = 4 }
})
detailPanel:SetBackdropColor(0.1, 0.1, 0.1, 0.8)
-- Search container frame for better organization
local searchContainer = CreateFrame("Frame", nil, frame)
searchContainer:SetHeight(30) -- Height for search elements
searchContainer:SetPoint("TOPLEFT", titleBar, "BOTTOMLEFT", 0, 0)
searchContainer:SetPoint("TOPRIGHT", titleBar, "BOTTOMRIGHT", 0, 0)
-- Search box
local searchBox = CreateFrame("EditBox", nil, searchContainer, "SearchBoxTemplate")
searchBox:SetSize(200, 20)
searchBox:SetPoint("TOPLEFT", titleBar, "BOTTOMLEFT", 65, -5)
searchBox:SetAutoFocus(false)
searchBox:SetMaxLetters(50)
searchBox:SetScript("OnTextChanged", function(self)
GHP.utils.UpdatePetList(frame, self:GetText())
end)
-- Search options dropdown
local Dropdown = CreateFrame("DropdownButton", "GiuiceHunterPetsSearchOptions", searchContainer, "WowStyle1DropdownTemplate")
Dropdown:SetDefaultText("Name")
Dropdown:SetPoint("LEFT", searchBox, "RIGHT", 0, -2)
local searchType = "name" -- Default search type
Dropdown:SetupMenu(function(dropdown, rootDescription)
rootDescription:CreateTitle("Search Options")
rootDescription:CreateButton("Name", function()
searchType = "name"
Dropdown:SetDefaultText("Name")
GHP.utils.UpdatePetList(frame, searchBox:GetText())
end)
rootDescription:CreateButton("Family", function()
searchType = "family"
Dropdown:SetDefaultText("Family")
GHP.utils.UpdatePetList(frame, searchBox:GetText())
end)
rootDescription:CreateButton("Level", function()
searchType = "level"
Dropdown:SetDefaultText("Level")
GHP.utils.UpdatePetList(frame, searchBox:GetText())
end)
end)
-- Scroll frame
local scrollFrame = CreateFrame("ScrollFrame", nil, frame, "UIPanelScrollFrameTemplate")
scrollFrame:SetPoint("TOPLEFT", searchContainer, "BOTTOMLEFT", 8, -8)
scrollFrame:SetPoint("BOTTOMRIGHT", 450 - 14, 8)
-- Scroll child adjustment
local scrollChild = CreateFrame("Frame")
scrollFrame:SetScrollChild(scrollChild)
scrollChild:SetSize(450 - 36, 1)
frame.searchBox = searchBox
frame.searchType = function() return searchType end
-- Save position when frame stops moving
frame:SetScript("OnDragStop", function(self)
self:StopMovingOrSizing()
-- Save position
local point, relativeTo, relativePoint, xOfs, yOfs = self:GetPoint()
GHP_SavedVars.position = { point, relativeTo, relativePoint, xOfs, yOfs }
end)
frame.scrollChild = scrollChild
frame.detailPanel = detailPanel
frame:Hide()
GHP.frames.mainFrame = frame
return frame
end
function GHP.utils.CreatePetEntry(scrollChild, petInfo)
local petContainer = CreateFrame("Button", nil, scrollChild, "GiuiceHunterPetListItemTemplate")
petContainer:SetPetInfo(petInfo)
return petContainer
end
-- Function to update pet list
function GHP.utils.UpdatePetList(frame, searchText)
local scrollChild = frame.scrollChild
-- Clear existing contents
for _, child in pairs({ scrollChild:GetChildren() }) do
child:Hide()
child:SetParent(nil)
end
-- Get both stabled and active pets
local stabledPets = C_StableInfo.GetStabledPetList() --GHP.utils.GetAllPets()
if not stabledPets then
print("No pets in stable.")
return
end
-- Filter pets based on search
local filteredPets = stabledPets
if searchText and searchText ~= "" then
searchText = searchText:lower()
filteredPets = {}
local searchType = frame.searchType()
for _, pet in ipairs(stabledPets) do
local match = false
if searchType == "name" then
match = pet.name:lower():find(searchText, 1, true) ~= nil
elseif searchType == "family" then
match = pet.familyName:lower():find(searchText, 1, true) ~= nil
elseif searchType == "level" then
match = tostring(pet.level):find(searchText, 1, true) ~= nil
end
if match then
table.insert(filteredPets, pet)
end
end
end
local previousElement
local totalHeight = 0
for index, petInfo in ipairs(filteredPets) do
local petContainer = GHP.utils.CreatePetEntry(scrollChild, petInfo) --CreateFrame("Frame", nil, scrollChild, BackdropTemplateMixin and "BackdropTemplate")
petContainer:SetSize(scrollChild:GetWidth() - 8, 70)
if previousElement then
petContainer:SetPoint("TOPLEFT", previousElement, "BOTTOMLEFT", 0, -2)
else
petContainer:SetPoint("TOPLEFT", 0, 0)
end
previousElement = petContainer
end
-- Auto-select the first pet if available
if #filteredPets > 0 then
GHP.utils.ShowPetDetails(GHP.frames.mainFrame.detailPanel, filteredPets[1])
end
scrollChild:SetHeight(math.max(totalHeight, frame:GetHeight()))
end
function GHP.utils.ShowPetDetails(detailPanel, petInfo)
-- Clear previous content
for _, child in pairs({ detailPanel:GetChildren() }) do
child:Hide()
child:SetParent(nil)
end
local modelViewer = CreateFrame("ModelScene", nil, detailPanel, "PanningModelSceneMixinTemplate")
modelViewer:SetPoint("TOPLEFT", detailPanel, "TOPLEFT", 20, -20)
modelViewer:SetPoint("BOTTOMRIGHT", detailPanel, "BOTTOMRIGHT", -20, 20)
-- Add abilities list header
local header = modelViewer:CreateFontString(nil, "OVERLAY", "GameFontNormalHuge2")
header:SetPoint("TOPLEFT", modelViewer, "TOPLEFT", 20, -20)
header:SetText(STABLE_PET_ABILITIES_LIST_HEADER)
header:GetShadowOffset()
-- Create abilities list
if petInfo.abilities and #petInfo.abilities > 0 then
local lastAbility
for i, abilityID in ipairs(petInfo.abilities) do
local ability = CreateFrame("Frame", nil, modelViewer)
ability:SetSize(250, 22)
if i == 1 then
ability:SetPoint("TOPLEFT", header, "BOTTOMLEFT", 0, -4)
else
ability:SetPoint("TOPLEFT", lastAbility, "BOTTOMLEFT", 0, -4)
end
-- Create icon texture
local icon = ability:CreateTexture(nil, "ARTWORK")
icon:SetSize(22, 22)
icon:SetPoint("LEFT", 0, 0)
local spellInfo = C_Spell.GetSpellInfo(abilityID)
icon:SetTexture(spellInfo.iconID)
-- Create name text
local name = ability:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
name:SetPoint("LEFT", icon, "RIGHT", 8, 0)
name:SetText(spellInfo.name)
name:SetJustifyH("LEFT")
-- Setup tooltip
ability:EnableMouse(true)
ability:SetScript("OnEnter", function()
GameTooltip:SetOwner(ability, "ANCHOR_RIGHT")
GameTooltip:SetSpellByID(abilityID)
GameTooltip:Show()
end)
ability:SetScript("OnLeave", function()
GameTooltip:Hide()
end)
lastAbility = ability
end
end
-- Add basic info below abilities
local infoContainer = CreateFrame("Frame", nil, modelViewer)
infoContainer:SetPoint("TOPLEFT", header, "BOTTOMLEFT", 0, -150) -- Adjust spacing as needed
infoContainer:SetSize(250, 200)
-- Add pet info
local function AddInfoLine(label, value, previousLine)
local container = CreateFrame("Frame", nil, infoContainer)
container:SetHeight(20)
if previousLine then
container:SetPoint("TOPLEFT", previousLine, "BOTTOMLEFT", 0, -5)
else
container:SetPoint("TOPLEFT", infoContainer, "TOPLEFT")
end
container:SetWidth(250)
local labelText = container:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
labelText:SetPoint("LEFT")
labelText:SetText(label .. ":")
labelText:SetTextColor(0.8, 0.8, 0.8)
local valueText = container:CreateFontString(nil, "OVERLAY", "GameFontHighlightSmall")
valueText:SetPoint("LEFT", labelText, "RIGHT", 5, 0)
valueText:SetText(value)
return container
end
local lastLine = AddInfoLine("Family", petInfo.familyName)
lastLine = AddInfoLine("Specialization", petInfo.specialization, lastLine)
lastLine = AddInfoLine("Diet", table.concat(C_StableInfo.GetStablePetFoodTypes(petInfo.slotID), ", "), lastLine)
lastLine = AddInfoLine("Status", petInfo.isExotic and "Exotic" or "Normal", lastLine)
-- Add background layer
local background = modelViewer:CreateTexture(nil, "BACKGROUND")
background:SetPoint("TOPLEFT")
background:SetPoint("BOTTOMRIGHT")
background:SetAtlas(backgroundForPetSpec[petInfo.specialization] or "hunter-stable-bg-art_cunning")
background:SetAlpha(0.8)
-- Add pet shadow
local shadow = modelViewer:CreateTexture(nil, "ARTWORK")
shadow:SetAtlas("perks-char-shadow")
shadow:SetAlpha(0.6)
shadow:SetSize(410, 90)
shadow:SetPoint("CENTER", modelViewer, "CENTER", -8, -145)
-- Setup model scene with proper camera
local forceSceneChange = true
modelViewer:TransitionToModelSceneID(petInfo.uiModelSceneID, CAMERA_TRANSITION_TYPE_IMMEDIATE, CAMERA_MODIFICATION_TYPE_DISCARD, forceSceneChange)
-- Create and setup the actor
local actor = modelViewer:GetActorByTag("pet")
if not actor then
actor = modelViewer:CreateActorByTag("pet")
end
if actor then
actor:SetModelByCreatureDisplayID(petInfo.displayID)
actor:SetSpellVisualKit(0)
actor:Show()
end
-- Add control frame
local controlFrame = CreateFrame("Frame", nil, modelViewer, "ModelSceneControlFrameTemplate")
controlFrame:SetPoint("BOTTOM", modelViewer, "BOTTOM", 0, 90)
controlFrame:SetModelScene(modelViewer)
-- Set up mouse wheel zoom
modelViewer:SetScript("OnMouseWheel", function(self, delta)
local zoomChange = delta * 0.5
local actorScale = actor:GetScale()
actorScale = math.max(0.1, math.min(3.0, actorScale + zoomChange))
actor:SetScale(actorScale)
end)
-- Create the active pets list using the template
if not modelViewer.activePetList then
modelViewer.activePetList = CreateFrame("Frame", nil, detailPanel, "GiuiceHunterActivePetListTemplate");
modelViewer.activePetList:SetPoint("TOPLEFT", modelViewer, "BOTTOMLEFT", 0, 45);
modelViewer.activePetList:SetPoint("TOPRIGHT", modelViewer, "BOTTOMRIGHT", 0, 45);
end
modelViewer.activePetList:Refresh();
end
-- Create and initialize the addon
local function InitializeAddon()
local mainFrame = CreateMainFrame()
InitializeMinimapButton()
-- Event handling
local eventFrame = CreateFrame("Frame")
eventFrame:RegisterEvent("PET_STABLE_SHOW")
eventFrame:RegisterEvent("PET_STABLE_UPDATE")
eventFrame:SetScript("OnEvent", function(self, event)
if mainFrame:IsShown() then
GHP.utils.UpdatePetList(mainFrame)
end
end)
-- Slash command
SLASH_HUNTERPETLIST1 = "/hunterpets"
SlashCmdList["HUNTERPETLIST"] = function()
if mainFrame:IsShown() then
mainFrame:Hide()
else
mainFrame:Show()
GHP.utils.UpdatePetList(mainFrame)
end
end
end
-- Register for ADDON_LOADED
local eventFrame = CreateFrame("Frame")
eventFrame:RegisterEvent("ADDON_LOADED")
eventFrame:SetScript("OnEvent", function(self, event, loadedAddonName)
if loadedAddonName == addonName then
InitializeAddon()
print("GiuiceHunterPets loaded successfully!")
end
end)