[Release] Safe Zone(s) Updated 9/10/18

I edited this a bit more and have been running it on my development server. There are a few things you should implement if you have no already done so just to make sure and rule these out.

1.) server.cfg file: Make sure you have pNotify starting before zone.

start pNotify
start zone

2.) __resource.lua file: set dependency to pNotify

resource_manifest_version '77731fab-63ca-442c-a67b-abc70f28dfa5'

dependency "pNotify"
client_script "client.lua"

3.) I moved your local player = GetPlayerPed(-1) to inside your looping thread. The id can change over time and if it’s only being collected once at the first run time then it can stop working once this happens. I also removed friendly fire, this shouldn’t be needed. I moved your god mode up inside of the statements so they only get set once when the notification is going to pNotify.

local inzone = 0
local notifIn = false
local notifOut = false

Citizen.CreateThread(function()
	while not NetworkIsPlayerActive(PlayerId()) do
		Citizen.Wait(0)
	end
	
	while true do
		Citizen.Wait(0)
		local player = GetPlayerPed(-1)
		local x,y,z = table.unpack(GetEntityCoords(player, true))
		local dist = GetDistanceBetweenCoords(x,y,z,1847.916015625,3675.8190917968,33.767009735108,true)

		if dist <= 50.0 then
			if not notifIn then
				SetEntityInvincible(player,true)
				TriggerEvent("pNotify:SendNotification",{
					text = "<b style='color:#1E90FF'>You are in a SafeZone</b>",
					type = "success",
					timeout = (3000),
					layout = "bottomcenter",
					queue = "global"
				})
				notifIn = true
				notifOut = false
			end
		else
			if not notifOut then
				SetEntityInvincible(player,false)
				TriggerEvent("pNotify:SendNotification",{
					text = "<b style='color:#1E90FF'>You are in NO LONGER a SafeZone</b>",
					type = "error",
					timeout = (3000),
					layout = "bottomcenter",
					queue = "global"
				})
				notifOut = true
				notifIn = false
			end
		end
	end
end)

Ok. Updated this, and now it should be pretty damn clean. No BS force restarts. This however does not enable God mode. @anders suggested that it could be interfereing with another resource that uses either SetEntityInvincible or SetPlayerInvincible. So I decided to just go with the FF option. Let me know if anyone has any problems!

1 Like

This is solid. Thanks man MVP!

1 Like

any update in adding more then one coordonate?

So this is what Im working on right now trying to get multiple locations. Im trying to use vdist. This seems to add the multiple locations. However it bugs the rest of it out… It will spam notifcations, and disregard the whole “safe” part of the script(FF, no weapons) Anyone have experience with vdist? Ive looked at a few other scripts that use it and tried to intergrate it into mine here. I think i dont have the “for k in” in the right spot?

local notifIn = false
local notifOut = false

local zones = {
	{ x = 1847.916015625, y = 3675.8190917968, z = 33.767009735108 },
	{ x = -1688.43811035156, y = -1073.62536621094, z = 13.1521873474121 },
	{ x = -2195.1352539063, y = 4288.7290039063, z = 49.173923492432 }
}

Citizen.CreateThread(function()
	while not NetworkIsPlayerActive(PlayerId()) do
		Citizen.Wait(0)
	end

	while true do
		Citizen.Wait(0)
		for k in pairs(zones)do
			local player = GetPlayerPed(-1)
			local pedpos = GetEntityCoords(player)
			local dist = Vdist(pedpos.x, pedpos.y, pedpos.z, zones[k].x, zones[k].y, zones[k].z)
		

			if dist <= 50.0 then
				if not notifIn then
					NetworkSetFriendlyFireOption(false)
					SetCurrentPedWeapon(player,GetHashKey("WEAPON_UNARMED"),true)
					TriggerEvent("pNotify:SendNotification",{
						text = "<b style='color:#1E90FF'>You are in a SafeZone</b>",
						type = "success",
						timeout = (3000),
						layout = "bottomcenter",
						queue = "global"
					})
					notifIn = true
					notifOut = false
				end
			else
				if not notifOut then
					NetworkSetFriendlyFireOption(true)
					TriggerEvent("pNotify:SendNotification",{
						text = "<b style='color:#1E90FF'>You are in NO LONGER a SafeZone</b>",
						type = "error",
						timeout = (3000),
						layout = "bottomcenter",
						queue = "global"
					})
					notifOut = true
					notifIn = false
				end
			end
		
			if notifIn then
				DisableControlAction(2, 37, true) -- disable weapon
				if IsDisabledControlJustPressed(2, 37) then
					TriggerEvent("pNotify:SendNotification",{
						text = "<b style='color:#1E90FF'>You can not use weapons in a Safe Zone</b>",
						type = "error",
						timeout = (3000),
						layout = "bottomcenter",
						queue = "global"
					})
				end
			end
		end
	end
end)
Old Tries
Click me
local notifIn = false
local notifOut = false

local zones = {
	{ ['x'] = 1847.916015625, ['y'] = 3675.8190917968, ['z'] = 33.767009735108 },
	{ ['x'] = -1688.43811035156, ['y'] = -1073.62536621094, ['z'] = 13.1521873474121 },
	{ ['x'] = -2195.1352539063, ['y'] = 4288.7290039063, ['z'] = 49.173923492432 },
}

Citizen.CreateThread(function()
	while not NetworkIsPlayerActive(PlayerId()) do
		Citizen.Wait(0)
	end

	while true do
		Citizen.Wait(0)
		local player = GetPlayerPed(-1)
		local pedpos = (GetEntityCoords(player, true)
		local x,y,z = table.unpack(GetEntityCoords(player, true))
		local dist = GetDistanceBetweenCoords(x,y,z,1847.916015625,3675.8190917968,33.767009735108,true)

		for k,v in ipairs(zones) do
			if(Vdist(v.x, v.y, v.z, x, y ,z ) <= 50) then
				if not notifIn then
					NetworkSetFriendlyFireOption(false)
					SetCurrentPedWeapon(player,GetHashKey("WEAPON_UNARMED"),true)
					TriggerEvent("pNotify:SendNotification",{
						text = "<b style='color:#1E90FF'>You are in a SafeZone</b>",
						type = "success",
						timeout = (3000),
						layout = "bottomcenter",
						queue = "global"
					})
					notifIn = true
					notifOut = false
				end
			else
				if not notifOut then
					NetworkSetFriendlyFireOption(true)
					TriggerEvent("pNotify:SendNotification",{
						text = "<b style='color:#1E90FF'>You are in NO LONGER a SafeZone</b>",
						type = "error",
						timeout = (3000),
						layout = "bottomcenter",
						queue = "global"
					})
					notifOut = true
					notifIn = false
				end
			end
			if notifIn then
				DisableControlAction(2, 37, true) -- disable weapon
				if IsDisabledControlJustPressed(2, 37) then
					TriggerEvent("pNotify:SendNotification",{
						text = "<b style='color:#1E90FF'>You can not use weapons in a Safe Zone</b>",
						type = "error",
						timeout = (3000),
						layout = "bottomcenter",
						queue = "global"
					})
				end
			end
		end
	end
end)

Im not sure if it needs to be

for k,v in ipairs(zones) do
			if(Vdist(v.x, v.y, v.z, x, y ,z ) <= 50) then

or

for k,v in ipairs(zones) do
			if(Vdist(v.x, v.y, v.z, pedpos.x, pedpos.y ,pedpos.z ) <= 50) then

Or if im using it right at all, first time trying this :stuck_out_tongue:

Edit:
The way i had it in the click me seemed to spam the shit out of the Noti

Edit2:

Trying to keep the vdist sperate from the loop?

Click me 2
local notifIn = false
local notifOut = false

Citizen.CreateThread(function()
	while not NetworkIsPlayerActive(PlayerId()) do
		Citizen.Wait(0)
	end
	
	while true do
		Citizen.Wait(0)
		local player = GetPlayerPed(-1)
		local x,y,z = table.unpack(GetEntityCoords(player, true))
		local dist = 0
		--local dist = GetDistanceBetweenCoords(x,y,z,1847.916015625,3675.8190917968,33.767009735108,true)


		local zones = {
			{ ['x'] = 1847.916015625, ['y'] = 3675.8190917968, ['z'] = 33.767009735108 },
			{ ['x'] = -1688.43811035156, ['y'] = -1073.62536621094, ['z'] = 13.1521873474121 },
			{ ['x'] = -2195.1352539063, ['y'] = 4288.7290039063, ['z'] = 49.173923492432 }
		}

		for k,v in ipairs(zones) do
			if (Vdist( v.x, v.y, v.z, x, y, z) <= 50) then
				dist = 1
			else
				dist = 0
			end
		end

		if dist == 1 then
			if not notifIn then
				NetworkSetFriendlyFireOption(false)
				SetCurrentPedWeapon(player,GetHashKey("WEAPON_UNARMED"),true)
				TriggerEvent("pNotify:SendNotification",{
					text = "<b style='color:#1E90FF'>You are in a SafeZone</b>",
					type = "success",
					timeout = (3000),
					layout = "bottomcenter",
					queue = "global"
				})
				notifIn = true
				notifOut = false
			end
		else
			if not notifOut then
				NetworkSetFriendlyFireOption(true)
				TriggerEvent("pNotify:SendNotification",{
					text = "<b style='color:#1E90FF'>You are in NO LONGER a SafeZone</b>",
					type = "error",
					timeout = (3000),
					layout = "bottomcenter",
					queue = "global"
				})
				notifOut = true
				notifIn = false
			end
		end
		if notifIn then
			DisableControlAction(2, 37, true) -- disable weapon
			if IsDisabledControlJustPressed(2, 37) then
				TriggerEvent("pNotify:SendNotification",{
					text = "<b style='color:#1E90FF'>You can not use weapons in a Safe Zone</b>",
					type = "error",
					timeout = (3000),
					layout = "bottomcenter",
					queue = "global"
				})
			end
		end
	end
end)

You’re on the right track @davewazere, take a look at this and see if it can help you at all. Seems to work as intended on my end.

local zones = {
	{ ['x'] = 1847.916015625, ['y'] = 3675.8190917968, ['z'] = 33.767009735108},
	{ ['x'] = -1688.43811035156, ['y'] = -1073.62536621094, ['z'] = 13.1521873474121 },
	{ ['x'] = -2195.1352539063, ['y'] = 4288.7290039063, ['z'] = 49.173923492432 }
}

local notifIn = false
local notifOut = false
local closestZone = 1

Citizen.CreateThread(function()
	while not NetworkIsPlayerActive(PlayerId()) do
		Citizen.Wait(0)
	end
	
	for i = 1, #zones, 1 do
		local szBlip = AddBlipForCoord(zones[i].x, zones[i].y, zones[i].z)
		SetBlipAsShortRange(szBlip, true)
		SetBlipColour(szBlip, 2)
		SetBlipSprite(szBlip, 398)
		BeginTextCommandSetBlipName("STRING")
		AddTextComponentString("SAFE ZONE")
		EndTextCommandSetBlipName(szBlip)
	end
	
end)

Citizen.CreateThread(function()
	while not NetworkIsPlayerActive(PlayerId()) do
		Citizen.Wait(0)
	end
	
	while true do
		local playerPed = GetPlayerPed(-1)
		local x, y, z = table.unpack(GetEntityCoords(playerPed, true))
		local minDistance = 100000
		for i = 1, #zones, 1 do
			dist = Vdist(zones[i].x, zones[i].y, zones[i].z, x, y, z)
			if dist < minDistance then
				minDistance = dist
				closestZone = i
			end
		end
		Citizen.Wait(15000)
	end
end)

Citizen.CreateThread(function()
	while not NetworkIsPlayerActive(PlayerId()) do
		Citizen.Wait(0)
	end
	
	while true do
		Citizen.Wait(1000)
		local player = GetPlayerPed(-1)
		local x,y,z = table.unpack(GetEntityCoords(player, true))
		local dist = Vdist(zones[closestZone].x, zones[closestZone].y, zones[closestZone].z, x, y, z)
	
		if dist <= 50 then
			if not notifIn then
				NetworkSetFriendlyFireOption(false)
				ClearPlayerWantedLevel(PlayerId())
				TriggerEvent("pNotify:SendNotification",{
					text = "<b style='color:#1E90FF'>You are in a SafeZone</b>",
					type = "success",
					timeout = (3000),
					layout = "bottomcenter",
					queue = "global"
				})
				notifIn = true
				notifOut = false
			end
			
			SetCurrentPedWeapon(player,GetHashKey("WEAPON_UNARMED"),true)
			DisableControlAction(2, 37, true)
			if IsDisabledControlJustPressed(2, 37) then
				TriggerEvent("pNotify:SendNotification",{
					text = "<b style='color:#1E90FF'>You can not use weapons in a Safe Zone</b>",
					type = "error",
					timeout = (3000),
					layout = "bottomcenter",
					queue = "global"
				})
			end
		else
			if not notifOut then
				NetworkSetFriendlyFireOption(true)
				TriggerEvent("pNotify:SendNotification",{
					text = "<b style='color:#1E90FF'>You are in NO LONGER a SafeZone</b>",
					type = "error",
					timeout = (3000),
					layout = "bottomcenter",
					queue = "global"
				})
				notifOut = true
				notifIn = false
			end
		end
	end
end)

So basically you have to have the part that is calling your distance from any one of the coords in the table in a separate function, is what I was missing? Is that what was casuing the horrendous spam(looping i assume?)

Also I see you added a blip as well, niceee. I assume I can just do the same with markers as well. Basically copy paste that block and change up the natives?

Lastly, could you still have used that - for k,v in pairs - in this situation as well? Or is it a different use case all together? What is the difference in the one I was trying to use and the i = 1, #tablename? Ive only seen for k,v in alot of the scripts I have on my server I look through.

Alright, I think this may be the final version :smiley:
Thank you so much for all your help!!!

I think Im also going to rework this into a sort of “No Go Zone” ordeal. Where, instead of doing the FF, it will teleport your back to a specific location if you enter a zone, or maybe even just leave a zone. :smiley:

Maybe be able to just read a players Y coords and trigger when above or below a certain value. Thus keeping players either in the north(what I want :stuck_out_tongue: ) or down in the city. Keep that RP control XD

The first thread executes once and creates the map blips, then it finishes and does not run again.

The second thread loops once every 15 seconds and determines which of the zones in your table is closest to the player coords and then sets that as the closest zone for use by the third thread. I took this approach for performance reasons so you don’t need to loop through the table on every tick. Others may put a big list of coords in there and it becomes a waste of resource.

The third thread is nearly identical to your original single safe zone script with the difference being that it is only looking to see whether the player is within 50 distance of the coords that were defined as closest coords in the prior thread and only runs once a second instead of once per tick.

I only use for k,v loops on tables that are not indexed. If you have a table whose keys are say ped ID’s, vehicle ID’s, names, etc, you have to loop these by key/value. For tables that are indexed like this script has performance is better if you iterate through them by index like I have above. Hope that makes sense.

If you want to have markers in here you have to add the marker in the third thread where it can be run on every tick and change the Citizen.Wait from 1000 to either 0 or 1. If you don’t do that then you will have blinking markers on the screen. You would add the create marker line right after the Citizen.Wait, not inside the if statement(s). Alternatively you could create a fourth thread that does infinite loop with Citizen.Wait 0 or 1 and have that draw the marker for the coords defined by the closestZone variable.

zones[closestZone].x, zones[closestZone].y, zones[closestZone].z

You have some cool ideas, I look forward to seeing where you go with this, has potential to be used in unique game modes :slight_smile:

Damn dood. Thank you again so much for all your help! That explanation was crisp :slight_smile: And thanks! Im just now starting to get an actual grasp this and Im loving it :slight_smile:

how can I do this to this script I saw some server have it

1 Like

Change this part:

TriggerEvent("pNotify:SendNotification",{
					text = "<b style='color:#1E90FF'>You are in a SafeZone</b>",
					type = "success",
					timeout = (3000),
					layout = "bottomcenter",
					queue = "global"
				})

to

DrawMissionText2("Your text", 5000)

( You can use ~r~, ~g~, ~b~, etc. for colors.
So like "You ~r~ ARE NOT ~w~ in a ~g~Safe Zone~w~!
Would be “You” in white | “ARE NOT” in red | " in a " in white | “safe zone” in green | and the ’ ! ’ in white. )

and add this to the bottom of the script:

function DrawMissionText2(m_text, showtime)
	ClearPrints()
	SetTextEntry_2("STRING")
	AddTextComponentString(m_text)
	DrawSubtitleTimed(showtime, 1)
end

Edit: Is that at the bottom of your screen or pNotify?

If its pNotify disregard all of what I said., you will have to refer to the pNoty post:

you can do the writing I gave you in the picture on the bottom left

and post the entire script here?

in the car you can take the gun and shoot and kill someone
get out of the car with your gun and you can kill
you still have working on

Hm, didnt even think to test that! Ill work on that later today or tonight. I assume there is a native for dealing with the ingame DriveBy function. Ill look into it! Thanks for the report!

Edit tested it out and yes, bug indeed.

1 Like

I still dont know what you mean, man. Is that a pNotification or is that just text on your screen at the bottom

Updated with a workaround, for now, to the Issue provided by @kheire007 .

– It disables firing all together now if in the zone.
–If they are able to pull out a gun, pressing the FIRE(LMB) button will cause you to go unarmed and trigger a notification.
–If they have a weapon out and try to access the weapon wheel(TAB) again in the zone it will un-arm them.

1 Like

many thanks :slight_smile:

1 Like

working fine :slight_smile:


1 Like

can you please help me?