local QBCore = exports['qb-core']:GetCoreObject() local fireworkTime = 0 local fireworkLoc = nil -- Modelle für Feuerwerks-Batterien local batteryModels = { "ind_prop_firework_04", -- Standard-Feuerwerks-Batterie "ind_prop_firework_03", -- Größere Feuerwerks-Batterie "prop_beach_fire", -- Alternative für bessere Sichtbarkeit "prop_firework_03" -- Weitere Batterie-Option } -- Farben für die Feuerwerkseffekte local colors = { {r = 255, g = 0, b = 0}, -- Rot {r = 0, g = 255, b = 0}, -- Grün {r = 0, g = 0, b = 255}, -- Blau {r = 255, g = 255, b = 0}, -- Gelb {r = 255, g = 0, b = 255}, -- Magenta {r = 0, g = 255, b = 255}, -- Cyan {r = 255, g = 255, b = 255} -- Weiß } -- Funktion zum Starten einer Feuerwerks-Batterie ohne Explosionseffekte local function startFireworkBattery(coords, type) -- Wähle ein Batteriemodell basierend auf dem Typ oder zufällig local batteryModel = batteryModels[type or math.random(1, #batteryModels)] -- Lade das Modell RequestModel(GetHashKey(batteryModel)) while not HasModelLoaded(GetHashKey(batteryModel)) do Wait(10) end -- Erstelle die Batterie local battery = CreateObject(GetHashKey(batteryModel), coords.x, coords.y, coords.z - 0.5, -- Leicht in den Boden eingelassen true, true, false) -- Stelle die Batterie richtig auf den Boden PlaceObjectOnGroundProperly(battery) FreezeEntityPosition(battery, true) -- Warte kurz, damit die Batterie sichtbar ist Wait(500) -- Füge einen Zündungseffekt hinzu RequestNamedPtfxAsset("core") while not HasNamedPtfxAssetLoaded("core") do Wait(10) end UseParticleFxAssetNextCall("core") local ignitionEffect = StartParticleFxLoopedOnEntity("ent_amb_torch_fire", battery, 0.0, 0.0, 0.2, 0.0, 0.0, 0.0, 0.5, false, false, false) -- Zündungsgeräusch PlaySoundFromEntity(-1, "DISTANT_FIREWORK_LAUNCH_01", battery, "dlc_sum20_beach_party_sounds", true, 20) -- Warte kurz für den Zündungseffekt Wait(1000) -- Stoppe den Zündungseffekt StopParticleFxLooped(ignitionEffect, 0) -- Bestimme die Anzahl der Schüsse basierend auf dem Typ local numShots = 0 if type == 1 then numShots = math.random(10, 15) elseif type == 2 then numShots = math.random(15, 20) elseif type == 3 then numShots = math.random(20, 25) elseif type == 4 then numShots = math.random(25, 30) else numShots = math.random(10, 20) end print("Starte Feuerwerks-Batterie mit " .. numShots .. " Schüssen") -- Liste der Partikeleffekte für Feuerwerk local fireworkEffects = { "ent_sht_flame", "ent_sht_confetti", "ent_sht_steam", "ent_dst_gen_firework", "ent_ray_heli_aprtmnt_l_fire", "ent_ray_heli_aprtmnt_h_fire", "proj_flare_trail" } -- Starte die Feuerwerksschüsse for i = 1, numShots do -- Bestimme die Höhe und Position des Schusses local height = math.random(30, 50) local offsetX = math.random(-10, 10) * (i / numShots) -- Größere Streuung bei späteren Schüssen local offsetY = math.random(-10, 10) * (i / numShots) -- Starteffekt (Abschuss von der Batterie) UseParticleFxAssetNextCall("core") StartParticleFxNonLoopedAtCoord("ent_sht_flame", coords.x, coords.y, coords.z + 0.5, 0.0, 0.0, 0.0, 0.8, false, false, false) -- Abschussgeräusch PlaySoundFromEntity(-1, "DISTANT_FIREWORK_LAUNCH_01", battery, "dlc_sum20_beach_party_sounds", true, 20) -- Warte kurz für den visuellen Effekt des Aufstiegs Wait(math.random(100, 200)) -- Explosionseffekt in der Luft (nur Partikel, keine echte Explosion) local explosionHeight = coords.z + height -- Wähle einen zufälligen Effekt local effect = fireworkEffects[math.random(1, #fireworkEffects)] -- Starte den Haupteffekt UseParticleFxAssetNextCall("core") StartParticleFxNonLoopedAtCoord( effect, coords.x + offsetX, coords.y + offsetY, explosionHeight, 0.0, 0.0, 0.0, math.random(20, 30) / 10, -- Größere Skalierung für bessere Sichtbarkeit false, false, false ) -- Füge zusätzliche Effekte für mehr Volumen hinzu for j = 1, 3 do local subOffsetX = math.random(-3, 3) local subOffsetY = math.random(-3, 3) local subOffsetZ = math.random(-3, 3) UseParticleFxAssetNextCall("core") StartParticleFxNonLoopedAtCoord( fireworkEffects[math.random(1, #fireworkEffects)], coords.x + offsetX + subOffsetX, coords.y + offsetY + subOffsetY, explosionHeight + subOffsetZ, 0.0, 0.0, 0.0, math.random(15, 25) / 10, false, false, false ) end -- Explosionsgeräusch PlaySoundFromCoord(-1, "DISTANT_FIREWORK_BURST_0" .. math.random(1, 3), coords.x + offsetX, coords.y + offsetY, explosionHeight, "dlc_sum20_beach_party_sounds", true, 50, false) -- Warte zwischen den Schüssen -- Schnellere Abfolge gegen Ende für ein Finale local waitTime = 0 if i < numShots * 0.7 then waitTime = math.random(300, 800) else waitTime = math.random(100, 300) end Wait(waitTime) end -- Warte nach dem letzten Schuss Wait(2000) -- Finale mit mehreren gleichzeitigen Effekten for i = 1, 8 do local finalOffsetX = math.random(-15, 15) local finalOffsetY = math.random(-15, 15) local finalHeight = math.random(30, 50) UseParticleFxAssetNextCall("core") StartParticleFxNonLoopedAtCoord( fireworkEffects[math.random(1, #fireworkEffects)], coords.x + finalOffsetX, coords.y + finalOffsetY, coords.z + finalHeight, 0.0, 0.0, 0.0, math.random(25, 35) / 10, -- Größere Skalierung für das Finale false, false, false ) -- Finale-Geräusch PlaySoundFromCoord(-1, "DISTANT_FIREWORK_BURST_0" .. math.random(1, 3), coords.x + finalOffsetX, coords.y + finalOffsetY, coords.z + finalHeight, "dlc_sum20_beach_party_sounds", true, 50, false) Wait(100) end -- Lösche die Batterie nach einer Weile Wait(5000) DeleteEntity(battery) end local function DrawText3D(x, y, z, text) SetTextScale(0.35, 0.35) SetTextFont(4) SetTextProportional(true) SetTextColour(255, 255, 255, 215) BeginTextCommandDisplayText('STRING') SetTextCentre(true) AddTextComponentSubstringPlayerName(text) SetDrawOrigin(x, y, z, 0) EndTextCommandDisplayText(0.0, 0.0) local factor = (string.len(text)) / 370 DrawRect(0.0, 0.0 + 0.0125, 0.017 + factor, 0.03, 0, 0, 0, 75) ClearDrawOrigin() end local function fireworkText() CreateThread(function() while true do Wait(0) if fireworkTime > 0 and fireworkLoc then DrawText3D(fireworkLoc.x, fireworkLoc.y, fireworkLoc.z, Lang:t('firework.time_left') .. fireworkTime) end if fireworkTime <= 0 then break end end end) end -- Verbesserte Feuerwerk-Startfunktion local function startFirework(asset, coords) fireworkTime = Config.Fireworks.delay fireworkLoc = { x = coords.x, y = coords.y, z = coords.z } CreateThread(function() fireworkText() while fireworkTime > 0 do Wait(1000) fireworkTime = fireworkTime - 1 end print("Countdown beendet, starte Feuerwerks-Batterie") -- Bestimme den Batterietyp basierend auf dem Asset local batteryType = 1 -- Standard if asset == "proj_xmas_firework" then batteryType = 2 elseif asset == "scr_indep_fireworks" then batteryType = 3 elseif asset == "proj_indep_firework_v2" then batteryType = 4 end startFireworkBattery(coords, batteryType) fireworkLoc = nil end) end -- Animation für das Anzünden mit Feuerzeug local function playLighterAnimation() local ped = PlayerPedId() -- Lade die Animation RequestAnimDict("anim@mp_player_intmenu@key_fob@") while not HasAnimDictLoaded("anim@mp_player_intmenu@key_fob@") do Wait(10) end -- Spiele die Animation ab TaskPlayAnim(ped, "anim@mp_player_intmenu@key_fob@", "fob_click", 3.0, 3.0, -1, 49, 0, false, false, false) -- Erstelle ein Feuerzeug-Objekt in der Hand local coords = GetEntityCoords(ped) local lighter = CreateObject(GetHashKey("prop_cs_lighter_01"), coords.x, coords.y, coords.z, true, true, true) AttachEntityToEntity(lighter, ped, GetPedBoneIndex(ped, 57005), 0.1, 0.05, 0.0, -60.0, 0.0, 0.0, true, true, false, true, 1, true) -- Füge einen Flammeneffekt hinzu RequestNamedPtfxAsset("core") while not HasNamedPtfxAssetLoaded("core") do Wait(10) end UseParticleFxAssetNextCall("core") local flame = StartParticleFxLoopedOnEntity("ent_amb_torch_fire", lighter, 0.0, 0.0, 0.15, 0.0, 0.0, 0.0, 0.15, false, false, false) -- Warte 2 Sekunden Wait(2000) -- Stoppe die Animation und lösche das Feuerzeug StopAnimTask(ped, "anim@mp_player_intmenu@key_fob@", "fob_click", 1.0) StopParticleFxLooped(flame, 0) DeleteEntity(lighter) end -- Überprüfe, ob der Spieler ein Feuerzeug hat local function hasLighter() local hasItem = QBCore.Functions.HasItem("lighter") return hasItem end RegisterNetEvent('fireworks:client:UseFirework', function(itemName, assetName) print("Feuerwerk-Event ausgelöst mit Item: " .. itemName) -- Überprüfe zuerst, ob der Spieler ein Feuerzeug hat if not hasLighter() then QBCore.Functions.Notify(Lang:t('firework.no_lighter'), 'error') return end QBCore.Functions.Progressbar('spawn_object', Lang:t('firework.place_progress'), 3000, false, true, { disableMovement = true, disableCarMovement = true, disableMouse = false, disableCombat = true, }, { animDict = 'anim@narcotics@trash', anim = 'drop_front', flags = 16, }, {}, {}, function() -- Done StopAnimTask(PlayerPedId(), 'anim@narcotics@trash', 'drop_front', 1.0) TriggerServerEvent('consumables:server:UseFirework', itemName) TriggerEvent('qb-inventory:client:ItemBox', QBCore.Shared.Items[itemName], 'remove') local pos = GetEntityCoords(PlayerPedId()) print("Feuerwerk platziert, beginne Anzündung") -- Spiele die Feuerzeug-Animation ab playLighterAnimation() -- Starte das Feuerwerk startFirework(assetName, pos) end, function() -- Cancel StopAnimTask(PlayerPedId(), 'anim@narcotics@trash', 'drop_front', 1.0) QBCore.Functions.Notify(Lang:t('firework.canceled'), 'error') end) end) -- Test-Befehl zum direkten Auslösen von Feuerwerk RegisterCommand('batterie', function(source, args) local playerPed = PlayerPedId() local coords = GetEntityCoords(playerPed) -- Überprüfe zuerst, ob der Spieler ein Feuerzeug hat if not hasLighter() then QBCore.Functions.Notify(Lang:t('firework.no_lighter'), 'error') return end -- Optional: Typ der Batterie als Argument local type = tonumber(args[1]) or math.random(1, 4) if type < 1 or type > 4 then type = 1 end -- Spiele die Feuerzeug-Animation ab playLighterAnimation() -- Starte das Feuerwerk startFireworkBattery(coords, type) end)