diff --git a/resources/[standalone]/vms_firework/client.lua b/resources/[standalone]/vms_firework/client.lua index 04c349d02..19f9db0e9 100644 --- a/resources/[standalone]/vms_firework/client.lua +++ b/resources/[standalone]/vms_firework/client.lua @@ -1,3 +1,5 @@ +-- No need for explicit import as we're using shared_scripts in fxmanifest.lua + local function DrawText3D(coords, text) local camCoords = GetFinalRenderedCamCoord() local distance = #(coords - camCoords) @@ -25,87 +27,133 @@ local function reqAnimDict(dict) end local function reqParticle(dict) - RequestNamedPtfxAsset(dict) + RequestNamedPtfxAsset(dict) while not HasNamedPtfxAssetLoaded(dict) do Wait(1) end end +-- Add this function to handle rocket flight +local function launchRocket(rocketObj, targetHeight, speed) + local startCoords = GetEntityCoords(rocketObj) + local targetCoords = vector3(startCoords.x, startCoords.y, startCoords.z + targetHeight) + + -- Add rocket launch particle effect + UseParticleFxAsset("core") + local effect = StartParticleFxLoopedOnEntity("ent_sht_flame", rocketObj, 0.0, 0.0, -0.2, 0.0, 0.0, 0.0, 0.5, false, false, false) + + -- Add rocket sound + PlaySoundFromEntity(-1, "Jet_Explosions", rocketObj, "exile_1", true, 0) + + -- Make rocket fly upward + local distance = #(targetCoords - startCoords) + local steps = math.floor(distance / speed) + local stepVector = (targetCoords - startCoords) / steps + + FreezeEntityPosition(rocketObj, false) + + for i = 1, steps do + local newPos = startCoords + (stepVector * i) + SetEntityCoords(rocketObj, newPos.x, newPos.y, newPos.z, false, false, false, false) + Wait(10) + end + + -- Stop particle effect + StopParticleFxLooped(effect, 0) + + return targetCoords +end + for k, v in pairs(Config.Fireworks) do - if v.command then - RegisterCommand(v.command, function(source, args, rawCommand) - TriggerEvent('vms_firework:startFirework', k) - end) - end + if v.command then + RegisterCommand(v.command, function(source, args, rawCommand) + TriggerEvent('vms_firework:startFirework', k) + end) + end end local hasBox = nil RegisterNetEvent('vms_firework:startFirework', function(type) - if Config.DisableMultiplyFireworks then - if hasBox then - return Config.Notification(Config.Translate['CANNOT_START'], 4500, 'error') - end - end - if Config.Fireworks[type] then - local myFirework = Config.Fireworks[type] - local myPed = PlayerPedId() - local myOffset = GetOffsetFromEntityInWorldCoords(myPed, 0, .6, 0) - local fireworkShoots = myFirework.shoots - local secondsToStart = myFirework.timeToStart - reqAnimDict(Config.PlacingAnimation[1]) - TaskPlayAnim(myPed, Config.PlacingAnimation[1], Config.PlacingAnimation[2], -1, -8.0, 3000, 0, 0, false, false, false) - Citizen.Wait((GetAnimDuration(Config.PlacingAnimation[1], Config.PlacingAnimation[2]) * 1000) - 2050) - hasBox = CreateObject(myFirework.prop, myOffset.x, myOffset.y, myOffset.z, true, false, false) - PlaceObjectOnGroundProperly(hasBox) - FreezeEntityPosition(hasBox, true) - Config.Notification(Config.Translate['YOU_PLACE_FIREWORK'], 4500, 'success') - local boxCoords = GetEntityCoords(hasBox) - while secondsToStart > 0 do - secondsToStart = secondsToStart - 5 - if Config.Enable3DText then - DrawText3D(boxCoords, secondsToStart/1000) - end - Citizen.Wait(0) - end + if Config.DisableMultiplyFireworks then + if hasBox then + return Config.Notification(Config.Translate['CANNOT_START'], 4500, 'error') + end + end + if Config.Fireworks[type] then + local myFirework = Config.Fireworks[type] + local myPed = PlayerPedId() + local myOffset = GetOffsetFromEntityInWorldCoords(myPed, 0, .6, 0) + local fireworkShoots = myFirework.shoots + local secondsToStart = myFirework.timeToStart + reqAnimDict(Config.PlacingAnimation[1]) + TaskPlayAnim(myPed, Config.PlacingAnimation[1], Config.PlacingAnimation[2], -1, -8.0, 3000, 0, 0, false, false, false) + Citizen.Wait((GetAnimDuration(Config.PlacingAnimation[1], Config.PlacingAnimation[2]) * 1000) - 2050) + hasBox = CreateObject(myFirework.prop, myOffset.x, myOffset.y, myOffset.z, true, false, false) + PlaceObjectOnGroundProperly(hasBox) + FreezeEntityPosition(hasBox, true) + Config.Notification(Config.Translate['YOU_PLACE_FIREWORK'], 4500, 'success') + local boxCoords = GetEntityCoords(hasBox) + + -- Countdown display + while secondsToStart > 0 do + secondsToStart = secondsToStart - 5 + if Config.Enable3DText then + DrawText3D(boxCoords, secondsToStart/1000) + end + Citizen.Wait(0) + end - for k, v in pairs(myFirework.particles) do - reqParticle(v.name) - end + -- Handle rocket launch for firework type 1 + local particleOrigin = boxCoords + if myFirework.isRocket then + -- Launch the rocket + particleOrigin = launchRocket(hasBox, myFirework.rocketHeight, myFirework.rocketSpeed) + + -- Wait a moment before explosion + Citizen.Wait(500) + end - while fireworkShoots ~= 0 do - fireworkShoots = fireworkShoots - 1 - for k, v in pairs(myFirework.particles) do - UseParticleFxAsset(v.name) - local effect = StartNetworkedParticleFxNonLoopedAtCoord( - v.effect, - boxCoords.x + (v.randomizeXY == true and math.random(-10, 10) or 0.0), - boxCoords.y + (v.randomizeXY == true and math.random(-10, 10) or 0.0), - boxCoords.z + v.plusHeight, - 0.0, - 0.0, - 0.0, - v.scale, - false, - false, - false - ) - if Config.Debug then - print('[ Shoots left: '..fireworkShoots..' ]', "ID: "..k, v.name, v.effect) - end - Citizen.Wait(v.timeToNextShoot) - end - Citizen.Wait(myFirework.timeBetweenShoots or 300) - end - NetworkFadeOutEntity(hasBox, true, false) - if Config.Debug then - print('Prop is removed') - end - Citizen.Wait(5000) - DeleteEntity(hasBox) - hasBox = nil - end + -- Load particle effects + for k, v in pairs(myFirework.particles) do + reqParticle(v.name) + end + + -- Create firework effects + while fireworkShoots ~= 0 do + fireworkShoots = fireworkShoots - 1 + for k, v in pairs(myFirework.particles) do + UseParticleFxAsset(v.name) + local effect = StartNetworkedParticleFxNonLoopedAtCoord( + v.effect, + particleOrigin.x + (v.randomizeXY == true and math.random(-10, 10) or 0.0), + particleOrigin.y + (v.randomizeXY == true and math.random(-10, 10) or 0.0), + particleOrigin.z + (myFirework.isRocket and 0 or v.plusHeight), + 0.0, + 0.0, + 0.0, + v.scale, + false, + false, + false + ) + if Config.Debug then + print('[ Shoots left: '..fireworkShoots..' ]', "ID: "..k, v.name, v.effect) + end + Citizen.Wait(v.timeToNextShoot) + end + Citizen.Wait(myFirework.timeBetweenShoots or 300) + end + + NetworkFadeOutEntity(hasBox, true, false) + if Config.Debug then + print('Prop is removed') + end + Citizen.Wait(5000) + DeleteEntity(hasBox) + hasBox = nil + end end) RegisterNetEvent('vms_firework:notification', function(message, time, type) - Config.Notification(Config.Translate[message], time, type) -end) \ No newline at end of file + Config.Notification(Config.Translate[message], time, type) +end) diff --git a/resources/[standalone]/vms_firework/config.lua b/resources/[standalone]/vms_firework/config.lua index 17b223d5f..e0f5ce63d 100644 --- a/resources/[standalone]/vms_firework/config.lua +++ b/resources/[standalone]/vms_firework/config.lua @@ -51,12 +51,15 @@ Config.LighterItem = 'lighter' -- Changed from 'bread' to 'lighter' Config.Fireworks = { [1] = { - item = 'firework1', + item = 'firework_1', itemRemovable = true, - command = nil, -- Removed command to only use items - shoots = 50, - prop = "ind_prop_firework_03", - timeToStart = 5500, + command = nil, + shoots = 10, + prop = "ind_prop_firework_01", -- Changed to rocket prop + isRocket = true, -- Add this flag to identify it as a flying rocket + rocketHeight = 50.0, -- How high the rocket should fly + rocketSpeed = 0.5, -- Speed of rocket ascent (lower is faster) + timeToStart = 2000, -- Reduced time to start for better experience timeBetweenShoots = 1250, particles = { {name = "scr_indep_fireworks", effect = "scr_indep_firework_starburst", scale = 2.0, plusHeight = 50.0, randomizeXY = true, timeToNextShoot = 120}, @@ -82,7 +85,7 @@ Config.Fireworks = { item = 'firework3', itemRemovable = true, command = nil, -- Removed command to only use items - shoots = 80, + shoots = 100, prop = "ind_prop_firework_03", timeToStart = 5500, timeBetweenShoots = 250,