local addonName = "MoanS" local MOAN_NAME = "|cFFFF69B4MoanS|r" local MOAN_TEXT = "|cFFFF69B4Moan!|r" local COMBO_COLOR = "|cFF00FF00" local COMBO_IMAGE_PATH = "Interface\\AddOns\\MoanS\\media\\combo_pic.tga" local defaults = { active = true, chat = true, petEnabled = true, healEnabled = true, totalMoans = 0, showCounter = true, showImages = 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, comboCount = 0, 0 -- CHAOS-VISUAL FUNKTION local function TriggerComboVisual() if not MoanSDB or not MoanSDB.showImages then return end local f = CreateFrame("Frame", nil, UIParent) -- Zufällige Größe (300 bis 550 Pixel) local randomSize = math.random(300, 550) f:SetSize(randomSize, randomSize) -- Große Streuung über den Bildschirm local randomX = math.random(-750, 750) local randomY = math.random(-400, 500) f:SetPoint("CENTER", randomX, randomY) local tex = f:CreateTexture(nil, "OVERLAY") tex:SetAllPoints() tex:SetTexture(COMBO_IMAGE_PATH) -- Zufällige Transparenz für mehr Dynamik local randomAlpha = math.random(50, 85) / 100 tex:SetAlpha(randomAlpha) local ag = f:CreateAnimationGroup() -- Explosionseffekt local scale = ag:CreateAnimation("Scale") scale:SetScale(1.4, 1.4) scale:SetDuration(0.15) scale:SetOrder(1) -- Fade Out local fade = ag:CreateAnimation("Alpha") fade:SetFromAlpha(1) fade:SetToAlpha(0) fade:SetStartDelay(0.5) fade:SetDuration(0.6) fade:SetOrder(2) ag:SetScript("OnFinished", function() f:Hide() f:SetParent(nil) end) ag:Play() end 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 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:SetSwipeColor(1, 0.41, 0.7, 0.5) CounterFrame.text = CounterFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge") CounterFrame.text:SetPoint("CENTER") local function ShowCritText(amount, isHighCombo) local f = CreateFrame("Frame", nil, CounterFrame); f:SetSize(200, 30) f:SetPoint("CENTER", CounterFrame, "CENTER", 0, 0) local text = f:CreateFontString(nil, "OVERLAY", "NumberFont_Outline_Huge") text:SetPoint("CENTER"); text:SetText(FormatNumber(amount)) text:SetTextColor(isHighCombo and 0 or 1, isHighCombo and 1 or 0.41, isHighCombo and 0 or 0.7) local ag = f:CreateAnimationGroup() local tX, tY = math.random(-120, 120), math.random(80, 150) local s = ag:CreateAnimation("Scale"); s:SetScale(1.5, 1.5); s:SetDuration(0.15); s:SetOrder(1) local t = ag:CreateAnimation("Translation"); t:SetOffset(tX, tY); t:SetDuration(1.4); t:SetSmoothing("OUT"); t:SetOrder(2) local a = ag:CreateAnimation("Alpha"); a:SetFromAlpha(1); a:SetToAlpha(0); a:SetStartDelay(0.7); a:SetDuration(0.7); a:SetOrder(2) ag:SetScript("OnFinished", function() f:Hide() end); ag:Play() end local function UpdateCounterDisplay() if not MoanSDB then return end CounterFrame.text:SetText("Moans: " .. (MoanSDB.totalMoans or 0)) CounterFrame:SetShown(MoanSDB.showCounter and MoanSDB.active) CounterFrame:EnableMouse(not MoanSDB.locked) end CounterFrame:SetScript("OnDragStart", CounterFrame.StartMoving) CounterFrame:SetScript("OnDragStop", function(self) self:StopMovingOrSizing() local p, _, r, x, y = self:GetPoint() if MoanSDB then MoanSDB.framePos = { p, r, x, y } end end) local function GetNextSound() local currentTime = GetTime() local timeout = MoanSDB and MoanSDB.comboTimeout or 4.0 if (currentTime - lastSoundTime) > timeout then comboCount = 1 else comboCount = comboCount + 1 end lastSoundTime = currentTime CounterFrame.Cooldown:SetCooldown(currentTime, timeout) local soundIndex = comboCount % 10 if soundIndex == 0 then soundIndex = 10 TriggerComboVisual() end local sFile = (MoanSDB.soundBaseName or "moan") .. soundIndex .. ".ogg" return "Interface\\AddOns\\MoanS\\media\\" .. sFile, comboCount, (comboCount >= 10) end local MoanSPanel = CreateFrame("Frame", "MoanSConfigPanel", UIParent) 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 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, MOAN_NAME) Settings.RegisterAddOnCategory(category) local title = MoanSPanel:CreateFontString(nil, "ARTWORK", "GameFontNormalLarge") title:SetPoint("TOPLEFT", 16, -16); title:SetText(MOAN_NAME .. " - Retail") CreateCB(MoanSPanel, "Addon Aktiviert", 16, -50, "active") CreateCB(MoanSPanel, "Chat Nachrichten", 16, -80, "chat") CreateCB(MoanSPanel, "Fenster anzeigen", 16, -110, "showCounter") CreateCB(MoanSPanel, "Bilder bei Ultra-Combo", 16, -140, "showImages") CreateCB(MoanSPanel, "Fenster fixieren (Lock)", 16, -170, "locked") CreateCB(MoanSPanel, "Pet Crits zählen", 16, -200, "petEnabled") CreateCB(MoanSPanel, "Heil-Crits zählen", 16, -230, "healEnabled") local slider = CreateFrame("Slider", "MoanSTimeoutSlider", MoanSPanel, "OptionsSliderTemplate") slider:SetPoint("TOPLEFT", 20, -280); 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, -330); btnTest:SetSize(160, 25); btnTest:SetText("Combo Testen") btnTest:SetScript("OnClick", function() local sPath, cIdx, isHigh = GetNextSound() PlaySoundFile(sPath, "Master"); ShowCritText(math.random(100,5000), isHigh) if MoanSDB.chat then local prefix = isHigh and (COMBO_COLOR .. "[ULTRA COMBO x" .. cIdx .. "]|r") or ("[Combo " .. cIdx .. "/9]") print(MOAN_TEXT .. " " .. prefix) end 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 _, sub, _, sGUID, _, _, _, _, _, _, _, a12, _, _, _, a15, _, a17, a18, _, a21 = CombatLogGetCurrentEventInfo() if sGUID == UnitGUID("player") or (MoanSDB.petEnabled and sGUID == UnitGUID("pet")) then local isCrit, amount = false, 0 if sub == "SWING_DAMAGE" then amount, isCrit = a12, a17 elseif sub:find("_DAMAGE") then amount, isCrit = a15, a21 elseif sub == "SPELL_HEAL" and MoanSDB.healEnabled then amount, isCrit = a15, a18 end if isCrit then local sPath, cIdx, isHigh = GetNextSound() PlaySoundFile(sPath, "Master"); ShowCritText(amount, isHigh) MoanSDB.totalMoans = MoanSDB.totalMoans + 1; UpdateCounterDisplay() if MoanSDB.chat then local prefix = isHigh and (COMBO_COLOR .. "[ULTRA COMBO x" .. cIdx .. "]|r") or ("[Combo " .. cIdx .. "/9]") print(MOAN_TEXT .. " " .. prefix .. " Crit: " .. FormatNumber(amount)) end end end end end) SLASH_MOANS1 = "/moans" SlashCmdList["MOANS"] = function() if category and category.GetID then Settings.OpenToCategory(category:GetID()) end end