Kayl Posted May 10, 2010 Share Posted May 10, 2010 (edited) Hey there, I'm fighting with ped lighting. After doing some tests, it seems that peds are created with no light-set. If you warp them to a vehicle or freeze them, they will stay black. They seem to only gain normal colors when having physically touched the ground at least once. Test code: local g_Peds = nil function pedTest() if g_Peds then for ped,pedData in pairs(g_Peds) do destroyElement(ped) destroyElement(pedData.marker) end removeEventHandler("onClientPreRender", g_Root, onPedTestPreRender) g_Peds = nil else g_Peds = {} setTime(12, 0) setWeather(0) local x, y, z = -1287.0609130859, -84.415733337402 local tHeight = {14.14, 17} local tFreeze = {"none", "mta", "manual"} for _,freeze in ipairs(tFreeze) do for _,height in ipairs(tHeight) do local pedData = {} pedData.x = x pedData.y = y pedData.z = height pedData.freeze = freeze local r, g, b = 0, 0, 0 if freeze == "none" then r, g, b = 255, 0, 0 elseif freeze == "mta" then r, g, b = 0, 255, 0 elseif freeze == "manual" then r, g, b = 0, 0, 255 end pedData.marker = createMarker(x, y, height+2, "arrow", 1, r, g, b, 255) local ped = createPed(70, x, y, height) if pedData.freeze == "mta" then setPedFrozen(ped, true) end g_Peds[ped] = pedData y = y + 2 end end addEventHandler("onClientPreRender", g_Root, onPedTestPreRender) end end addCommandHandler("pedtest", pedTest) function onPedTestPreRender() setTime(12, 0) setWeather(0) for ped, pedData in pairs(g_Peds) do if pedData.freeze == "manual" then setElementPosition(ped, pedData.x, pedData.y, pedData.z) end end end Screenshots: Colors: blue = manually frozen (onClientPreRender), green = setPedFrozen, red = not frozen at all Starting conditions: all peds created at ground level are lit correctly, others aren't. The second ped from the right finally touched the ground and is now correctly lit The setPedFrozen isn't perfect and the green dude shakes like hell (not seen on still image) and slowly but utterly approaches the ground The shaking dude, in his shaking nightmare, has touched the ground a tiny bit and therefore gained a tiny bit of correct light So, is there a way to fix that and make all the peds have correct lighting? Edited May 11, 2010 by Guest Link to comment
50p Posted May 11, 2010 Share Posted May 11, 2010 No, this is a bug. Not 100% sure if GTA's bug though. It also happens when player walks on custom models (can't remember if it's due to wrong collision data or vertex colour). All you can do is spawn the ped on the ground and move him where you want him to be. As you mentioned, it makes ped lit properly since he/she first touches the ground. Link to comment
Xierra Posted May 11, 2010 Share Posted May 11, 2010 I'm not really sure that's a GTA bug, as I always see no shakes to some things like GTA SA's interior markers. Maybe it can be a bug only if you put the marker on something which is above the ground and before falling onto the ground. I also agree to some of 50p's point though. Best way is to put the marker after the ped is on the ground instead. PS: hmm, you must be kayl, the great scripter of the DKR Clan? Wow! I also really liked the server! Damn awesome scripts! Link to comment
Kayl Posted May 11, 2010 Author Share Posted May 11, 2010 @xxx3 Sorry I don't really understand your answer. The markers here are just to highlight where each ped was original created and what freeze method is used for each. The shaking mentioned is affecting the "ped under the green marker" only because of its freeze method. Thank you for your comment on DKR Clan's scripts. @50p I feared you might answer that. It makes the ped creation "asynchronous" but I guess it's the price you have to pay to get this ped lighting working. I have modified the previous code in order to create the pink peds at ground level and then after 1sec only freeze them where expected: local g_Peds = nil function pedTest() if g_Peds then for ped,pedData in pairs(g_Peds) do destroyElement(ped) destroyElement(pedData.marker) end removeEventHandler("onClientPreRender", g_Root, onPedTestPreRender) g_Peds = nil else g_Peds = {} setTime(12, 0) setWeather(0) local x, y, z = -1287.0609130859, -84.415733337402 local tHeight = {14.14, 17} local tFreeze = {"none", "mta", "manual", "ground_created"} for _,freeze in ipairs(tFreeze) do for _,height in ipairs(tHeight) do local pedData = {} pedData.x = x pedData.y = y pedData.z = height pedData.freeze = freeze local r, g, b = 0, 0, 0 if freeze == "none" then r, g, b = 255, 0, 0 elseif freeze == "mta" then r, g, b = 0, 255, 0 elseif freeze == "manual" then r, g, b = 0, 0, 255 elseif freeze == "ground_created" then r, g, b = 255, 0, 255 pedData.realZ = pedData.z pedData.z = 14.14 end pedData.marker = createMarker(x, y, height+2, "arrow", 1, r, g, b, 255) local ped = createPed(70, pedData.x, pedData.y, pedData.z) if pedData.freeze == "mta" then setPedFrozen(ped, true) elseif pedData.freeze == "ground_created" then setElementPosition(ped, pedData.x, pedData.y, pedData.z) setPedFrozen(ped, true) pedData.ticks = getTickCount() end g_Peds[ped] = pedData y = y + 2 end end addEventHandler("onClientPreRender", g_Root, onPedTestPreRender) end end addCommandHandler("pedtest", pedTest) function onPedTestPreRender() setTime(12, 0) setWeather(0) local now = getTickCount() for ped, pedData in pairs(g_Peds) do if pedData.freeze == "manual" then setElementPosition(ped, pedData.x, pedData.y, pedData.z) elseif pedData.freeze == "ground_created" then if (now - pedData.ticks) > 1000 then pedData.z = pedData.realZ pedData.freeze = "manual" setElementPosition(ped, pedData.x, pedData.y, pedData.z) end end end end And indeed it works: I then modified the code again to be able to create those peds in front of the camera instead of in predefined positions. The temporary position of the ped is the ground position found under the camera. This works when the ground is near: But when the camera is up in the sky it doesn't: It might be because no ground data is actually found or the ped put temporarily at ground level is not even streamed-in so the trick doesn't work: I guess I will therefore try the following to have something that works all the time: - fade camera to black - put it at a predefined position looking at the ground - wait for collision data to be loaded (watching processLineOfSight on the known expected ground position) - create the ped - wait 1 sec - move the camera & ped where they ought to be placed in the first place - unfade the camera This is not a solution that would work for everyone but for what I want to do I can tolerate a "loading" time. I'll edit my post or post a new one to comment on the success/failure of the aforementioned procedure. Edit Ok since there was no reply I can edit my post to avoid double post. I have implemented the procedure I mentioned and this allows the creation of a correctly lit ped very high up in the sky. I have also added a ped next to it, created there to show that this one remains, as expected, black. local g_PedTest = nil function pedTest3() if g_PedTest then if g_PedTest.ped then destroyElement(g_PedTest.ped) end if g_PedTest.ped2 then destroyElement(g_PedTest.ped2) end if g_PedTest.cameraTarget then setCameraTarget(g_PedTest.cameraTarget) elseif g_PedTest.initialcameraMatrix then setCameraMatrix(unpack(g_PedTest.initialcameraMatrix)) end if g_PedTest.cameraFaded then fadeCamera(true) end removeEventHandler("onClientPreRender", g_Root, onRealPedTestPreRender) g_PedTest = nil else g_PedTest = {} setTime(12, 0) setWeather(0) g_PedTest.cameraTarget = getCameraTarget() if not g_PedTest.cameraTarget then g_PedTest.initialcameraMatrix = {getCameraMatrix()} end fadeCamera(false, 0) g_PedTest.cameraFaded = true g_PedTest.cameraMatrix = {4, 4, 4, 0, 0, 2, 0, 70} setCameraMatrix(unpack(g_PedTest.cameraMatrix)) g_PedTest.state = "waiting_ground" g_PedTest.ped2Data = {1002, -45, 2000} g_PedTest.ped2 = createPed(70, unpack(g_PedTest.ped2Data)) addEventHandler("onClientPreRender", g_Root, onRealPedTestPreRender) end end addCommandHandler("pedtest3", pedTest3) function onRealPedTestPreRender() setTime(12, 0) setWeather(0) setCameraMatrix(unpack(g_PedTest.cameraMatrix)) if g_PedTest.state and g_PedTest.state == "waiting_ground" then local hit, hitx, hity, hitz = processLineOfSight(0, 0, 10, 0, 0, -10, true, false, false, false) if hit then g_PedTest.ped = createPed(70, 0, 0, 3.11) setPedFrozen(g_PedTest.ped, true) g_PedTest.state = "waiting_ped" g_PedTest.ticks = getTickCount() end elseif g_PedTest.state == "waiting_ped" then local now = getTickCount() if (now - g_PedTest.ticks) > 1000 then g_PedTest.pedData = {1000, -45, 2000} g_PedTest.cameraMatrix = {1000, -40, 2002, 1000, -45, 2000, 0, 70} setCameraMatrix(unpack(g_PedTest.cameraMatrix)) setElementPosition(g_PedTest.ped, unpack(g_PedTest.pedData)) if g_PedTest.cameraFaded then fadeCamera(true, 1.0) g_PedTest.cameraFaded = false end end else setElementPosition(g_PedTest.ped, unpack(g_PedTest.pedData)) end setElementPosition(g_PedTest.ped2, unpack(g_PedTest.ped2Data)) end The whole process only takes 1 second (safety time for the ped to light up correctly) and it's suitable for my needs. So thanks for the input, I consider my problem solved. Edit2: Tips for someone willing to reproduce the above code, it's important for the local player to also be placed in interior 0 or else the collision data won't be streamed-in and the processLineOfSight will always fail (at least in 1.0.3) Link to comment
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now