From e5ccf5cfb5f62c15118b6e1512de73ceff5f6fc6 Mon Sep 17 00:00:00 2001 From: Leonetienne Date: Sat, 27 May 2023 22:26:55 +0200 Subject: [PATCH] feat: add funny hurt sound, improved tracking, and added milestone announcements --- Trackster.toc | 3 +- av-texts.lua | 114 ++++++++++++++++++++++++++ hurt.wav | Bin 0 -> 32372 bytes main.lua | 215 +++++++++++++++++++++++++++++++++++++++++--------- 4 files changed, 295 insertions(+), 37 deletions(-) create mode 100644 av-texts.lua create mode 100644 hurt.wav diff --git a/Trackster.toc b/Trackster.toc index ca1826a..605e21d 100644 --- a/Trackster.toc +++ b/Trackster.toc @@ -5,7 +5,7 @@ ## Version: 1.2 # Stats stated here are saved per character. -## SavedVariablesPerCharacter: Trackster_jumpCounter, Trackster_critCounter, Trackster_questCounter, Trackster_castCounter, Trackster_loginCounter, Trackster_bossCounter, Trackster_chatCounter, Trackster_itemCounter, Trackster_goldCounter, Trackster_distanceTravelledCounter, Trackster_distanceTravelledCounter__swam, Trackster_distanceTravelledCounter__walked, Trackster_distanceTravelledCounter__groundmount, Trackster_distanceTravelledCounter__flight, Trackster_distanceTravelledCounter__taxi, Trackster_distanceTravelledCounter__ghost +## SavedVariablesPerCharacter: Trackster_jumpCounter, Trackster_critCounter, Trackster_questCounter, Trackster_killCounter, Trackster_castCounter, Trackster_loginCounter, Trackster_bossCounter, Trackster_chatCounter, Trackster_itemCounter, Trackster_goldCounter, Trackster_distanceTravelledCounter, Trackster_distanceTravelledCounter__swam, Trackster_distanceTravelledCounter__walked, Trackster_distanceTravelledCounter__groundmount, Trackster_distanceTravelledCounter__flight, Trackster_distanceTravelledCounter__taxi, Trackster_distanceTravelledCounter__ghost # Stats stated here are saved for the whole wow client. @@ -18,5 +18,6 @@ # These are internal values. Just don't touch those. ## SavedVariablesPerCharacter: Trackster_showMainframe, Trackster_frameScale +av-texts.lua main.lua options.lua diff --git a/av-texts.lua b/av-texts.lua new file mode 100644 index 0000000..a5a9e6e --- /dev/null +++ b/av-texts.lua @@ -0,0 +1,114 @@ +local hour = 3600; +local day = 24*hour; +local week = 7*day; +local month = 30*day; +local year = 360*day; +local km = 1000; + +Trackster_avMessages = { + quests = { + [1] = "First quest completed!", + [10] = "Completed ten quests", + [69] = "69 quests. Nice!", + [100] = "Completed 100 quests", + [420] = "Completed 420 quests! Smoke them Druid TIER-1 set pieces!", + [1000] = "Completed 1000 quests, that's a lot of quests!", + [9999] = "9,999 Quests! Go get the Champagne! Just one more to go!", + [10000] = "10,000 quests! POP! CLING CLING! CONGRATULATIONS!", + }, + kills = { + [1] = "First blood", + [10] = "Serial killer", + [69] = "69 kills. Nice!", + [100] = "Tenfold serial killer", + [420] = "420 kills! Smoke 'em", + [1000] = "Thousand kills!", + [2000] = "Thousands of kills!", + [10000] = "Tenfold thousandkiller! 10k kills!", + [25000] = "25k kills! Quarter of a Kilohectakill", + [50000] = "Fiftyfold thousandkiller! Half of a Kilohectakill!", + [75000] = "75k kills! Three quarters to a Kilohectakill!", + [100000] = "100k kills! Kilohectakiller!", + [110000] = "110k kills! Kilohectakill + Kilodecakill!", + [120000] = "120k kills! Kilohectakill + 2 Kilodecakills!", + [130000] = "130k kills! Kilohectakill + 3 Kilodecakills!", + [140000] = "140k kills! Kilohectakill + 4 Kilodecakills!", + [150000] = "150k kills! Kilohectakill + 5 Kilodecakills!", + [250000] = "500k kills! That's a quarter Megakill! Wtf!", + [500000] = "500k kills! That's half a Megakill! Wtf!", + [750000] = "750k kills! That's a three-quarter Megakill! Wtf!", + [1000000] = "ONE MILLION KILLS! THAT'S A MEGAKILL!", + [1000000000] = "GIGAKILLER!!!!", + }, + deaths = { + [1] = "You died!", + [10] = "Died ten times", + [69] = "69 Deaths! Death by snu-snu!", + [100] = "Died a hundred deaths!", + [200] = "Died two-hundred deaths!", + [300] = "Died three-hundred deaths!", + [400] = "Died four-hundred deaths!", + [420] = "420 deaths! Overdosed? Is that even possible?", + [500] = "Died five-hundred deaths!", + [600] = "Died six-hundred deaths!", + [700] = "Died seven-hundred deaths!", + [800] = "Died eight-hundred deaths!", + [900] = "Died nine-hundred deaths!", + [1000] = "Died a thousand deaths!", + }, + timePlayed = { + [hour] = "Played for an hour!", + [10 * hour] = "Played for ten hours!", + [100 * hour] = "Played a hundred hours!", + [200 * hour] = "Played for two-hundred hours!", + [300 * hour] = "Played for three-hundred hours!", + [400 * hour] = "Played for four-hundred hours!", + [500 * hour] = "Played for five-hundred hours!", + [600 * hour] = "Played for six-hundred hours!", + [700 * hour] = "Played for seven-hundred hours!", + [800 * hour] = "Played for eight-hundred hours!", + [900 * hour] = "Played for nine-hundred hours!", + [1000 * hour] = "Played for a thousand hours!!!", + [8 * hour] = "Played for a workday!", + [day] = "Played for an entire day!", + [week] = "Played for an entire week!", + [2 * week] = "Played for two weeks!", + [3 * week] = "Played for three weeks!", + [4 * week] = "Played for four weeks!", + [5 * week] = "Played for five weeks!", + [6 * week] = "Played for six weeks!", + [7 * week] = "Played for seven weeks!", + [9 * week] = "Played for nine weeks!", + [10 * week] = "Played for ten weeks!", + [month] = "Played for an entire month!", + [2 * month] = "Played for two months!", + [3 * month] = "Played a quarter year!", + [4 * month] = "Played for four months!", + [5 * month] = "Played for five months!", + [6 * month] = "Played half a year!", + [7 * month] = "Played for seven months!", + [9 * month] = "Played for three quartals of a year!", + [10 * month] = "Played for ten months!", + [11 * month] = "Played for eleven months!", + [year] = "Played for an entire year! This should not even be possible!", + }, + distAll = { + [2440 * 2 * km] = "Travelled the equivalent of the diameter of Mercury (" .. 2440 * 2 .. "km)", + [6052 * 2 * km] = "Travelled the equivalent of the diameter of Venus (" .. 6052 * 2 .. "km)", + [6371 * 2 * km] = "Travelled the equivalent of the diameter of the Earth (" .. 6371 * 2 .. "km)", + [3390 * 2 * km] = "Travelled the equivalent of the diameter of Mars (" .. 3390 * 2 .. "km)", + [69911 * 2 * km] = "Travelled the equivalent of the diameter of Jupiter (" .. 69911 * 2 .. "km)", + [58232 * 2 * km] = "Travelled the equivalent of the diameter of Saturn (" .. 58232 * 2 .. "km)", + [25362 * 2 * km] = "Travelled the equivalent of the diameter of Uranus (" .. 25362 * 2 .. "km)", + [24622 * 2 * km] = "Travelled the equivalent of the diameter of Neptune (" .. 24622 * 2 .. "km)", + [40075 * km] = "Travelled the equivalent of the the Earths circumference (" .. 40075 .. "km)", + [20032 * km] = "Travelled the equivalent of HALF the the Earths circumference (" .. 20032 .. "km)", + [22860 * km] = "Travelled the equivalent 250,000 football fields (" .. 22860 .. "km)", + [45720 * km] = "Travelled the equivalent 500,000 football fields (" .. 45720 .. "km)", + [29412765] = "Travelled 50,000 smoots (" .. 29412.765 .. "km)", + }, + distWalked = { + [804 * km] = "And I would walk five hundred miles...", + [804 * 2 * km] = "... And I would walk five hundred more", + }, +} diff --git a/hurt.wav b/hurt.wav new file mode 100644 index 0000000000000000000000000000000000000000..0f30176cb6b58e5086d4b81aabfa36b086b7a03a GIT binary patch literal 32372 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 ZwOk9^&!c~Ac>b@>ZK0*^!smtO_&-sFc5nay literal 0 HcmV?d00001 diff --git a/main.lua b/main.lua index 607a291..f234261 100644 --- a/main.lua +++ b/main.lua @@ -15,6 +15,7 @@ Trackster_chatCounter = 0; Trackster_itemCounter = 0; Trackster_goldCounter = 0; Trackster_questCounter = 0; +Trackster_killCounter = 0; Trackster_distanceTravelledCounter = 0; Trackster_distanceTravelledCounter__swam = 0; Trackster_distanceTravelledCounter__walked = 0; @@ -145,6 +146,130 @@ local function PrintMsg(s) print("|cFFFFD044Trackster:|r " .. s); end +--> Will play a sound and display a string on screen +local function AnnounceMilestone(message) + --> Play a nice sound --> https://www.wowhead.com/sound=63971/ui-legendaryloot-toast + PlaySound(63971); + --> Announce the message on screen + UIErrorsFrame:AddMessage(message, 1.0, 1.0, 0.0, 1.0, UIERRORS_HOLD_TIME) + --> Announce in chat + PrintMsg(message); +end + +--> Will call AnnounceMilestone automatically, each time value is a multiple of interval, or explicitly defined in avMessages +--> Only use for integer, steady, individually incremented values! +--> Meaning, they are integers, never decrease in value, and call this method for every single increment, and every increment must be by 1! +local function AutoAnnounceMilestone_INT_STEADY_IINCR(value, kindkey, prettyName, interval) + if (value > 0) then + --> If a multiple of interval, or if we have a special message for that count + if (value % interval == 0) or (Trackster_avMessages[kindkey] and Trackster_avMessages[kindkey][value]) then + + --> Fetch a special message if we have one, else come up with one + local message; + if Trackster_avMessages[kindkey] and Trackster_avMessages[kindkey][value] then + message = Trackster_avMessages[kindkey][value]; + else + --> Little special case for time played + if (kindkey == "timePlayed") then + local totalHours = math.floor((lastConfirmedTime + internalTimeOffset + Trackster_timeOffset) / 3600); + message = "Congratulations! You have played for " .. totalHours .. " hours!"; + else + message = "Congratulations! You have reached " .. value .. " " .. kindkey .. "!"; + end + end + + AnnounceMilestone(message); + end + end +end + +--> Will call AnnounceMilestone automatically, each time value is close to a multiple of interval, or explicitly defined in avMessages +--> Only use for decimal, steady values! +--> Meaning, they are decimal numbers and must never decrease in value! +--> Y is the leeway to trigger. Let's say, if you set a trigger for 1,000,000, and have a Y of 2, it would still trigger for 1,000,002. +local aamds_triggersUsed = {} +local function AutoAnnounceMilestone_DEC_STEADY(value, kindkey, prettyName, interval, Y) + if (Y == nil) then Y = 1 end; + + local intval = math.floor(value); + + --> Special trigger points + if (Trackster_avMessages[kindkey]) then + --> Find closest trigger point + local closestKey = nil; + local minDifference = math.huge; + for key, _ in pairs(Trackster_avMessages[kindkey]) do + if key <= intval then + local difference = intval - key + if difference < minDifference then + minDifference = difference + closestKey = key + end + end + end + + --> If we have found a closest key (may be 0 because were only looking at <= value keys + if (closestKey) then + --> If value is near closest defined trigger value AND trigger value is not blacklisted + local intsOverNearestTrigger = intval - closestKey; + if ((intsOverNearestTrigger <= Y) and (aamds_triggersUsed[kindkey][closestKey] == nil)) then + --> Announce the milestone + local message = Trackster_avMessages[kindkey][closestKey]; + AnnounceMilestone(message); + + --> Blacklist this trigger value + if (aamds_triggersUsed[kindkey] == nil) then + aamds_triggersUsed[kindkey] = {}; + end + aamds_triggersUsed[kindkey][closestKey] = true; + + return; + end + end + end + + --> Procedural trigger points + local mod = intval % interval; + local intsOverNearestTrigger = intval % interval; + local nearestTrigger = intval - intsOverNearestTrigger; + + --> If value is near procedural trigger AND trigger value is not blacklisted + if ((intsOverNearestTrigger <= Y) and (aamds_triggersUsed[kindkey] == nil or aamds_triggersUsed[kindkey][nearestTrigger] == nil)) then + --> Announce the milestone + local message = "Congratulations! You have reached " .. value .. " " .. prettyName .. "!"; + AnnounceMilestone(message); + + --> Blacklist this trigger value + if (aamds_triggersUsed[kindkey] == nil) then + aamds_triggersUsed[kindkey] = {}; + end + aamds_triggersUsed[kindkey][nearestTrigger] = true; + end +end + +local function CommafyNumber(number) + -- Convert the number to a string + local strNumber = tostring(number) + + -- Reverse the string + local reversedStr = string.reverse(strNumber) + + -- Add commas every three characters + local formattedStr = reversedStr:gsub("(%d%d%d)", "%1,") + + -- Reverse the formatted string back to its original order + local finalStr = string.reverse(formattedStr) + + -- Remove any leading comma if present + if string.sub(finalStr, 1, 1) == "," then + finalStr = string.sub(finalStr, 2) + end + + -- Return the formatted number + return finalStr +end + + mainFrame:SetBackdrop({ bgFile="Interface\\DialogFrame\\UI-DialogBox-Background", edgeFile="Interface\\DialogFrame\\UI-DialogBox-Border", @@ -255,7 +380,7 @@ local timer__taxi = 0; local timer__ghost = 0; function UpdateDistanceTravelled(self, deltaTime, forceTextUpdate) --> Update value in background in every frame - local deltaDistance = GetUnitSpeed("PLAYER") * 0.9144 * deltaTime; + local deltaDistance = GetUnitSpeed("PLAYER") * 0.9144 * deltaTime; --> Distance gets saved in meters, GetUnitSpeed returns yards per second Trackster_distanceTravelledCounter = Trackster_distanceTravelledCounter + deltaDistance; --> Increment specialized distance counters, if the state fits (like, swimming only if IsSwimming() == true) @@ -281,6 +406,14 @@ function UpdateDistanceTravelled(self, deltaTime, forceTextUpdate) local val__flight = round(Trackster_distanceTravelledCounter__flight + Trackster_distanceTravelledOffset__flight); local val__taxi = round(Trackster_distanceTravelledCounter__taxi + Trackster_distanceTravelledOffset__taxi); local val__ghost = round(Trackster_distanceTravelledCounter__ghost + Trackster_distanceTravelledOffset__ghost); + + AutoAnnounceMilestone_DEC_STEADY(val__all, "distAll", "kilometers travelled", 1000*1000, 100); --> Each 1,000 km + AutoAnnounceMilestone_DEC_STEADY(val__swam, "distSwam", "kilometers swam", 50*1000, 100); --> Each 50 km + AutoAnnounceMilestone_DEC_STEADY(val__walked, "distWalked", "kilometers travelled by foot", 500*1000, 100); --> Each 500 km + AutoAnnounceMilestone_DEC_STEADY(val__groundmount, "distGroundmount", "kilometers rode (on ground)", 1000*1000, 100); --> Each 1,000 km + AutoAnnounceMilestone_DEC_STEADY(val__flight, "distFlight", "kilometers flown", 1000*000, 100); --> Each 1,000 km + AutoAnnounceMilestone_DEC_STEADY(val__taxi, "distTaxi", "kilometers rode (on taxi)", 500*000, 100); --> Each 500 km + AutoAnnounceMilestone_DEC_STEADY(val__ghost, "distGhost", "kilometers haunted", 10*000, 100); --> Each 10 km timer__all = timer__all + deltaTime; timer__swam = timer__swam + deltaTime; @@ -356,9 +489,9 @@ function UpdateDistanceTravelled(self, deltaTime, forceTextUpdate) if (timer__all >= updateDelayS__all or forceTextUpdate) then --> Update UI text every deltaTime seconds if (val__all < 10000) then - fsDist:SetText("Distance travelled: " .. textCol_value .. val__all .. "m"); + fsDist:SetText("Distance travelled: " .. textCol_value .. CommafyNumber(val__all) .. "m"); else - fsDist:SetText("Distance travelled: " .. textCol_value .. round(val__all/1000) .. "km"); + fsDist:SetText("Distance travelled: " .. textCol_value .. CommafyNumber(round(val__all/1000)) .. "km"); end timer__all = 0; @@ -366,9 +499,9 @@ function UpdateDistanceTravelled(self, deltaTime, forceTextUpdate) if (timer__swam >= updateDelayS__swam or forceTextUpdate) then --> Update UI text every deltaTime seconds if (val__swam < 10000) then - fsDist__swam:SetText("Distance swam: " .. textCol_value .. val__swam .. "m"); + fsDist__swam:SetText("Distance swam: " .. textCol_value .. CommafyNumber(val__swam) .. "m"); else - fsDist__swam:SetText("Distance swam: " .. textCol_value .. round(val__swam/1000) .. "km"); + fsDist__swam:SetText("Distance swam: " .. textCol_value .. CommafyNumber(round(val__swam/1000)) .. "km"); end timer__swam = 0; @@ -376,9 +509,9 @@ function UpdateDistanceTravelled(self, deltaTime, forceTextUpdate) if (timer__walked >= updateDelayS__walked or forceTextUpdate) then --> Update UI text every deltaTime seconds if (val__walked < 10000) then - fsDist__walked:SetText("Distance by foot: " .. textCol_value .. val__walked .. "m"); + fsDist__walked:SetText("Distance by foot: " .. textCol_value .. CommafyNumber(val__walked) .. "m"); else - fsDist__walked:SetText("Distance by foot: " .. textCol_value .. round(val__walked/1000) .. "km"); + fsDist__walked:SetText("Distance by foot: " .. textCol_value .. CommafyNumber(round(val__walked/1000)) .. "km"); end timer__walked = 0; @@ -386,9 +519,9 @@ function UpdateDistanceTravelled(self, deltaTime, forceTextUpdate) if (timer__groundmount >= updateDelayS__groundmount or forceTextUpdate) then --> Update UI text every deltaTime seconds if (val__groundmount < 10000) then - fsDist__groundmount:SetText("Distance rode: " .. textCol_value .. val__groundmount .. "m"); + fsDist__groundmount:SetText("Distance rode: " .. textCol_value .. CommafyNumber(val__groundmount) .. "m"); else - fsDist__groundmount:SetText("Distance rode: " .. textCol_value .. round(val__groundmount/1000) .. "km"); + fsDist__groundmount:SetText("Distance rode: " .. textCol_value .. CommafyNumber(round(val__groundmount/1000)) .. "km"); end timer__groundmount = 0; @@ -396,9 +529,9 @@ function UpdateDistanceTravelled(self, deltaTime, forceTextUpdate) if (timer__flight >= updateDelayS__flight or forceTextUpdate) then --> Update UI text every deltaTime seconds if (val__flight < 10000) then - fsDist__flight:SetText("Distance flown: " .. textCol_value .. val__flight .. "m"); + fsDist__flight:SetText("Distance flown: " .. textCol_value .. CommafyNumber(val__flight) .. "m"); else - fsDist__flight:SetText("Distance flown: " .. textCol_value .. round(val__flight/1000) .. "km"); + fsDist__flight:SetText("Distance flown: " .. textCol_value .. CommafyNumber(round(val__flight/1000)) .. "km"); end timer__flight = 0; @@ -406,9 +539,9 @@ function UpdateDistanceTravelled(self, deltaTime, forceTextUpdate) if (timer__taxi >= updateDelayS__taxi or forceTextUpdate) then --> Update UI text every deltaTime seconds if (val__taxi < 10000) then - fsDist__taxi:SetText("Distance on taxi: " .. textCol_value .. val__taxi .. "m"); + fsDist__taxi:SetText("Distance on taxi: " .. textCol_value .. CommafyNumber(val__taxi) .. "m"); else - fsDist__taxi:SetText("Distance on taxi: " .. textCol_value .. round(val__taxi/1000) .. "km"); + fsDist__taxi:SetText("Distance on taxi: " .. textCol_value .. CommafyNumber(round(val__taxi/1000)) .. "km"); end timer__taxi = 0; @@ -416,9 +549,9 @@ function UpdateDistanceTravelled(self, deltaTime, forceTextUpdate) if (timer__ghost >= updateDelayS__ghost or forceTextUpdate) then --> Update UI text every deltaTime seconds if (val__ghost < 10000) then - fsDist__ghost:SetText("Distance haunted: " .. textCol_value .. val__ghost .. "m"); + fsDist__ghost:SetText("Distance haunted: " .. textCol_value .. CommafyNumber(val__ghost) .. "m"); else - fsDist__ghost:SetText("Distance haunted: " .. textCol_value .. round(val__ghost/1000) .. "km"); + fsDist__ghost:SetText("Distance haunted: " .. textCol_value .. CommafyNumber(round(val__ghost/1000)) .. "km"); end timer__ghost = 0; @@ -435,27 +568,25 @@ function UpdateDeaths() local val = select(1, GetStatistic(60)); if (val == "--") then - fsDeaths:SetText("Death count: " .. textCol_value .. (Trackster_deathOffset)); + fsDeaths:SetText("Death count: " .. textCol_value .. CommafyNumber(Trackster_deathOffset)); + AutoAnnounceMilestone_INT_STEADY_IINCR(Trackster_deathOffset, "deaths", "deaths", 100); else - fsDeaths:SetText("Death count: " .. textCol_value .. (val + Trackster_deathOffset)); + fsDeaths:SetText("Death count: " .. textCol_value .. CommafyNumber(val + Trackster_deathOffset)); end end local function UpdateKills() Trackster_killsOffset = round(Trackster_killsOffset); - - local val = select(1, GetStatistic(1197)); - - if (val == "--") then - fsKills:SetText("Kill count: " .. textCol_value .. (Trackster_killsOffset)); - else - fsKills:SetText("Kill count: " .. textCol_value .. (val + Trackster_killsOffset)); - end + + fsKills:SetText("Kill count: " .. textCol_value .. CommafyNumber(Trackster_killCounter + Trackster_killsOffset)); + AutoAnnounceMilestone_INT_STEADY_IINCR(Trackster_deathOffset, "kills", "creatures slain", 1000); end local function UpdateQuests() Trackster_questsOffset = round(Trackster_questsOffset); - fsQuests:SetText("Quest count: " .. textCol_value .. (Trackster_questCounter + Trackster_questsOffset)); + fsQuests:SetText("Quest count: " .. textCol_value .. CommafyNumber(Trackster_questCounter + Trackster_questsOffset)); + + AutoAnnounceMilestone_INT_STEADY_IINCR(Trackster_questCounter + Trackster_questsOffset, "quests", "quests completed", 100); end local function UpdateHearthstones() @@ -494,8 +625,9 @@ end local function UpdateJump() Trackster_jumpOffset = round(Trackster_jumpOffset); - fsJump:SetText("Jump count: " .. textCol_value .. (Trackster_jumpCounter + Trackster_jumpOffset)); - + fsJump:SetText("Jump count: " .. textCol_value .. CommafyNumber(Trackster_jumpCounter + Trackster_jumpOffset)); + + AutoAnnounceMilestone_INT_STEADY_IINCR(Trackster_jumpCounter + Trackster_jumpOffset, "jumps", "times jumped", 10000); end local function UpdateCasts() @@ -510,26 +642,29 @@ local function UpdateCasts() elseif(val >= 100000) then val = tostring(round(val / 1000), 0) .. "K"; end - fsCasts:SetText("Cast count: " .. textCol_value .. val); + fsCasts:SetText("Cast count: " .. textCol_value .. CommafyNumber(val)); + AutoAnnounceMilestone_INT_STEADY_IINCR(Trackster_castCounter + Trackster_castOffset, "casts" , "spells casted", 10000); end local function UpdateCrits() Trackster_critOffset = round(Trackster_critOffset); - fsCrits:SetText("Crit count: " .. textCol_value .. (Trackster_critCounter + Trackster_critOffset)); + fsCrits:SetText("Crit count: " .. textCol_value .. CommafyNumber(Trackster_critCounter + Trackster_critOffset)); + AutoAnnounceMilestone_INT_STEADY_IINCR(Trackster_critCounter + Trackster_critOffset, "crits", "critical hits", 10000); end local function UpdateLogins() Trackster_loginOffset = round(Trackster_loginOffset); - fsLogins:SetText("Login count: " .. textCol_value .. (Trackster_loginCounter + Trackster_loginOffset)); + fsLogins:SetText("Login/Reload count: " .. textCol_value .. CommafyNumber(Trackster_loginCounter + Trackster_loginOffset)); end local function UpdateBoss() Trackster_bossOffset = round(Trackster_bossOffset); - fsBoss:SetText("Boss count: " .. textCol_value .. (Trackster_bossCounter + Trackster_bossOffset)); + fsBoss:SetText("Boss count: " .. textCol_value .. CommafyNumber(Trackster_bossCounter + Trackster_bossOffset)); + AutoAnnounceMilestone_INT_STEADY_IINCR(Trackster_bossCounter + Trackster_bossOffset, "bosses", "bosses slain", 100); end @@ -552,7 +687,9 @@ end local function UpdateChat() Trackster_chatOffset = round(Trackster_chatOffset); - fsChat:SetText("Chat msgs sent: " .. textCol_value .. (Trackster_chatCounter + Trackster_chatOffset)); + fsChat:SetText("Chat msgs sent: " .. textCol_value .. CommafyNumber(Trackster_chatCounter + Trackster_chatOffset)); + + AutoAnnounceMilestone_INT_STEADY_IINCR(Trackster_chatCounter + Trackster_chatOffset, "chatMessagesSent", "chat messages sent", 1000); end local function UpdateItem() @@ -570,6 +707,8 @@ local function UpdateTime() local d, h, m, s = select(1, FormatTime(time() - Trackster_timestampRunBegin)); fsAbsTime:SetText("Time real: " .. textCol_value .. d .. "d, " .. h .. ":" .. m .. ":" .. s); + + AutoAnnounceMilestone_INT_STEADY_IINCR(lastConfirmedTime + internalTimeOffset + Trackster_timeOffset, "timePlayed", "time played", 3600*100); end @@ -813,11 +952,15 @@ local function eventHandler(self, event, ...) UpdateDeaths(); elseif (event == "COMBAT_LOG_EVENT_UNFILTERED") then - local type, fo, foo, source = select(2, CombatLogGetCurrentEventInfo()); + local type, _, _, source, _, _, dest = select(2, CombatLogGetCurrentEventInfo()); if(source == GetUnitName("player")) then - if (type == "UNIT_DIED") then UpdateKills(); + if (type == "PARTY_KILL") then + Trackster_killCounter = Trackster_killCounter + 1; + PlaySoundFile("Interface\\AddOns\\Trackster\\hurt.wav", "MASTER"); + print(type .. ', ' .. source .. ', ' .. dest); + UpdateKills(); elseif (type == "SPELL_DAMAGE") then @@ -844,7 +987,7 @@ local function eventHandler(self, event, ...) elseif (event == "QUEST_TURNED_IN") then --> This event may fire multiple times per quest turnin -.- so we'll just add a cooldown to it... local timeNow = time(); - if (timeNow - timeLastQuestCompleted > 3) then + if (timeNow - timeLastQuestCompleted > 1) then print("Quest turned in, fired, and counted!"); Trackster_questCounter = Trackster_questCounter + 1; UpdateQuests();