diff --git a/init.lua b/init.lua index 646a1f0..a13bd78 100644 --- a/init.lua +++ b/init.lua @@ -110,7 +110,7 @@ Bridge.RegisterModule("Raycast", cLib.Raycast) Bridge.RegisterModule("PlaceableObject", cLib.PlaceableObject) Bridge.RegisterModule("Point", cLib.Point) Bridge.RegisterModule("Object", cLib.Object) - +Bridge.RegisterModule("Particle", cLib.Particle) -- Fill the bridge tables with player data. diff --git a/lib/particles/client/particles.lua b/lib/particles/client/particles.lua index 89ed5f2..f0cc83a 100644 --- a/lib/particles/client/particles.lua +++ b/lib/particles/client/particles.lua @@ -1,22 +1,20 @@ Particle = {} -Particles = {} - ---- Load a particle dictionary. This function will block until the dictionary is loaded. ---- @param dict string -- The name of the particle dictionary to load. ---- @return boolean -- Returns true if the dictionary was loaded successfully, false otherwise. ---- @throws string -- Throws an error if the dictionary fails to load after 100 attempts. -function Particle.LoadDict(dict) - RequestNamedPtfxAsset(dict) +---Loads a ptfx asset into memory. +---@param dict string +---@return boolean +function LoadPtfxAsset(dict) local failed = 100 while not HasNamedPtfxAssetLoaded(dict) and failed >= 0 do + RequestNamedPtfxAsset(dict) failed = failed - 1 - Wait(50) + Wait(100) end - assert(failed >= 0, "Failed to load particle dictionary: " .. dict) - return true + assert(failed > 0, "Failed to load dict asset: " .. dict) + return HasNamedPtfxAssetLoaded(dict) end + --- Create a particle effect at the specified position and rotation. --- @param dict string --- @param ptfx string @@ -28,26 +26,57 @@ end --- @param loopLength number|nil --- @return number|nil ptfxHandle -- The handle of the particle effect, or nil if it failed to create. function Particle.Create(dict, ptfx, pos, rot, scale, color, looped, loopLength) - if not Particle.LoadDict(dict) then return end - UseParticleFxAssetNextCall(dict) - local handle = nil - if looped then - handle = StartParticleFxLoopedAtCoord(ptfx, pos.x, pos.y, pos.z, rot.x, rot.y, rot.z, scale, false, false, false, false) - SetParticleFxLoopedColour(handle, color.x, color.y, color.z, false) - if loopLength then - Wait(loopLength) - StopParticleFxLooped(handle, 0) - RemoveParticleFx(handle, false) - end - else + LoadPtfxAsset(dict) + CreateThread(function() + UseParticleFxAssetNextCall(dict) SetParticleFxNonLoopedColour(color.x, color.y, color.z) - handle = StartParticleFxNonLoopedAtCoord(ptfx, pos.x, pos.y, pos.z, rot.x, rot.y, rot.z, scale, false, false, false) - RemoveParticleFx(handle, false) - end - return handle + if looped then + StartParticleFxLoopedAtCoord(ptfx, pos.x, pos.y, pos.z, rot.x, rot.y, rot.z, scale, false, false, false, false) + if loopLength then + Wait(loopLength) + RemoveParticleFxInRange(pos.x, pos.y, pos.z, 0.01) + end + else + StartParticleFxNonLoopedAtCoord(ptfx, pos.x, pos.y, pos.z, rot.x, rot.y, rot.z, scale, false, false, false, false) + end + RemoveNamedPtfxAsset(ptfx) + end) end --- need to add looping effects (regarless of if its a looped particle or not) +function Particle.CreateOnEntity(dict, ptfx, entity, offset, rot, scale, color, looped, loopLength) + LoadPtfxAsset(dict) + UseParticleFxAssetNextCall(dict) + SetParticleFxNonLoopedColour(color.x, color.y, color.z) + local particle = nil + if looped then + particle = StartNetworkedParticleFxLoopedOnEntity(ptfx, entity, offset.x, offset.y, offset.z, rot.x, rot.y, rot.z, scale, false, false, false) + if loopLength then + Wait(loopLength) + RemoveParticleFxFromEntity(entity) + end + else + particle = StartNetworkedParticleFxLoopedOnEntity(ptfx, entity, offset.x, offset.y, offset.z, rot.x, rot.y, rot.z, scale, false, false, false) + end + RemoveNamedPtfxAsset(ptfx) + return particle +end +function Particle.CreateOnEntityBone(dict, ptfx, entity, bone, offset, rot, scale, color, looped, loopLength) + LoadPtfxAsset(dict) + UseParticleFxAssetNextCall(dict) + SetParticleFxNonLoopedColour(color.x, color.y, color.z) + local particle = nil + if looped then + particle = StartNetworkedParticleFxLoopedOnEntityBone(ptfx, entity, offset.x, offset.y, offset.z, rot.x, rot.y, rot.z, bone, scale, false, false, false) + if loopLength then + Wait(loopLength) + RemoveParticleFxFromEntity(entity) + end + else + particle = StartNetworkedParticleFxNonLoopedOnEntityBone(ptfx, entity, offset.x, offset.y, offset.z, rot.x, rot.y, rot.z, bone, scale, false, false, false) + end + RemoveNamedPtfxAsset(ptfx) + return particle +end return Particle \ No newline at end of file