local savedLooks = {} local currentPed = PlayerPedId() local menuPool = NativeUI.CreatePool() local lookMenu = NativeUI.CreateMenu("Look-Menü", "Wähle deinen Style") menuPool:Add(lookMenu) local originalCamCoords = nil local cam = nil local loading = false local isMenuOpen = false local minimapLocked = false -- HUD Funktionen function hideHUD() DisplayRadar(false) TriggerEvent('codem-blackhudv2:SetForceHide', true, true) for i = 0, 22 do HideHudComponentThisFrame(i) end HideHudAndRadarThisFrame() end function showHUD() DisplayRadar(true) TriggerEvent('codem-blackhudv2:SetForceHide', false, false) SetRadarBigmapEnabled(false, false) end function isAnyMenuVisible() -- Prüfe Hauptmenü if lookMenu:Visible() then return true end -- Prüfe alle Untermenüs rekursiv local function checkSubMenus(menu) for _, item in pairs(menu.Items) do if item.SubMenu then if item.SubMenu:Visible() then return true end if checkSubMenus(item.SubMenu) then return true end end end return false end return checkSubMenus(lookMenu) end function updateMenuVisibility(menu, state) menu:Visible(state) for _, submenu in pairs(menu.Items) do if submenu.SubMenu then submenu.SubMenu:Visible(state) end end end RegisterNetEvent("lookchanger:setSavedLooks", function(data) savedLooks = data loading = false populateLookMenu() lookMenu:Visible(true) focusCameraOnPedFront() end) function closeMenu() lookMenu:Visible(false) for _, item in pairs(lookMenu.Items) do if item.SubMenu then item.SubMenu:Visible(false) end end clearCustomCamera() isMenuOpen = false -- Explizit alle Kontrollen wieder aktivieren EnableAllControlActions(0) -- Spieler entsperren local ped = PlayerPedId() FreezeEntityPosition(ped, false) SetEntityCollision(ped, true, true) -- Minimap-Rotation wieder freigeben if minimapLocked then minimapLocked = false UnlockMinimapAngle() end -- HUD wieder einblenden showHUD() TriggerEvent('codem-blackhudv2:SetForceHide', false, false) -- Kurzzeitig ESC-Taste blockieren Citizen.CreateThread(function() DisableControlAction(0, 200, true) -- ESC DisableControlAction(0, 199, true) -- P (Pause Menu) Wait(200) -- 200ms Verzögerung EnableControlAction(0, 200, true) EnableControlAction(0, 199, true) end) end RegisterCommand("lookchanger_menu", function() if not isMenuOpen and not loading then loading = true isMenuOpen = true TriggerServerEvent("lookchanger:requestLooks") elseif lookMenu:Visible() then closeMenu() end end) RegisterKeyMapping("lookchanger_menu", "Öffnet das Look-Menü", "keyboard", "F6") -- Hauptthread für Menüsteuerung und HUD Citizen.CreateThread(function() local spinnerAngle = 0.0 while true do Citizen.Wait(0) menuPool:ProcessMenus() if isAnyMenuVisible() then hideHUD() DisableAllControlActions(0) EnableControlAction(0, 1, true) -- Maus EnableControlAction(0, 2, true) -- Maus EnableControlAction(0, 18, true) -- Enter EnableControlAction(0, 172, true) -- Hoch EnableControlAction(0, 173, true) -- Runter EnableControlAction(0, 174, true) -- Links EnableControlAction(0, 175, true) -- Rechts EnableControlAction(0, 200, true) -- ESC EnableControlAction(0, 194, true) -- Backslash -- Minimap-Rotation verhindern if not minimapLocked then minimapLocked = true SetRadarBigmapEnabled(false, false) LockMinimapAngle(0) end if IsControlJustPressed(0, 200) or IsControlJustPressed(0, 194) then -- ESC oder Backslash closeMenu() end drawHint("Drücke ESC, Backslash oder F6, um das Menü zu schließen") elseif minimapLocked then minimapLocked = false UnlockMinimapAngle() showHUD() end if loading then drawLoadingSpinner("Daten werden geladen...", spinnerAngle) spinnerAngle = (spinnerAngle + 5) % 360 end end end) -- Kontinuierlicher Thread für HUD-Kontrolle Citizen.CreateThread(function() while true do if isAnyMenuVisible() then -- Aggressives HUD ausblenden DisplayRadar(false) TriggerEvent('codem-blackhudv2:SetForceHide', true, true) for i = 0, 22 do HideHudComponentThisFrame(i) end HideHudAndRadarThisFrame() end Citizen.Wait(0) end end) function focusCameraOnPedFront() local ped = PlayerPedId() originalCamCoords = GetEntityCoords(ped) local offset = GetOffsetFromEntityInWorldCoords(ped, 0.0, 1.5, 0.6) cam = CreateCam("DEFAULT_SCRIPTED_CAMERA", true) SetCamCoord(cam, offset.x, offset.y, offset.z) PointCamAtEntity(cam, ped, 0.0, 0.0, 0.6, true) SetCamActive(cam, true) RenderScriptCams(true, false, 0, true, true) local zoomStartTime = GetGameTimer() Citizen.CreateThread(function() while GetGameTimer() - zoomStartTime < 1000 do local zoomAmount = (GetGameTimer() - zoomStartTime) / 1000 SetCamFov(cam, 50 + zoomAmount * 10) Citizen.Wait(0) end end) end function clearCustomCamera() if cam then RenderScriptCams(false, false, 0, true, true) DestroyCam(cam, false) cam = nil end end function drawHint(text) SetTextFont(0) SetTextProportional(1) SetTextScale(0.35, 0.35) SetTextColour(255, 255, 255, 215) SetTextDropShadow() SetTextEdge(1, 0, 0, 0, 255) SetTextOutline() SetTextEntry("STRING") AddTextComponentString(text) DrawText(0.015, 0.955) end function notify(msg) SetNotificationTextEntry("STRING") AddTextComponentSubstringPlayerName(msg) DrawNotification(false, false) end function requestInput(prompt) AddTextEntry('FMMC_KEY_TIP1', prompt) DisplayOnscreenKeyboard(1, 'FMMC_KEY_TIP1', '', '', '', '', '', 30) while UpdateOnscreenKeyboard() == 0 do DisableAllControlActions(0) DisplayRadar(false) TriggerEvent('codem-blackhudv2:SetForceHide', true, true) Citizen.Wait(0) end if GetOnscreenKeyboardResult() then return GetOnscreenKeyboardResult() end return nil end function getCurrentLook(type) local ped = PlayerPedId() if type == "hair" then return { GetPedDrawableVariation(ped, 2), GetPedTextureVariation(ped, 2) } elseif type == "hat" then return { GetPedPropIndex(ped, 0), GetPedPropTextureIndex(ped, 0) } elseif type == "glasses" then return { GetPedPropIndex(ped, 1), GetPedPropTextureIndex(ped, 1) } elseif type == "bag" then return { GetPedDrawableVariation(ped, 5), GetPedTextureVariation(ped, 5) } elseif type == "shirt" then return { GetPedDrawableVariation(ped, 11), GetPedTextureVariation(ped, 11) } elseif type == "arms" then return { GetPedDrawableVariation(ped, 3), GetPedTextureVariation(ped, 3) } elseif type == "vest" then return { GetPedDrawableVariation(ped, 9), GetPedTextureVariation(ped, 9) } elseif type == "undershirt" then return { GetPedDrawableVariation(ped, 8), GetPedTextureVariation(ped, 8) } elseif type == "mask" then return { GetPedDrawableVariation(ped, 1), GetPedTextureVariation(ped, 1) } elseif type == "chain" then return { GetPedDrawableVariation(ped, 7), GetPedTextureVariation(ped, 7) } end end function applyLook(type, data) local ped = PlayerPedId() if type == "hair" then SetPedComponentVariation(ped, 2, data[1], data[2], 0) elseif type == "hat" then SetPedPropIndex(ped, 0, data[1], data[2], true) elseif type == "glasses" then SetPedPropIndex(ped, 1, data[1], data[2], true) elseif type == "bag" then SetPedComponentVariation(ped, 5, data[1], data[2], 0) elseif type == "shirt" then SetPedComponentVariation(ped, 11, data[1], data[2], 0) elseif type == "arms" then SetPedComponentVariation(ped, 3, data[1], data[2], 0) elseif type == "vest" then SetPedComponentVariation(ped, 9, data[1], data[2], 0) elseif type == "undershirt" then SetPedComponentVariation(ped, 8, data[1], data[2], 0) elseif type == "mask" then SetPedComponentVariation(ped, 1, data[1], data[2], 0) elseif type == "chain" then SetPedComponentVariation(ped, 7, data[1], data[2], 0) end end function createLoadButton(category, slot, menu) local name = "Leer" if savedLooks[category] and savedLooks[category][slot] then name = savedLooks[category][slot].name or ("Slot " .. slot) end local btn = NativeUI.CreateItem("Slot " .. slot .. ": " .. name, "") menu:AddItem(btn) btn.Activated = function(_, item) if savedLooks[category] and savedLooks[category][slot] then applyLook(category, savedLooks[category][slot].look) notify("Look geladen: " .. name) else notify("Kein Look in Slot " .. slot .. ".") end end return btn end function createSaveButton(category, slot, menu) local btn = NativeUI.CreateItem("Speichere Slot " .. slot, "") menu:AddItem(btn) btn.Activated = function(_, item) local confirm = true local name = nil -- Temporär das Menü ausblenden während der Eingabe menu:Visible(false) DisplayRadar(false) TriggerEvent('codem-blackhudv2:SetForceHide', true, true) if savedLooks[category] and savedLooks[category][slot] then name = requestInput("Slot ist belegt. Zum Überschreiben Namen eingeben, oder leer lassen zum Abbrechen:") if name == nil or name == "" then confirm = false notify("Speichern abgebrochen.") end else name = requestInput("Gib einen Namen für diesen Slot ein:") if name == nil or name == "" then confirm = false notify("Speichern abgebrochen.") end end -- Menü wieder anzeigen menu:Visible(true) if confirm and name then local look = getCurrentLook(category) savedLooks[category] = savedLooks[category] or {} savedLooks[category][slot] = { name = name, look = look } TriggerServerEvent("lookchanger:saveLook", category, slot, { name = name, look = look }) notify("Look gespeichert als " .. name) -- Button Text aktualisieren for i, item in pairs(menu.Items) do if item:Text():find("Slot " .. slot .. ":") then item:Text("Slot " .. slot .. ": " .. name) break end end end end end function populateLookMenu() lookMenu:Clear() local categories = { { key = "hair", label = "Haare", slots = 2 }, { key = "hat", label = "Hut", slots = 4 }, { key = "glasses", label = "Brille", slots = 4 }, { key = "mask", label = "Maske", slots = 4 }, { key = "chain", label = "Kette", slots = 4 }, { key = "bag", label = "Rucksack", slots = 4 }, { key = "shirt", label = "Oberteil", slots = 4 }, { key = "arms", label = "Arme", slots = 6 }, { key = "vest", label = "Weste", slots = 4 }, { key = "undershirt", label = "Unterhemd", slots = 4 } } for _, cat in ipairs(categories) do local subMenu = NativeUI.CreateMenu(cat.label, "Slots für " .. cat.label) menuPool:Add(subMenu) -- Event-Handler für jedes Untermenü subMenu.OnMenuOpened = function(menu) TriggerEvent('codem-blackhudv2:SetForceHide', true, true) DisplayRadar(false) end local btn = NativeUI.CreateItem(cat.label, "Öffne Slots für " .. cat.label) lookMenu:AddItem(btn) lookMenu:BindMenuToItem(subMenu, btn) for i = 1, cat.slots do createLoadButton(cat.key, i, subMenu) createSaveButton(cat.key, i, subMenu) end end end function drawLoadingSpinner(text, angle) local x, y = 0.5, 0.5 local radius = 0.03 local r = math.rad(angle) local px = x + math.cos(r) * radius local py = y + math.sin(r) * radius DrawRect(x, y, 0.15, 0.07, 0, 0, 0, 180) DrawLine(x, y, px, py, 255, 255, 255, 255) SetTextFont(0) SetTextScale(0.4, 0.4) SetTextCentre(true) SetTextEntry("STRING") AddTextComponentString(text) DrawText(x, y + 0.04) end AddEventHandler('onResourceStop', function(resourceName) if (GetCurrentResourceName() ~= resourceName) then return end if lookMenu:Visible() then closeMenu() end -- Sicherstellen, dass der Spieler wirklich frei ist local ped = PlayerPedId() FreezeEntityPosition(ped, false) SetEntityCollision(ped, true, true) EnableAllControlActions(0) TriggerEvent('codem-blackhudv2:SetForceHide', false, false) end)