local addonName = "MoanS" local defaults = { active = true, chat = true, petEnabled = true, healEnabled = true, color = "|cffFF69B4", totalMoans = 0, showCounter = true, framePos = nil, soundBaseName = "moan", comboTimeout = 4.0, locked = false, } local frame = CreateFrame("Frame") frame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED") frame:RegisterEvent("ADDON_LOADED") local lastSoundTime = 0 local comboCount = 0 local MAX_SOUNDS = 9 -- Hilfsfunktion: Zahlen kürzen local function FormatNumber(amount) if not amount or type(amount) ~= "number" then return amount or "0" end if amount >= 1000000 then return string.format("%.1fM", amount / 1000000) elseif amount >= 1000 then return string.format("%.1fK", amount / 1000) else return tostring(amount) end end -- 1. GRAFISCHER COUNTER local CounterFrame = CreateFrame("Frame", "MoanSCounterFrame", UIParent, "BackdropTemplate") CounterFrame:SetSize(130, 40) CounterFrame:SetPoint("CENTER", 0, 0) CounterFrame:SetMovable(true) CounterFrame:EnableMouse(true) CounterFrame:RegisterForDrag("LeftButton") CounterFrame:SetClampedToScreen(true) CounterFrame.bg = CounterFrame:CreateTexture(nil, "BACKGROUND") CounterFrame.bg:SetAllPoints() CounterFrame.bg:SetColorTexture(0, 0, 0, 0.6) CounterFrame.Cooldown = CreateFrame("Cooldown", nil, CounterFrame, "CooldownFrameTemplate") CounterFrame.Cooldown:SetAllPoints() CounterFrame.Cooldown:SetDrawEdge(false) CounterFrame.Cooldown:SetSwipeColor(1, 0.41, 0.7, 0.5) CounterFrame.text = CounterFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge") CounterFrame.text:SetPoint("CENTER") CounterFrame.text:SetText("Moans: 0") -- 2. FEUERWERK ANIMATION local function ShowCritText(amount) local f = CreateFrame("Frame", nil, CounterFrame) f:SetSize(200, 30) f:SetPoint("CENTER", CounterFrame, "CENTER", 0, 0) local text = f:CreateFontString(nil, "OVERLAY", "NumberFontNormal") text:SetPoint("CENTER") text:SetText(FormatNumber(amount)) text:SetTextColor(1, 0.41, 0.7) text:SetFont(text:GetFont(), 22, "OUTLINE") local ag = f:CreateAnimationGroup() local targetX = math.random(-120, 120) local targetY = math.random(80, 150) local scale = ag:CreateAnimation("Scale") scale:SetScale(1.4, 1.4) scale:SetDuration(0.15) scale:SetOrder(1) local translation = ag:CreateAnimation("Translation") translation:SetOffset(targetX, targetY) translation:SetDuration(1.4) translation:SetSmoothing("OUT") translation:SetOrder(2) local alpha = ag:CreateAnimation("Alpha") alpha:SetFromAlpha(1) alpha:SetToAlpha(0) alpha:SetStartDelay(0.7) alpha:SetDuration(0.7) alpha:SetOrder(2) ag:SetScript("OnFinished", function() f:Hide() end) ag:Play() end -- 3. UPDATES & OPTIONEN local function UpdateCounterDisplay() if not MoanSDB then return end CounterFrame.text:SetText("Moans: " .. (MoanSDB.totalMoans or 0)) if MoanSDB.showCounter and MoanSDB.active then CounterFrame:Show() else CounterFrame:Hide() end CounterFrame:EnableMouse(not MoanSDB.locked) end CounterFrame:SetScript("OnDragStart", CounterFrame.StartMoving) CounterFrame:SetScript("OnDragStop", function(self) self:StopMovingOrSizing() local point, _, relativePoint, x, y = self:GetPoint() if MoanSDB then MoanSDB.framePos = { point, relativePoint, x, y } end end) local function TriggerCombo() local currentTime = GetTime() local timeout = MoanSDB and MoanSDB.comboTimeout or 4.0 local soundFile = "" if (currentTime - lastSoundTime) > timeout or comboCount >= MAX_SOUNDS then comboCount = 1 else comboCount = comboCount + 1 end lastSoundTime = currentTime CounterFrame.Cooldown:SetCooldown(currentTime, timeout) if comboCount == MAX_SOUNDS then soundFile = "Interface\\AddOns\\MoanS\\moan10.ogg" else soundFile = "Interface\\AddOns\\MoanS\\" .. (MoanSDB.soundBaseName or "moan") .. comboCount .. ".ogg" end return soundFile end -- 4. CONFIG PANEL local MoanSPanel = CreateFrame("Frame", "MoanSConfigPanel", UIParent) MoanSPanel.name = addonName local category local function CreateCB(parent, label, x, y, dbKey) local cb = CreateFrame("CheckButton", nil, parent, "InterfaceOptionsCheckButtonTemplate") cb:SetPoint("TOPLEFT", x, y) cb.Text:SetText(label) cb:SetScript("OnShow", function(self) if MoanSDB then self:SetChecked(MoanSDB[dbKey]) end end) cb:SetScript("OnClick", function(self) MoanSDB[dbKey] = self:GetChecked() UpdateCounterDisplay() end) return cb end -- 5. HAUPT EVENT HANDLER frame:SetScript("OnEvent", function(self, event, arg1) if event == "ADDON_LOADED" and arg1 == addonName then if not MoanSDB then MoanSDB = CopyTable(defaults) end for k, v in pairs(defaults) do if MoanSDB[k] == nil then MoanSDB[k] = v end end category = Settings.RegisterCanvasLayoutCategory(MoanSPanel, addonName) Settings.RegisterAddOnCategory(category) local title = MoanSPanel:CreateFontString(nil, "ARTWORK", "GameFontNormalLarge") title:SetPoint("TOPLEFT", 16, -16) title:SetText("|cffFF69B4MoanS|r - Classic Anniversary") CreateCB(MoanSPanel, "Addon Aktiviert", 16, -50, "active") CreateCB(MoanSPanel, "Fenster anzeigen", 16, -80, "showCounter") CreateCB(MoanSPanel, "Fenster fixieren (Lock)", 16, -110, "locked") CreateCB(MoanSPanel, "Chat Nachrichten", 16, -140, "chat") local slider = CreateFrame("Slider", "MoanSTimeoutSlider", MoanSPanel, "OptionsSliderTemplate") slider:SetPoint("TOPLEFT", 20, -190) slider:SetMinMaxValues(0.5, 10.0) slider:SetValueStep(0.5) slider:SetWidth(180) _G[slider:GetName().."Low"]:SetText("0.5s") _G[slider:GetName().."High"]:SetText("10s") local sliderVal = slider:CreateFontString(nil, "ARTWORK", "GameFontHighlight") sliderVal:SetPoint("BOTTOM", slider, "TOP", 0, 5) slider:SetScript("OnValueChanged", function(s, val) val = math.floor(val * 2 + 0.5) / 2 MoanSDB.comboTimeout = val sliderVal:SetText("Combo-Zeit: "..val.."s") end) slider:SetValue(MoanSDB.comboTimeout) local btnTest = CreateFrame("Button", nil, MoanSPanel, "UIPanelButtonTemplate") btnTest:SetPoint("TOPLEFT", 16, -240) btnTest:SetSize(160, 25) btnTest:SetText("Feuerwerk Testen") btnTest:SetScript("OnClick", function() PlaySoundFile(TriggerCombo(), "Master") ShowCritText(math.random(100, 5000)) end) if MoanSDB.framePos then CounterFrame:ClearAllPoints() CounterFrame:SetPoint(MoanSDB.framePos[1], UIParent, MoanSDB.framePos[2], MoanSDB.framePos[3], MoanSDB.framePos[4]) end UpdateCounterDisplay() elseif event == "COMBAT_LOG_EVENT_UNFILTERED" then if not MoanSDB or not MoanSDB.active then return end local info = {CombatLogGetCurrentEventInfo()} local subevent, sourceGUID = info[2], info[4] if sourceGUID == UnitGUID("player") or (sourceGUID == UnitGUID("pet") and MoanSDB.petEnabled) then local isCrit, amount = false, 0 if subevent == "SWING_DAMAGE" then amount, isCrit = info[12], info[18] elseif subevent == "RANGE_DAMAGE" or subevent == "SPELL_DAMAGE" then amount, isCrit = info[15], info[21] elseif subevent == "SPELL_HEAL" and MoanSDB.healEnabled then amount, isCrit = info[15], info[18] end if isCrit then PlaySoundFile(TriggerCombo(), "Master") ShowCritText(amount) MoanSDB.totalMoans = MoanSDB.totalMoans + 1 UpdateCounterDisplay() end end end end) SLASH_MOANS1 = "/moans" SlashCmdList["MOANS"] = function() if category then Settings.OpenToCategory(category:GetID()) end end