159 lines
		
	
	
	
		
			5.6 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			159 lines
		
	
	
	
		
			5.6 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
| -- 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)
 | |
|     local scale = (0.8 / distance) * 2
 | |
|     local fov = (1 / GetGameplayCamFov()) * 100
 | |
|     scale = scale * fov
 | |
|     SetTextScale(0.0 * scale, 0.55 * scale)
 | |
|     SetTextFont(4)
 | |
|     SetTextProportional(1)
 | |
|     SetTextDropShadow()
 | |
|     SetTextColour(240, 240, 240, 185)
 | |
|     BeginTextCommandDisplayText('STRING')
 | |
|     SetTextCentre(true)
 | |
|     AddTextComponentSubstringPlayerName(text)
 | |
|     SetDrawOrigin(coords.xyz, 0)
 | |
|     EndTextCommandDisplayText(0.0, 0.0)
 | |
|     ClearDrawOrigin()
 | |
| end
 | |
| 
 | |
| local function reqAnimDict(dict)
 | |
|     while not HasAnimDictLoaded(dict) do
 | |
|         RequestAnimDict(dict)
 | |
|         Wait(2)
 | |
|     end
 | |
| end
 | |
| 
 | |
| local function reqParticle(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
 | |
| 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)
 | |
|         
 | |
|         -- Countdown display
 | |
|         while secondsToStart > 0 do
 | |
|             secondsToStart = secondsToStart - 5
 | |
|             if Config.Enable3DText then
 | |
|                 DrawText3D(boxCoords, secondsToStart/1000)
 | |
|             end
 | |
|             Citizen.Wait(0)
 | |
|         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
 | |
| 
 | |
|         -- 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)
 | 
