Fire Script Horrible Syncing | Can someone help?

Hello, me and some friends found a fire script, and decided to re-use it on our server. But the problem is that when the fire is stopped, players that are not looking at the fire do not see the fire get stopped. And whats worst is that they can still be damaged by the flame. firemod.zip (3.3 KB)

Feel free to look through it, I just want some help for making a good fire script.

Also, I did not make this mod, we just edited it. All I want is help with synchronization

Server.lua



AddEventHandler("chatMessage", function(source, name, message)
	local args = stringsplit(message, " ");
	if (args[1] == "/fire") then
		CancelEvent();
		if (args[2] == "start") then
			if (not args[3] or not args[4] or not args[5] or not args[6]) then
				sendUsage(source);
			else
				TriggerClientEvent("Fire:start", source, args[3], args[4], args[5], args[6]);
				TriggerClientEvent("chatMessage", source, "",{255, 255, 255}, "^4Fire: ^1started fire");
			end
		elseif (args[2] == "stop") then
			TriggerClientEvent("Fire:stop", source);
			TriggerClientEvent("chatMessage", source, "",{255, 255, 255}, "^4Fire: ^1stopped all fires");
		elseif (args[2] == "preview") then
			if (args[3] == "stop") then
				TriggerClientEvent("Fire:preview", source, args[3], args[4], args[5], args[6], false);

					TriggerClientEvent("chatMessage", source, "",{255, 255, 255}, "^4Fire: ^1disabled preview");
			else
				if (not args[3] or not args[4] or not args[5] or not args[6]) then
					sendUsage(source);
				else
					TriggerClientEvent("Fire:preview", source,args[3], args[4], args[5], args[6], true);
					TriggerClientEvent("chatMessage", source, "",{255, 255, 255}, "^4Fire: ^1enabled preview");
				end
			end
		else
			sendUsage(source);
		end
	end
end);

function sendUsage(source)
	TriggerClientEvent("chatMessage", source, "USAGE",{255, 255, 255}, "/fire start [distance_from_player] [area_size] [density] [scale of flames]");
	TriggerClientEvent("chatMessage", source, "USAGE",{255, 255, 255}, "/fire stop");
	TriggerClientEvent("chatMessage", source, "USAGE",{255, 255, 255}, "/fire preview [distance_from_player] [area_size] [density] [scale of flames]");
	TriggerClientEvent("chatMessage", source, "USAGE",{255, 255, 255}, "/fire preview stop");
end

function newFire(posX, posY, posZ, scale)
	TriggerClientEvent("Fire:newFire", -1, posX, posY, posZ, scale);
end
RegisterServerEvent("Fire:newFire");
AddEventHandler("Fire:newFire", newFire);


------------------------------------------------------------
-- Utils
------------------------------------------------------------

function stringsplit(inputstr, sep)
    if sep == nil then
        sep = "%s"
    end
    local t={} ; i=1
    for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
        t[i] = str
        i = i + 1
    end
    return t
end

Client.lua

local removeFireTimer = math.random(4000, 6000) -- In miliseconds
------------------------------------------------------------
-- Global variables
------------------------------------------------------------

Fire = setmetatable({}, Fire);
Fire.__index = Fire;

Fire.preview = false;
Fire.flames = {};


------------------------------------------------------------
-- Client: preview function
------------------------------------------------------------

function Fire.preview(distance, area, density, scale, toggle)
	Citizen.CreateThread(function()
		Fire.preview = false;
		Wait(100);
		Fire.preview = toggle;
		while Fire.preview do
			Wait(5);
			local heading = GetEntityHeading(GetPlayerPed(-1));
			local localPos = GetEntityCoords(GetPlayerPed(-1));
			local x = localPos.x + math.cos(math.rad(heading+90)) * distance;
			local y = localPos.y + math.sin(math.rad(heading+90)) * distance;
			local z = localPos.z;

			-- Display a circle for the area
			local angle = 0;
			while angle < 360 do
				local circle_x = x + math.cos(math.rad(angle)) * area/2;
				local circle_y = y + math.sin(math.rad(angle)) * area/2;
				local circle_x_next = x + math.cos(math.rad(angle + 1)) * area/2;
				local circle_y_next = y + math.sin(math.rad(angle + 1)) * area/2;
				local _, circle_z = GetGroundZFor_3dCoord(circle_x, circle_y, localPos.z + 5.0);
				local _, circle_z_next = GetGroundZFor_3dCoord(circle_x_next, circle_y_next, localPos.z);
				DrawLine(circle_x, circle_y, circle_z + 0.05, circle_x_next, circle_y_next, circle_z_next + 0.05, 0, 0, 255, 255);
				angle = angle + 1;
			end

			-- Display crosses at fire locations
			local area_x = x - area/2;
			local area_y = y - area/2;
			local area_x_max = x + area/2;
			local area_y_max = y + area/2;
			local step = math.ceil(area / density);
			while area_x <= area_x_max do
				area_y = y - area/2;
				while area_y <= area_y_max do
					if (GetDistanceBetweenCoords(x, y, z, area_x, area_y, 0, false) < area/2) then
						local _, area_z = GetGroundZFor_3dCoord(area_x, area_y, localPos.z + 5.0);
						DrawLine(area_x - 0.25, area_y - 0.25, area_z + 0.05, area_x + 0.25, area_y + 0.25, area_z + 0.05, 255, 0, 0, 255);
						DrawLine(area_x - 0.25, area_y + 0.25, area_z + 0.05, area_x + 0.25, area_y - 0.25, area_z + 0.05, 255, 0, 0, 255);
					end
					area_y = area_y + step;
				end
				area_x = area_x + step;
			end
		end
	end)
end

RegisterNetEvent("Fire:preview");
AddEventHandler("Fire:preview", Fire.preview)


------------------------------------------------------------
-- Client: start fire function
------------------------------------------------------------

function Fire.start(distance, area, density, scale)
	local heading = GetEntityHeading(GetPlayerPed(-1));
	local localPos = GetEntityCoords(GetPlayerPed(-1));
	local x = localPos.x + math.cos(math.rad(heading+90)) * distance;
	local y = localPos.y + math.sin(math.rad(heading+90)) * distance;
	local z = localPos.z;
	local area_x = x - area/2;
	local area_y = y - area/2;
	local area_x_max = x + area/2;
	local area_y_max = y + area/2;
	local step = math.ceil(area / density);

	-- Loop through a square, with steps based on density
	while area_x <= area_x_max do
		area_y = y - area/2;
		while area_y <= area_y_max do
			-- Check the distance to the center to make it into a circle only
			if (GetDistanceBetweenCoords(x, y, z, area_x, area_y, 0, false) < area/2) then
				local _, area_z = GetGroundZFor_3dCoord(area_x, area_y, localPos.z + 5.0);
				-- Fire.newFire(area_x, area_y, area_z, scale);
				TriggerServerEvent("Fire:newFire", area_x, area_y, area_z, scale);
			end
			area_y = area_y + step;
		end
		area_x = area_x + step;
	end
end
RegisterNetEvent("Fire:start");
AddEventHandler("Fire:start", Fire.start);

function Fire.newFire(posX, posY, posZ, scale)
	-- Load the fire particle
	if (not HasNamedPtfxAssetLoaded("core")) then
		RequestNamedPtfxAsset("core");
		local waitTime = 0;
		while not HasNamedPtfxAssetLoaded("core") do
			if (waitTime >= 1000) then
				RequestNamedPtfxAsset("core");
				waitTime = 0;
			end
			Wait(10);
			waitTime = waitTime + 10;
		end
	end
	UseParticleFxAssetNextCall("core");

	-- Make both a standard fire and a big fire particle on top of it
	local fxHandle = StartParticleFxLoopedAtCoord("ent_ray_ch2_farm_fire_dble", posX, posY, posZ + 0.25, 0.0, 0.0, 0.0, scale + 0.001, false, false, false, false);
	local fireHandle = StartScriptFire(posX, posY, posZ + 0.25, 0, false);
	Fire.flames[#Fire.flames + 1] = {fire = fireHandle, ptfx = fxHandle, pos = {x = posX, y = posY, z = posZ + 0.05}};
end
RegisterNetEvent("Fire:newFire");
AddEventHandler("Fire:newFire", Fire.newFire);


------------------------------------------------------------
-- Client: stop all fires function
------------------------------------------------------------

function Fire.stop()
	for i, flame in pairs(Fire.flames) do
		if DoesParticleFxLoopedExist(flame.ptfx) then
			StopParticleFxLooped(flame.ptfx, 1);
			RemoveParticleFx(flame.ptfx, 1);
		end
		RemoveScriptFire(flame.fire);
		StopFireInRange(flame.pos.x, flame.pos.y, flame.pos.z, 20.0);
		table.remove(Fire.flames, i);
	end
end
RegisterNetEvent("Fire:stop");
AddEventHandler("Fire:stop", Fire.stop);


------------------------------------------------------------
-- Client: Handle fires
------------------------------------------------------------

Citizen.CreateThread(function()
	while true do
		Wait(10);
		-- Loop through all the fires
		for i, flame in pairs(Fire.flames) do
			if DoesParticleFxLoopedExist(flame.ptfx) then
				-- If there are no more 'normal' fire next to the big fire particle, remove the particle
				if (GetNumberOfFiresInRange(flame.pos.x, flame.pos.y, flame.pos.z, 0.2) <= 1) then
                    Citizen.Wait(removeFireTimer)
					StopParticleFxLooped(flame.ptfx, 1);
					RemoveParticleFx(flame.ptfx, 1);
					RemoveScriptFire(flame.fire);
					table.remove(Fire.flames, i);
				end
			end
		end
	end
end)

Add me on discord if you think you want to help make a good release some day. : Syme Robinson#7901

EMAIL