Dzsozi (h03)

Only one wheel is returned with getVehicleComponents

Recommended Posts

Hello!

I would like to do a simple function which allows me to create GTA SA effects at the position of the vehicle's wheels.

For some reason the effect is being created only at one wheel, which is the right front wheel in case of cars, and the front wheel in case of bikes. I don't know what am I doing wrong, I would be grateful if someone could help me solve the problem, here's my script:

Client Side:

local effectAtWheels = {}

function createEffectAtWheels(vehicle, effect)
	if not tostring(effect) then return false end
	if vehicle and isElement(vehicle) and getElementType(vehicle) == "vehicle" then
		local vehicleType = getVehicleType(vehicle)
		if vehiclesWithWheels[vehicleType] then
			local vehicleX, vehicleY, vehicleZ = getElementPosition(vehicle)
			local _, _, vehicleRotation = getElementRotation(vehicle)
			
			for component in pairs(getVehicleComponents(vehicle)) do
				if wheelComponents[component] then
					for i=1, #component do
						local wheelX, wheelY, wheelZ = getVehicleComponentPosition(vehicle, component, "world")
						local groundZ = getGroundPosition(wheelX, wheelY, wheelZ)
						
						if wheelZ <= groundZ+0.5 then -- if the wheel is on the ground
							effectAtWheels[component] = createEffect(effect, wheelX, wheelY, wheelZ-0.225, 0, 0, vehicleRotation, 150, false)
						end
						
						if effectAtWheels[component] and isElement(effectAtWheels[component]) then
							return effectAtWheels[component]
						end
					end
				end
			end
		end
	end
end

Global/Shared script:

wheelComponents = {
	["wheel_lf_dummy"] = true,
	["wheel_lb_dummy"] = true,
	["wheel_rf_dummy"] = true,
	["wheel_rb_dummy"] = true,
	["wheel_front"] = true,
	["wheel_rear"] = true,
}

vehiclesWithWheels = {
	["Automobile"] = true,
	["Bike"] = true,
	["Trailer"] = true,
	["BMX"] = true,
	["Monster Truck"] = true,
	["Quad"] = true,
}

What could be the problem? I don't understand why is it happening, there is nothing seems to be wrong for me, also, debugscript doesn't output any errors.

Thank you for your reply in advance!

Edited by Dzsozi (h03)

Share this post


Link to post

Okay, so I realised that this only happens when I use the createEffect function, but I tried it with fxAddFootSplash and it was working. My question is why it doesn't work with the createEffect function and how can I make it work with that function?

Share this post


Link to post

You use the same key word for all the components as for only one component, and you do not index the components table.

Share this post


Link to post

You can't figure out why you used the same variable name? You got to be kidding me.

Just remove the second loop and debug your code.

Share this post


Link to post

I already did that before posting, I added it later while trying to fix the problem. Here's my current code:

function createEffectAtWheels(vehicle, effect, duration)
	if not tostring(effect) then return false end
	if vehicle and isElement(vehicle) and getElementType(vehicle) == "vehicle" then
		local vehicleType = getVehicleType(vehicle)
		if vehiclesWithWheels[vehicleType] then
			local vehicleX, vehicleY, vehicleZ = getElementPosition(vehicle)
			local _, _, vehicleRotation = getElementRotation(vehicle)
			
			local effectAtWheels = {}
			local effectDestroyTimer
			
			if isTimer(effectDestroyTimer) then
				killTimer(effectDestroyTimer)
				effectDestroyTimer = nil
			end
			
			for component in pairs(getVehicleComponents(vehicle)) do
				if wheelComponents[component] then
					local wheelX, wheelY, wheelZ = getVehicleComponentPosition(vehicle, component, "world")
					local groundZ = getGroundPosition(wheelX, wheelY, wheelZ)
					
					outputChatBox(tostring(component))
					
					if wheelZ <= groundZ+0.5 then
						effectAtWheels[component] = createEffect(effect, wheelX, wheelY, wheelZ-0.275, 0, 0, vehicleRotation, 150, false)
					end
					
					effectDestroyTimer = setTimer(function()
						if effectAtWheels[component] and isElement(effectAtWheels[component]) then
							destroyElement(effectAtWheels[component])
							effectAtWheels[component] = nil
						end
					end, duration, 1)
					
					if effectAtWheels[component] and isElement(effectAtWheels[component]) then
						return effectAtWheels[component]
					end
				end
			end
		end
	end
end
wheelComponents = {
	["wheel_lf_dummy"] = true,
	["wheel_lb_dummy"] = true,
	["wheel_rf_dummy"] = true,
	["wheel_rb_dummy"] = true,
	["wheel_front"] = true,
	["wheel_rear"] = true,
}

And the problem is the same, the effect is being created only at the right front wheel, and it changes to another wheel if the right front wheel doesn't touch the ground, but as soon as it touches the ground the effect is being created only at that wheel again.

Share this post


Link to post

the

effectDestroyTimer

Is global. (not sure if that is the problem, but will have influence.)

 

 

How does the script know that it has to create the effect? Because that sounds more like your problem. (the trigger itself)

Share this post


Link to post
15 minutes ago, IIYAMA said:

the


effectDestroyTimer

Is global. (not sure if that is the problem, but will have influence.)

 

 

How does the script know that it has to create the effect? Because that sounds more like your problem. (the trigger itself)

Yes, I also noticed that the effectDestroyTimer was global, I already fixed it, this doesn't seem to be the problem.

Here's how I call the function:

local waterSplash = {}
function waterSplashEffect()
	for k, vehicle in pairs(getElementsByType("vehicle")) do
		if isElementStreamedIn(vehicle) then
			if not isVehicleBlown(vehicle) then
				if isVehicleOnGround(vehicle) and not isVehicleOnRoof(vehicle) then
					if getVehicleSpeed(vehicle) >= 10 then
						waterSplash[vehicle] = createEffectAtWheels(vehicle, "water_splash", 1000)
					end
				end
			end
		end
	end
end

addEventHandler("onClientResourceStart", getResourceRootElement(getThisResource()), 
	function()
		setTimer(function()
			waterSplashEffect()
		end, 50, 0)
	end
)

 

Share this post


Link to post

Lines 21-23 in the code in the OP:

						if effectAtWheels[component] and isElement(effectAtWheels[component]) then
							return effectAtWheels[component]
						end

this condition will always be met, therefor the function will be terminated in the first iteration of the for loop...

What it the use of the 'waterSplash' table? If you don't use it anywhere else in the code, simply remove the 21-23 lines, if you need that table then I would suggest skipping the condition and returning the whole 'effectAtWheels' table outside the for loop.

Share this post


Link to post
7 hours ago, Wojak said:

Lines 21-23 in the code in the OP:


						if effectAtWheels[component] and isElement(effectAtWheels[component]) then
							return effectAtWheels[component]
						end

this condition will always be met, therefor the function will be terminated in the first iteration of the for loop...

What it the use of the 'waterSplash' table? If you don't use it anywhere else in the code, simply remove the 21-23 lines, if you need that table then I would suggest skipping the condition and returning the whole 'effectAtWheels' table outside the for loop.

Thank you, I fixed everything you mentioned, works perfectly now. Thank you again!

Share this post


Link to post

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.