├── README.md ├── client.lua ├── config.lua ├── fxmanifest.lua └── server.lua /README.md: -------------------------------------------------------------------------------- 1 | ![FIREWORKS](https://user-images.githubusercontent.com/60104107/209708278-b9b55a71-8d64-4917-8c86-4f7002922e10.png) 2 | 3 | # vms_firework 4 | 5 | ### https://discord.gg/k4YNwYxE4h 6 | -------------------------------------------------------------------------------- /client.lua: -------------------------------------------------------------------------------- 1 | local function DrawText3D(coords, text) 2 | local camCoords = GetFinalRenderedCamCoord() 3 | local distance = #(coords - camCoords) 4 | local scale = (0.8 / distance) * 2 5 | local fov = (1 / GetGameplayCamFov()) * 100 6 | scale = scale * fov 7 | SetTextScale(0.0 * scale, 0.55 * scale) 8 | SetTextFont(4) 9 | SetTextProportional(1) 10 | SetTextDropShadow() 11 | SetTextColour(240, 240, 240, 185) 12 | BeginTextCommandDisplayText('STRING') 13 | SetTextCentre(true) 14 | AddTextComponentSubstringPlayerName(text) 15 | SetDrawOrigin(coords.xyz, 0) 16 | EndTextCommandDisplayText(0.0, 0.0) 17 | ClearDrawOrigin() 18 | end 19 | 20 | local function reqAnimDict(dict) 21 | while not HasAnimDictLoaded(dict) do 22 | RequestAnimDict(dict) 23 | Wait(2) 24 | end 25 | end 26 | 27 | local function reqParticle(dict) 28 | RequestNamedPtfxAsset(dict) 29 | while not HasNamedPtfxAssetLoaded(dict) do 30 | Wait(1) 31 | end 32 | end 33 | 34 | for k, v in pairs(Config.Fireworks) do 35 | if v.command then 36 | RegisterCommand(v.command, function(source, args, rawCommand) 37 | TriggerEvent('vms_firework:startFirework', k) 38 | end) 39 | end 40 | end 41 | 42 | local hasBox = nil 43 | RegisterNetEvent('vms_firework:startFirework', function(type) 44 | if Config.DisableMultiplyFireworks then 45 | if hasBox then 46 | return Config.Notification(Config.Translate['CANNOT_START'], 4500, 'error') 47 | end 48 | end 49 | if Config.Fireworks[type] then 50 | local myFirework = Config.Fireworks[type] 51 | local myPed = PlayerPedId() 52 | local myOffset = GetOffsetFromEntityInWorldCoords(myPed, 0, .6, 0) 53 | local fireworkShoots = myFirework.shoots 54 | local secondsToStart = myFirework.timeToStart 55 | reqAnimDict(Config.PlacingAnimation[1]) 56 | TaskPlayAnim(myPed, Config.PlacingAnimation[1], Config.PlacingAnimation[2], -1, -8.0, 3000, 0, 0, false, false, false) 57 | Citizen.Wait((GetAnimDuration(Config.PlacingAnimation[1], Config.PlacingAnimation[2]) * 1000) - 2050) 58 | hasBox = CreateObject(myFirework.prop, myOffset.x, myOffset.y, myOffset.z, true, false, false) 59 | PlaceObjectOnGroundProperly(hasBox) 60 | FreezeEntityPosition(hasBox, true) 61 | Config.Notification(Config.Translate['YOU_PLACE_FIREWORK'], 4500, 'success') 62 | local boxCoords = GetEntityCoords(hasBox) 63 | while secondsToStart > 0 do 64 | secondsToStart = secondsToStart - 5 65 | if Config.Enable3DText then 66 | DrawText3D(boxCoords, secondsToStart/1000) 67 | end 68 | Citizen.Wait(0) 69 | end 70 | 71 | for k, v in pairs(myFirework.particles) do 72 | reqParticle(v.name) 73 | end 74 | 75 | while fireworkShoots ~= 0 do 76 | fireworkShoots = fireworkShoots - 1 77 | for k, v in pairs(myFirework.particles) do 78 | UseParticleFxAsset(v.name) 79 | local effect = StartNetworkedParticleFxNonLoopedAtCoord( 80 | v.effect, 81 | boxCoords.x + (v.randomizeXY == true and math.random(-10, 10) or 0.0), 82 | boxCoords.y + (v.randomizeXY == true and math.random(-10, 10) or 0.0), 83 | boxCoords.z + v.plusHeight, 84 | 0.0, 85 | 0.0, 86 | 0.0, 87 | v.scale, 88 | false, 89 | false, 90 | false 91 | ) 92 | if Config.Debug then 93 | print('[ Shoots left: '..fireworkShoots..' ]', "ID: "..k, v.name, v.effect) 94 | end 95 | Citizen.Wait(v.timeToNextShoot) 96 | end 97 | Citizen.Wait(myFirework.timeBetweenShoots or 300) 98 | end 99 | NetworkFadeOutEntity(hasBox, true, false) 100 | if Config.Debug then 101 | print('Prop is removed') 102 | end 103 | Citizen.Wait(5000) 104 | DeleteEntity(hasBox) 105 | hasBox = nil 106 | end 107 | end) 108 | 109 | RegisterNetEvent('vms_firework:notification', function(message, time, type) 110 | Config.Notification(Config.Translate[message], time, type) 111 | end) -------------------------------------------------------------------------------- /config.lua: -------------------------------------------------------------------------------- 1 | -- Hi, if you like the script, join the discord: https://discord.gg/k4YNwYxE4h 2 | 3 | Config = {} 4 | 5 | Config.Debug = false 6 | 7 | Config.Core = "ESX" -- "ESX" / "QB-Core" 8 | 9 | if Config.Core == "ESX" then 10 | ESX = exports['es_extended']:getSharedObject() 11 | elseif Config.Core == "QB-Core" then 12 | QBCore = exports['qb-core']:GetCoreObject() 13 | end 14 | 15 | Config.Notification = function(message, time, type) 16 | if type == "success" then 17 | exports["vms_notify"]:Notification("FIREWORK", message, time, "#27FF09", "fa-solid fa-fire") 18 | -- TriggerEvent('esx:showNotification', message) --[ ESX ] 19 | -- TriggerEvent('QBCore:Notify', message, 'success', time) -- [ QB-Core ] 20 | 21 | elseif type == "error" then 22 | exports["vms_notify"]:Notification("FIREWORK", message, time, "#FF0909", "fa-solid fa-fire") 23 | -- TriggerEvent('esx:showNotification', message) --[ ESX ] 24 | -- TriggerEvent('QBCore:Notify', message, 'error', time) -- [ QB-Core ] 25 | 26 | end 27 | end 28 | 29 | Config.Translate = { 30 | ['CANNOT_START'] = "You can't set off several fireworks at once, wait until the current one goes off", -- Only if: Config.DisableMultiplyFireworks = true 31 | ['NEED_LIGHTER'] = "You need have lighter!", -- Only if: Config.NeedLighter = true 32 | ['YOU_PLACE_FIREWORK'] = "You place the firework!", 33 | } 34 | 35 | Config.Enable3DText = true -- 3DText on fireworks, shows the time to go off 36 | 37 | Config.PlacingAnimation = {'anim@mp_fireworks', 'place_firework_3_box'} -- Animation of placing firework 38 | 39 | Config.DisableMultiplyFireworks = false -- if you set it true, the player will be able to place one firework, the next one only after he finishes shooting 40 | 41 | Config.NeedLighter = true 42 | Config.LighterItem = 'bread' 43 | 44 | 45 | Config.Fireworks = { 46 | [1] = { 47 | item = 'firework_1', -- name or nil 48 | itemRemovable = true, -- if it is on the item, is it to be removed after use 49 | command = 'fire_1', -- name of command or nil 50 | shoots = 50, -- count of shots 51 | prop = "ind_prop_firework_03", 52 | timeToStart = 5500, -- +/- 5000 == 5 seconds 53 | timeBetweenShoots = 1250, 54 | particles = { 55 | {name = "scr_indep_fireworks", effect = "scr_indep_firework_starburst", scale = 2.0, plusHeight = 50.0, randomizeXY = true, timeToNextShoot = 120}, 56 | {name = "proj_indep_firework", effect = "scr_indep_firework_grd_burst", scale = 2.0, plusHeight = 50.0, randomizeXY = true, timeToNextShoot = 300}, 57 | {name = "proj_indep_firework", effect = "scr_indep_firework_air_burst", scale = 2.0, plusHeight = 50.0, randomizeXY = true, timeToNextShoot = 600}, 58 | }, 59 | }, 60 | [2] = { 61 | item = 'firework_2', 62 | itemRemovable = true, 63 | command = 'fire_2', 64 | shoots = 80, 65 | prop = "ind_prop_firework_03", 66 | timeToStart = 5500, 67 | timeBetweenShoots = 250, 68 | particles = { 69 | {name = "scr_indep_fireworks", effect = "scr_indep_firework_trailburst", scale = 2.0, plusHeight = 10.0, randomizeXY = true, timeToNextShoot = 125}, 70 | {name = "proj_indep_firework_v2", effect = "scr_firework_indep_burst_rwb", scale = 1.0, plusHeight = 50.0, randomizeXY = true, timeToNextShoot = 125}, 71 | {name = "proj_xmas_firework", effect = "scr_firework_xmas_ring_burst_rgw", scale = 1.0, plusHeight = 50.0, randomizeXY = true, timeToNextShoot = 125}, 72 | }, 73 | }, 74 | [3] = { 75 | item = 'firework_3', 76 | itemRemovable = true, 77 | command = 'fire_3', 78 | shoots = 80, 79 | prop = "ind_prop_firework_03", 80 | timeToStart = 5500, 81 | timeBetweenShoots = 250, 82 | particles = { 83 | {name = "proj_indep_firework", effect = "scr_indep_firework_air_burst", scale = 1.0, plusHeight = 50.0, randomizeXY = true, timeToNextShoot = 125}, 84 | {name = "proj_indep_firework_v2", effect = "scr_firework_indep_spiral_burst_rwb", scale = 1.0, plusHeight = 50.0, randomizeXY = true, timeToNextShoot = 125}, 85 | {name = "proj_indep_firework_v2", effect = "scr_firework_indep_repeat_burst_rwb", scale = 1.0, plusHeight = 50.0, randomizeXY = true, timeToNextShoot = 125}, 86 | {name = "scr_indep_fireworks", effect = "scr_indep_firework_starburst", scale = 1.0, plusHeight = 50.0, randomizeXY = true, timeToNextShoot = 125}, 87 | }, 88 | }, 89 | [4] = { 90 | item = 'firework_4', 91 | itemRemovable = true, 92 | command = 'fire_4', 93 | shoots = 50, 94 | prop = "ind_prop_firework_03", 95 | timeToStart = 5000, 96 | timeBetweenShoots = 550, 97 | particles = { 98 | {name = "scr_indep_fireworks", effect = "scr_indep_firework_trailburst", scale = 4.0, plusHeight = 50.0, randomizeXY = true, timeToNextShoot = 10}, 99 | }, 100 | }, 101 | [5] = { 102 | item = 'fontain_4', 103 | itemRemovable = true, 104 | command = 'fontain_4', 105 | shoots = 80, 106 | prop = "ind_prop_firework_04", 107 | timeToStart = 3500, 108 | timeBetweenShoots = 700, 109 | particles = { 110 | {name = "scr_indep_fireworks", effect = "scr_indep_firework_fountain", scale = 0.25, plusHeight = 0.25, randomizeXY = false, timeToNextShoot = 500}, 111 | }, 112 | }, 113 | --[[ 114 | [6] = { 115 | item = nil, 116 | itemRemovable = false, 117 | command = '', 118 | shoots = 1, 119 | prop = "ind_prop_firework_04", 120 | timeToStart = 1000, 121 | timeBetweenShoots = 100, 122 | particles = { 123 | -- {name = "proj_indep_firework", effect = "scr_indep_firework_grd_burst", scale = 2.0, plusHeight = 50.0, randomizeXY = true, timeToNextShoot = 600}, 124 | -- {name = "proj_indep_firework", effect = "scr_indep_firework_air_burst", scale = 2.0, plusHeight = 50.0, randomizeXY = true, timeToNextShoot = 600}, 125 | 126 | -- {name = "proj_indep_firework_v2", effect = "scr_firework_indep_burst_rwb", scale = 1.0, plusHeight = 50.0, randomizeXY = true, timeToNextShoot = 2025}, 127 | -- {name = "proj_indep_firework_v2", effect = "scr_firework_indep_spiral_burst_rwb", scale = 1.0, plusHeight = 50.0, randomizeXY = true, timeToNextShoot = 2025}, 128 | -- {name = "proj_indep_firework_v2", effect = "scr_firework_indep_ring_burst_rwb", scale = 1.0, plusHeight = 50.0, randomizeXY = true, timeToNextShoot = 2025}, 129 | -- {name = "proj_indep_firework_v2", effect = "scr_xmas_firework_burst_fizzle", scale = 1.0, plusHeight = 50.0, randomizeXY = true, timeToNextShoot = 2025}, 130 | -- {name = "proj_indep_firework_v2", effect = "scr_firework_indep_repeat_burst_rwb", scale = 1.0, plusHeight = 50.0, randomizeXY = true, timeToNextShoot = 2025}, 131 | 132 | -- {name = "proj_xmas_firework", effect = "scr_firework_xmas_ring_burst_rgw", scale = 1.0, plusHeight = 50.0, randomizeXY = true, timeToNextShoot = 2025}, 133 | -- {name = "proj_xmas_firework", effect = "scr_firework_xmas_burst_rgw", scale = 1.0, plusHeight = 50.0, randomizeXY = true, timeToNextShoot = 2025}, 134 | -- {name = "proj_xmas_firework", effect = "scr_firework_xmas_repeat_burst_rgw", scale = 1.0, plusHeight = 50.0, randomizeXY = true, timeToNextShoot = 2025}, 135 | -- {name = "proj_xmas_firework", effect = "scr_firework_xmas_spiral_burst_rgw", scale = 1.0, plusHeight = 50.0, randomizeXY = true, timeToNextShoot = 2025}, 136 | 137 | -- {name = "scr_indep_fireworks", effect = "scr_indep_firework_starburst", scale = 1.0, plusHeight = 50.0, randomizeXY = true, timeToNextShoot = 2025}, 138 | -- {name = "scr_indep_fireworks", effect = "scr_indep_firework_shotburst", scale = 1.0, plusHeight = 50.0, randomizeXY = true, timeToNextShoot = 2025}, 139 | -- {name = "scr_indep_fireworks", effect = "scr_indep_firework_trailburst", scale = 1.0, plusHeight = 50.0, randomizeXY = true, timeToNextShoot = 2025}, 140 | -- {name = "scr_indep_fireworks", effect = "scr_indep_firework_trailburst_spawn", scale = 1.0, plusHeight = 50.0, randomizeXY = true, timeToNextShoot = 2025}, 141 | -- {name = "scr_indep_fireworks", effect = "scr_indep_firework_burst_spawn", scale = 1.0, plusHeight = 50.0, randomizeXY = true, timeToNextShoot = 2025}, 142 | -- {name = "scr_indep_fireworks", effect = "scr_indep_firework_fountain", scale = 1.0, plusHeight = 50.0, randomizeXY = true, timeToNextShoot = 2025}, 143 | }, 144 | } 145 | ]] 146 | } 147 | -------------------------------------------------------------------------------- /fxmanifest.lua: -------------------------------------------------------------------------------- 1 | fx_version 'cerulean' 2 | game 'gta5' 3 | lua54 'yes' 4 | 5 | author 'vames™️' 6 | description 'vms_firework' 7 | version '1.0.0' 8 | 9 | shared_script 'config.lua' 10 | 11 | client_scripts { 12 | 'client.lua' 13 | } 14 | 15 | server_scripts { 16 | 'server.lua' 17 | } -------------------------------------------------------------------------------- /server.lua: -------------------------------------------------------------------------------- 1 | if Config.Core == "ESX" then 2 | for k, v in pairs(Config.Fireworks) do 3 | if v.item then 4 | ESX.RegisterUsableItem(v.item, function(source) 5 | local xPlayer = ESX.GetPlayerFromId(source) 6 | if Config.NeedLighter then 7 | local isHaveLighter = xPlayer.getInventoryItem(Config.LighterItem).count 8 | if isHaveLighter == 0 then 9 | return TriggerClientEvent('vms_firework:notification', source, 'NEED_LIGHTER', 5000, 'error') 10 | end 11 | end 12 | if v.itemRemovable then 13 | xPlayer.removeInventoryItem(v.item, 1) 14 | end 15 | TriggerClientEvent('vms_firework:startFirework', source, k) 16 | end) 17 | end 18 | end 19 | elseif Config.Core == "QB-Core" then 20 | for k, v in pairs(Config.Fireworks) do 21 | if v.item then 22 | QBCore.Functions.CreateUseableItem(v.item, function(source, item) 23 | local Player = QBCore.Functions.GetPlayer(source) 24 | if Config.NeedLighter then 25 | local isHaveLighter = Player.Functions.GetItemByName(Config.LighterItem) 26 | if isHaveLighter == nil or isHaveLighter.amount == 0 then 27 | return TriggerClientEvent('vms_firework:notification', source, 'NEED_LIGHTER', 5000, 'error') 28 | end 29 | end 30 | if v.itemRemovable then 31 | Player.Functions.RemoveItem(v.item, 1, false) 32 | end 33 | TriggerClientEvent('vms_firework:startFirework', source, k) 34 | end) 35 | end 36 | end 37 | end --------------------------------------------------------------------------------