Jump to content

cancel functions if its a zombie/ped


kewizzle

Recommended Posts

sooo i wrote this script tonight all works well until i add zombies they keep triggering the functions and causing the timer to not work as intendded.

 

function dxDrawTextOnElement(TheElement,text,height,distance,R,G,B,alpha,size,font,...)
	local x, y, z = getElementPosition(TheElement)
	local x2, y2, z2 = getCameraMatrix()
	local distance = distance or 20
	local height = height or 1

	if (isLineOfSightClear(x, y, z+2, x2, y2, z2, ...)) then
		local sx, sy = getScreenFromWorldPosition(x, y, z+height)
		if(sx) and (sy) then
			local distanceBetweenPoints = getDistanceBetweenPoints3D(x, y, z, x2, y2, z2)
			if(distanceBetweenPoints < distance) then
				dxDrawText(text, sx+2, sy+2, sx, sy, tocolor(R or 255, G or 255, B or 255, alpha or 255), (size or 1)-(distanceBetweenPoints / distance), font or "arial", "center", "center")
			end
		end
	end
end

--Warehouse Zones
createBlip(2577, 2822, 11, 22)
WarehouseCol1 = createColRectangle( 2535, 2796, 80, 50 ) 
WarehouseArea1 = createRadarArea( 2535, 2796, 80, 50, 0, 0, 255, 90, root ) 
setElementData(WarehouseCol1, "warehoue", true)
setElementData(WarehouseArea1, "warehoue", true)

--Leaving the warehouse
function warehouseLeave()
if (getElementType(getRootElement()) == "ped") then return end --thought maybe this would work
		if isElementWithinColShape(localPlayer, WarehouseCol1) == true then
			timertxt = getElementData(localPlayer, "timer")
			Wtimer = dxDrawTextOnElement(localPlayer, "Defend Warehouse: "..timertxt, 1, 20, 255, 0, 255, 255, 5, "arial")
		elseif Wtimer == nil then return
		else
			destroyElement(Wtimer)
	end
end
addEventHandler("onClientRender", getRootElement(), warehouseLeave)
addEventHandler("onClientElementColShapeLeave", getRootElement(), warehouseLeave)

--warehouse timer
function warehoueTimer()
if (getElementType(getRootElement()) == "ped") then return end --thought maybe this would work
timerW = getElementData(localPlayer, "timer")
    if isElementWithinColShape(localPlayer, WarehouseCol1) == true and getElementData(localPlayer, "timer") >= 1 then
		setElementData(localPlayer, "timer", timerW-1)
	elseif isElementWithinColShape(localPlayer, WarehouseCol1) == true and getElementData(localPlayer, "timer") == 0 then
		triggerServerEvent("doSupplyTruck", localPlayer)
	end
end

--Entering warehouse
function warehoueEnter()
if (getElementType(getRootElement()) == "ped") then return end --thought maybe this would work
	if isElementWithinColShape(localPlayer, WarehouseCol1) == true then
			setElementData(localPlayer, "timer", 60)
			:O = setTimer(warehoueTimer, 1000, 61)
		else
		killTimer(:O)
	end
end
addEventHandler("onClientElementColShapeLeave", getRootElement(), warehoueEnter)
addEventHandler("onClientElementColShapeHit", getRootElement(), warehoueEnter)
 --switch from destroyed element source to player source
function switchh()
triggerServerEvent("switch2", localPlayer)
end
addEvent( "switch", true )
addEventHandler( "switch", localPlayer, switchh )

 

Edited by kewizzle
Link to comment

There is a fundamental logic issue in your script. The element type of the root element is "root". Thus the following check will always fail:

if (getElementType(getRootElement()) == "ped") then return end --thought maybe this would work

Do you know about predefined event handler global variables? They are set based on the situation of each issued event. Look them up here. I suggest you to use the source event handler global variable like this:

if (getElementType(source) == "ped") then return end

The following is kind of weird, so please split up the event handler code:

--Leaving the warehouse
function warehouseLeave()
if (getElementType(getRootElement()) == "ped") then return end --thought maybe this would work
		if isElementWithinColShape(localPlayer, WarehouseCol1) == true then
			timertxt = getElementData(localPlayer, "timer")
			Wtimer = dxDrawTextOnElement(localPlayer, "Defend Warehouse: "..timertxt, 1, 20, 255, 0, 255, 255, 5, "arial")
		elseif Wtimer == nil then return
		else
			destroyElement(Wtimer)
	end
end
addEventHandler("onClientRender", getRootElement(), warehouseLeave)	-- OK. because of dxDrawTextOnElement
addEventHandler("onClientElementColShapeLeave", getRootElement(), warehouseLeave)	-- Why???

Good luck with your scripting! ?

Edited by The_GTA
  • Thanks 1
Link to comment
7 hours ago, The_GTA said:

There is a fundamental logic issue in your script. The element type of the root element is "root". Thus the following check will always fail:

if (getElementType(getRootElement()) == "ped") then return end --thought maybe this would work

Do you know about predefined event handler global variables? They are set based on the situation of each issued event. Look them up here. I suggest you to use the source event handler global variable like this:

if (getElementType(source) == "ped") then return end

The following is kind of weird, so please split up the event handler code:

--Leaving the warehouse
function warehouseLeave()
if (getElementType(getRootElement()) == "ped") then return end --thought maybe this would work
		if isElementWithinColShape(localPlayer, WarehouseCol1) == true then
			timertxt = getElementData(localPlayer, "timer")
			Wtimer = dxDrawTextOnElement(localPlayer, "Defend Warehouse: "..timertxt, 1, 20, 255, 0, 255, 255, 5, "arial")
		elseif Wtimer == nil then return
		else
			destroyElement(Wtimer)
	end
end
addEventHandler("onClientRender", getRootElement(), warehouseLeave)	-- OK. because of dxDrawTextOnElement
addEventHandler("onClientElementColShapeLeave", getRootElement(), warehouseLeave)	-- Why???

Good luck with your scripting! ?

it works now except when a zombie is killed within the col shape it resets the timer and speeds it up lol im getting there also maybe has something with the Leave function so ima mess with it

HAHAHAHAHA idk if you remember the drop system i made lmaooo i had to fix the supply run to include those

 

if (getElementType(source) == "ped") or (getElementType(source) == "pickup") or (getElementType(source) == "marker") then return end

i could probably do instead

if not (getElementType(source) == "player") then return end

 

Link to comment

well i been messing with it allllll day and i wrote this entirely myself last night and i just cant figure out this tho i just learned more than i wanted to from the wiki than i was trying too atm lmao but if anyone especially @The_GTA can show me how to return the end of each function if the colshape is not WarehouseCol1 much appreciated.

function dxDrawTextOnElement(TheElement,text,height,distance,R,G,B,alpha,size,font,...)
	local x, y, z = getElementPosition(TheElement)
	local x2, y2, z2 = getCameraMatrix()
	local distance = distance or 20
	local height = height or 1

	if (isLineOfSightClear(x, y, z+2, x2, y2, z2, ...)) then
		local sx, sy = getScreenFromWorldPosition(x, y, z+height)
		if(sx) and (sy) then
			local distanceBetweenPoints = getDistanceBetweenPoints3D(x, y, z, x2, y2, z2)
			if(distanceBetweenPoints < distance) then
				dxDrawText(text, sx+2, sy+2, sx, sy, tocolor(R or 255, G or 255, B or 255, alpha or 255), (size or 1)-(distanceBetweenPoints / distance), font or "arial", "center", "center")
			end
		end
	end
end

--Warehouse Zones
createBlip(2577, 2822, 11, 22)
WarehouseCol1 = createColRectangle( 2535, 2796, 80, 50 ) 
WarehouseArea1 = createRadarArea( 2535, 2796, 80, 50, 0, 0, 255, 90, root ) 
setElementData(WarehouseCol1, "warehoue", true)
setElementData(WarehouseArea1, "warehoue", true)

--Leaving the warehouse
function warehouseLeave()
if (getElementType(source) == "ped") or (getElementType(source) == "marker") then return end --thought maybe this would work
		if isElementWithinColShape(localPlayer, WarehouseCol1) == true then
			timertxt = getElementData(localPlayer, "timer")
			Wtimer = dxDrawTextOnElement(localPlayer, "Defend Warehouse: "..timertxt, 1, 20, 255, 0, 255, 255, 5, "arial")
		elseif Wtimer == nil then return
		else
			destroyElement(Wtimer)
	end
end
addEventHandler("onClientRender", getRootElement(), warehouseLeave)
addEventHandler("onClientElementColShapeLeave", localPlayer, warehouseLeave)

--warehouse timer
function warehoueTimer()
if (getElementType(source) == "ped") or (getElementType(source) == "marker") then return end --thought maybe this would work
timerW = getElementData(localPlayer, "timer")
    if isElementWithinColShape(localPlayer, WarehouseCol1) == true and getElementData(localPlayer, "timer") >= 1 then
		setElementData(localPlayer, "timer", timerW-1)
	elseif isElementWithinColShape(localPlayer, WarehouseCol1) == true and getElementData(localPlayer, "timer") == 0 then
		triggerServerEvent("doSupplyTruck", localPlayer)
	end
end

--Entering warehouse
function warehoueEnter()
if (getElementType(source) == "ped") or (getElementType(source) == "marker") then return end --thought maybe this would work
	if isElementWithinColShape(localPlayer, WarehouseCol1) == true then
			setElementData(localPlayer, "timer", 60)
			:O = setTimer(warehoueTimer, 1000, 61)
		else
		killTimer(:O)
	end
end
addEventHandler("onClientElementColShapeLeave", localPlayer, warehoueEnter)
addEventHandler("onClientElementColShapeHit", localPlayer, warehoueEnter)
 --switch from destroyed element source to player source
function switchh()
triggerServerEvent("switch2", localPlayer)
end
addEvent( "switch", true )
addEventHandler( "switch", localPlayer, switchh )

this is what im working with rn. bout to lay down possibly goto sleep.

Link to comment
5 hours ago, kewizzle said:

well i been messing with it allllll day and i wrote this entirely myself last night and i just cant figure out this tho i just learned more than i wanted to from the wiki than i was trying too atm lmao but if anyone especially @The_GTA can show me how to return the end of each function if the colshape is not WarehouseCol1 much appreciated.

Which functions do you mean in particular? I don't understand.

  • Thanks 1
Link to comment

Well @The_GTAEverytime I hit a marker it resets the timer and it also doubles the speed I'm pretty sure it is running the setTimer timer Everytime I hit a marker I just need each function to be cancelled if I hit a marker while Inside WarehouseCol1. Idk if I'm correct but maybe it's becaus markers have colshapes? 

Link to comment
35 minutes ago, kewizzle said:

Well @The_GTAEverytime I hit a marker it resets the timer and it also doubles the speed I'm pretty sure it is running the setTimer timer Everytime I hit a marker I just need each function to be cancelled if I hit a marker while Inside WarehouseCol1. Idk if I'm correct but maybe it's becaus markers have colshapes? 

You're not even giving a full description what your script is supposed to do! Besides that, your script has flaws. But the flaws of your kind of scripts do not allow general support. Instead of doing too much, I want to give you hints:

function warehoueEnter()
if (getElementType(source) == "ped") or (getElementType(source) == "marker") then return end --thought maybe this would work
	if isElementWithinColShape(localPlayer, WarehouseCol1) == true then
			setElementData(localPlayer, "timer", 60)
			:O = setTimer(warehoueTimer, 1000, 61)
		else
		killTimer(:O)
	end
end
addEventHandler("onClientElementColShapeLeave", localPlayer, warehoueEnter)
addEventHandler("onClientElementColShapeHit", localPlayer, warehoueEnter)
  • you fire this event for all colshapes; is this really what you want to do? for what colshapes do you want warehoueEnter to really trigger? if you asked this question in a straightforward way, maybe people could help you much easier. If you want to limit triggering events to certain elements such as WarehouseCol1, use the addEventHandler function with propagate set to false and comparing the first argument of the event handler callback to WarehouseCol1. Look at the wiki page of onClientElementColShapeHit for an example!
  • you triggering this event handler for both leaving and entering the col shapes makes no sense. could you please decide on what is important here: entering the warehoue if you enter the col shape (onClientElementColShapeHit) or when you leave it (onClientElementColShapeLeave)?

There seldom exist MTA scripters that seek support on our forums and I like to see you here. If you want to listen to my advice, then please learn from the code structures and examples from the wiki. Format your code exactly like on the wiki pages. Get used to best-practice coding rules.

  • Thanks 1
Link to comment
14 minutes ago, kewizzle said:

Okay I'ma rewrite the script from start to finish. Can you give me an example on how to use an element from one function to another? Or how would I do that? Say I created the setTimer in warehouseEnter and want to kill it in warehouseLeave.

Sure. Here is my example.

-- We assume that there is only one warehouse on the map/server.
-- We assume that being inside the warehouse means being inside the colshape.
local warehouse_timer = false;
local warehouse_col = false;    -- TODO.

local function warehouseEnter(shape, matching_dimm)
    if (shape == warehouse_col) and (matching_dimm) then
        -- If we previously had a warehouse_timer, then we should clean it up here regardless.
        if (warehouse_timer) then
            killTimer(warehouse_timer);
            warehouse_timer = false;
        end
    
        warehouse_timer = setTimer(
            function()
                -- TODO
                
                -- If the timer has finished, then we should clean it up.
                warehouse_timer = false;
            end, 1000, 1    -- TODO
        );
    end
end
addEventHandler("onClientElementColShapeHit", root, warehouseEnter);

local function warehouseLeave(shape, matching_dimm)
    if (shape == warehouse_col) and (matching_dimm) then
        -- If we have previously entered the warehouse clientside, then we should
        -- have the warehouse_timer variable set to not false. We assume that
        -- the warehouseEnter function has been properly implemented.
        if (warehouse_timer) then
            killTimer(warehouse_timer);
            warehouse_timer = false;
        end
    end
end
addEventHandler("onClientElementColShapeLeave", root, warehouseLeave);

Good luck with your project. I like that you phrased your idea in a serious way. ?

Edited by The_GTA
  • Thanks 1
Link to comment
18 minutes ago, kewizzle said:

Thanks for all your help I'd like you to win the day again so I went ahead and gave you a good boost

Thank you very much. I am trying my hardest to help you and everyone else who is genuinely in the need of it. You're welcome!

  • Like 1
Link to comment
14 hours ago, The_GTA said:

Thank you very much. I am trying my hardest to help you and everyone else who is genuinely in the need of it. You're welcome!

guess what buddy i was able to use the old script and i fixed it completely. using what you taught me. i found this little piece of code useful

(shape == warehouse_col)

and my finished script here. 

function dxDrawTextOnElement(TheElement,text,height,distance,R,G,B,alpha,size,font,...)
	local x, y, z = getElementPosition(TheElement)
	local x2, y2, z2 = getCameraMatrix()
	local distance = distance or 20
	local height = height or 1

	if (isLineOfSightClear(x, y, z+2, x2, y2, z2, ...)) then
		local sx, sy = getScreenFromWorldPosition(x, y, z+height)
		if(sx) and (sy) then
			local distanceBetweenPoints = getDistanceBetweenPoints3D(x, y, z, x2, y2, z2)
			if(distanceBetweenPoints < distance) then
				dxDrawText(text, sx+2, sy+2, sx, sy, tocolor(R or 255, G or 255, B or 255, alpha or 255), (size or 1)-(distanceBetweenPoints / distance), font or "arial", "center", "center")
			end
		end
	end
end

--Warehouse Zones
createBlip(2577, 2822, 11, 22)
WarehouseCol1 = createColRectangle( 2535, 2796, 80, 50 ) 
WarehouseArea1 = createRadarArea( 2535, 2796, 80, 50, 0, 0, 255, 90, root ) 
setElementData(WarehouseCol1, "warehoue", true)
setElementData(WarehouseArea1, "warehoue", true)

--Leaving the warehouse
function warehouseLeave()
if (getElementType(source) == "ped") or (getElementType(source) == "marker") then return end --thought maybe this would work
		if isElementWithinColShape(localPlayer, WarehouseCol1) == true then
			timertxt = getElementData(localPlayer, "timer")
			Wtimer = dxDrawTextOnElement(localPlayer, "Defend Warehouse: "..timertxt, 1, 20, 255, 0, 255, 255, 5, "arial")
		elseif Wtimer == nil then return
		else
			destroyElement(Wtimer)
	end
end
addEventHandler("onClientRender", getRootElement(), warehouseLeave)
addEventHandler("onClientElementColShapeLeave", localPlayer, warehouseLeave)

--warehouse timer
function warehoueTimer()
if (getElementType(localPlayer) == "ped") or (getElementType(localPlayer) == "marker") then return end --thought maybe this would work
timerW = getElementData(localPlayer, "timer")
    if isElementWithinColShape(localPlayer, WarehouseCol1) == true and getElementData(localPlayer, "timer") >= 1 then
		setElementData(localPlayer, "timer", timerW-1)
	elseif isElementWithinColShape(localPlayer, WarehouseCol1) == true and getElementData(localPlayer, "timer") == 0 then
		triggerServerEvent("doSupplyTruck", localPlayer)
	end
end

--Entering warehouse
function warehoueEnter(shape)
if (getElementType(source) == "ped") or (getElementType(source) == "marker") or (shape ~= WarehouseCol1) then return end --thought maybe this would work
	if isElementWithinColShape(localPlayer, WarehouseCol1) == true and (shape == WarehouseCol1) then
			setElementData(localPlayer, "timer", 60)
			:O = setTimer(warehoueTimer, 1000, 61)
		else
		killTimer(:O)
	end
end
addEventHandler("onClientElementColShapeLeave", localPlayer, warehoueEnter)
addEventHandler("onClientElementColShapeHit", localPlayer, warehoueEnter)
 --switch from destroyed element source to player source
function switchh()
triggerServerEvent("switch2", localPlayer)
end
addEventHandler( "switch", localPlayer, switchh )
addEvent( "switch", true )

this is my largest script ive ever written other than guis i think i did pretty good it works flawless.

Link to comment
4 hours ago, kewizzle said:

yknow what buddy ima remake this buut completely server side

Parts of it, like drawing text on elements, have to be done clientside. You might have to tell clients the text string using an event and when it should stop displaying (I recommend a timer).

Link to comment
19 hours ago, The_GTA said:

Parts of it, like drawing text on elements, have to be done clientside. You might have to tell clients the text string using an event and when it should stop displaying (I recommend a timer).

i redid it works well i just used my display and text item

 

ima post a video lmk what you think bro

Edited by kewizzle
Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...