-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathspud.lua
337 lines (289 loc) · 10.9 KB
/
spud.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
-- Create addon namespace
local addonName, Spud = ...
Spud = Spud or {}
-- Move all our variables into the namespace
Spud.playerKills = {}
Spud.totalKills = 0
Spud.currentCombatDamage = {}
Spud.currentTarget = nil
Spud.playerLoot = {}
Spud.totalLoot = 0
-- Localization table
Spud.L = Spud.L or {}
local L = Spud.L
-- Default English strings
L["NO_KILLS"] = "No kills have been made yet."
L["NO_LOOT"] = "No loot has been collected yet."
L["RESET_MESSAGE"] = "Statistics have been reset."
L["HELP_HEADER"] = "Spud Commands:"
L["USAGE_WHISPER"] = "Usage: /spudwhisper <player>"
L["VERSION"] = "Spud Version %s"
-- define a function to reset the kill counts
local function resetCounts()
-- Reset kill counts
for playerName in pairs(Spud.playerKills) do
Spud.playerKills[playerName] = 0
end
Spud.totalKills = 0
-- Reset loot counts
for playerName in pairs(Spud.playerLoot) do
Spud.playerLoot[playerName] = 0
end
Spud.totalLoot = 0
print(L["RESET_MESSAGE"])
end
-- define a function to generate a kill count message
local function generateKillCountMessage(playerName, killCount)
if Spud.totalKills == 0 then
return string.format("%s has killed %d enemies.", playerName, killCount)
end
local percentage = (killCount / Spud.totalKills) * 100
return string.format("%s has killed %d enemies (%.2f%% of total).", playerName, killCount, percentage)
end
-- define a function to generate loot message
local function generateLootMessage(playerName, lootAmount)
if Spud.totalLoot == 0 then
return string.format("%s has looted %d copper.", playerName, lootAmount)
end
local percentage = (lootAmount / Spud.totalLoot) * 100
return string.format("%s has looted %d copper (%.2f%% of total).", playerName, lootAmount, percentage)
end
-- define our function that handles the event
local function eventHandler(self, event)
if event == "COMBAT_LOG_EVENT_UNFILTERED" then
local _, subevent, _, srcGUID, _, _, _, destGUID, destName, dstFlags = CombatLogGetCurrentEventInfo()
-- Track damage events
if subevent == "DAMAGE_SHIELD" or subevent == "DAMAGE_SPLIT" or subevent == "RANGE_DAMAGE" or subevent == "SPELL_DAMAGE" or subevent == "SPELL_PERIODIC_DAMAGE" or subevent == "SWING_DAMAGE" then
local amount = select(subevent == "SWING_DAMAGE" and 12 or 15, CombatLogGetCurrentEventInfo())
-- Initialize damage tracking for this target
if not Spud.currentCombatDamage[destGUID] then
Spud.currentCombatDamage[destGUID] = {}
end
-- Add damage to player's total
if srcGUID then
local playerName = select(6, GetPlayerInfoByGUID(srcGUID))
if playerName then
Spud.currentCombatDamage[destGUID][playerName] = (Spud.currentCombatDamage[destGUID][playerName] or 0) + amount
end
end
end
-- Handle kills
if subevent == "PARTY_KILL" then
local isNPC = bit.band(dstFlags, COMBATLOG_OBJECT_TYPE_NPC) > 0
if isNPC and destGUID and Spud.currentCombatDamage[destGUID] then
-- Calculate damage percentages and update kill counts
local totalDamage = 0
for _, damage in pairs(Spud.currentCombatDamage[destGUID]) do
totalDamage = totalDamage + damage
end
-- Update kill counts based on damage contribution
for playerName, damage in pairs(Spud.currentCombatDamage[destGUID]) do
local contribution = damage / totalDamage
if not Spud.playerKills[playerName] then
Spud.playerKills[playerName] = 0
end
Spud.playerKills[playerName] = Spud.playerKills[playerName] + contribution
Spud.totalKills = Spud.totalKills + contribution
end
-- Clear damage tracking for this target
Spud.currentCombatDamage[destGUID] = nil
end
end
-- Handle loot events
if subevent == "LOOT_MONEY" then
if srcGUID then
local playerName = select(6, GetPlayerInfoByGUID(srcGUID))
if playerName then
local amount = select(13, CombatLogGetCurrentEventInfo())
if not Spud.playerLoot[playerName] then
Spud.playerLoot[playerName] = 0
end
Spud.playerLoot[playerName] = Spud.playerLoot[playerName] + amount
Spud.totalLoot = Spud.totalLoot + amount
end
end
end
if SpudStatsFrame and SpudStatsFrame:IsShown() then
UpdateStats(SpudStatsFrame)
end
end
end
-- define our slash commands
SLASH_SPUD1 = "/spud"
SlashCmdList["SPUD"] = function(msg)
local hasKills = false
for playerName, killCount in pairs(Spud.playerKills) do
hasKills = true
print(generateKillCountMessage(playerName, killCount))
end
if not hasKills then
print(L["NO_KILLS"])
end
end
SLASH_SPUDSHARE1 = "/spudshare"
SlashCmdList["SPUDSHARE"] = function(msg)
local hasKills = false
for playerName, killCount in pairs(Spud.playerKills) do
hasKills = true
SendChatMessage(generateKillCountMessage(playerName, killCount), "PARTY")
end
if not hasKills then
SendChatMessage(L["NO_KILLS"], "PARTY")
end
end
SLASH_SPUDRESET1 = "/spudreset"
SlashCmdList["SPUDRESET"] = resetCounts
SLASH_SPUDWHISPER1 = "/spudwhisper"
SlashCmdList["SPUDWHISPER"] = function(msg)
-- Check if a player name was provided
if msg and msg:trim() ~= "" then
local targetPlayer = msg:trim()
local hasKills = false
-- Send kill counts via whisper
for playerName, killCount in pairs(Spud.playerKills) do
hasKills = true
SendChatMessage(generateKillCountMessage(playerName, killCount), "WHISPER", nil, targetPlayer)
end
if not hasKills then
SendChatMessage(L["NO_KILLS"], "WHISPER", nil, targetPlayer)
end
else
print("Usage: /spudwhisper <player>")
end
end
SLASH_SPUDHELP1 = "/spudhelp"
SlashCmdList["SPUDHELP"] = function(msg)
print(string.format(L["VERSION"], GetAddOnMetadata("Spud", "Version")))
print(L["HELP_HEADER"])
print(" /spud - List current session's kill counts")
print(" /spudshare - Share kill counts with party")
print(" /spudwhisper <player> - Whisper kill counts to player")
print(" /spudreset - Reset all statistics")
print(" /spudloot - List current session's loot statistics")
print(" /spudlootshare - Share loot statistics with party")
print(" /spudlootwhisper <player> - Whisper loot statistics to player")
print(" /spudhelp - Show this help message")
print(" /spudwindow - Toggle stats window display")
end
SLASH_SPUDRESETALL1 = "/spudresetall"
SlashCmdList["SPUDRESETALL"] = function(msg)
-- Reset current session counts
resetCounts()
-- TODO: When persistent storage is implemented, this will also clear stored counts for all characters
print(L["RESET_MESSAGE"])
end
SLASH_SPUDLOOT1 = "/spudloot"
SlashCmdList["SPUDLOOT"] = function(msg)
local hasLoot = false
for playerName, lootAmount in pairs(Spud.playerLoot) do
hasLoot = true
print(generateLootMessage(playerName, lootAmount))
end
if not hasLoot then
print("No loot has been collected yet.")
end
end
SLASH_SPUDLOOTSHARE1 = "/spudlootshare"
SlashCmdList["SPUDLOOTSHARE"] = function(msg)
local hasLoot = false
for playerName, lootAmount in pairs(Spud.playerLoot) do
hasLoot = true
SendChatMessage(generateLootMessage(playerName, lootAmount), "PARTY")
end
if not hasLoot then
SendChatMessage(L["NO_LOOT"], "PARTY")
end
end
SLASH_SPUDLOOTWHISPER1 = "/spudlootwhisper"
SlashCmdList["SPUDLOOTWHISPER"] = function(msg)
if msg and msg:trim() ~= "" then
local targetPlayer = msg:trim()
local hasLoot = false
for playerName, lootAmount in pairs(Spud.playerLoot) do
hasLoot = true
SendChatMessage(generateLootMessage(playerName, lootAmount), "WHISPER", nil, targetPlayer)
end
if not hasLoot then
SendChatMessage(L["NO_LOOT"], "WHISPER", nil, targetPlayer)
end
else
print(L["USAGE_WHISPER"])
end
end
-- Add to the existing slash commands section
SLASH_UNTAMEDBEASTMODE1 = "/untamedbeastmode"
SlashCmdList["UNTAMEDBEASTMODE"] = function(msg)
-- Override the kill count message generator temporarily
local originalGenerator = generateKillCountMessage
generateKillCountMessage = function(playerName, killCount)
if Spud.totalKills == 0 then
return string.format("%s *RAWRS* %d *GROWLS*", playerName, killCount)
end
local percentage = (killCount / Spud.totalKills) * 100
return string.format("%s has *SAVAGELY MAULED* %d prey (*FEROCIOUSLY* %d%% of the hunt)",
playerName, killCount, percentage)
end
-- Reset after 30 seconds
C_Timer.After(30, function()
generateKillCountMessage = originalGenerator
print("The beast has been tamed... for now...")
end)
print("*UNLEASHING PRIMAL FURY* - Messages are now more... bestial... for 30 seconds")
end
-- create frame and register event
local frame = CreateFrame("Frame")
frame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
frame:SetScript("OnEvent", eventHandler)
-- initialize kill counts
resetCounts()
-- Create the main frame
local function CreateStatsFrame()
local frame = CreateFrame("Frame", "SpudStatsFrame", UIParent, "BasicFrameTemplateWithInset")
frame:SetSize(300, 400)
frame:SetPoint("CENTER")
frame:SetMovable(true)
frame:EnableMouse(true)
frame:RegisterForDrag("LeftButton")
frame:SetScript("OnDragStart", frame.StartMoving)
frame:SetScript("OnDragStop", frame.StopMovingOrSizing)
-- Add title
frame.title = frame:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
frame.title:SetPoint("TOP", 0, -5)
frame.title:SetText("Spud Stats")
-- Add scrolling content frame
local scrollFrame = CreateFrame("ScrollFrame", nil, frame, "UIPanelScrollFrameTemplate")
scrollFrame:SetPoint("TOPLEFT", 8, -30)
scrollFrame:SetPoint("BOTTOMRIGHT", -30, 8)
local content = CreateFrame("Frame", nil, scrollFrame)
content:SetSize(scrollFrame:GetSize())
scrollFrame:SetScrollChild(content)
frame.content = content
frame:Hide()
return frame
end
-- Update the stats display
local function UpdateStats(frame)
local content = frame.content
local yOffset = 0
-- Clear existing fontstrings
for _, child in pairs({content:GetChildren()}) do
child:Hide()
end
-- Add kill stats
for playerName, killCount in pairs(Spud.playerKills) do
local text = content:CreateFontString(nil, "OVERLAY", "GameFontNormal")
text:SetPoint("TOPLEFT", 10, -yOffset)
text:SetText(generateKillCountMessage(playerName, killCount))
yOffset = yOffset + 20
end
-- Add spacing
yOffset = yOffset + 20
-- Add loot stats
for playerName, lootAmount in pairs(Spud.playerLoot) do
local text = content:CreateFontString(nil, "OVERLAY", "GameFontNormal")
text:SetPoint("TOPLEFT", 10, -yOffset)
text:SetText(generateLootMessage(playerName, lootAmount))
yOffset = yOffset + 20
end
content:SetHeight(yOffset)
end