Cael Posted July 3, 2021 Posted July 3, 2021 I'm probably missing something obvious, but I've been trying to script a lua predicate that checks for when a cargo object that's created in script is inside a trigger zone, on the ground, and not dead. I wrote the predicate but when I run it the game crashes. I'm not getting a popup message with an error, and I didn't see anything in the logs. Could anyone tell me what I'm doing wrong? Thanks in advance local zone = trigger.misc.getZone("CargoDelivery") local cargo = StaticObject.getByName("AmmoPallet") local cargoPos = cargo:getPoint() local xCargo = cargoPos.x local yCargo = cargoPos.y local xZone = zone.point.x local yZone = zone.point.y local xDiff = xCargo - xZone local yDiff = yCargo - yZone local dist = math.sqrt(xDiff * xDiff + yDiff * yDiff) local radius = zone.radius if StaticObject.getLife(cargo) < 1 and cargo:inAir() == false and dist <= radius then return true end
Grimes Posted July 4, 2021 Posted July 4, 2021 Not sure why it would be crashing, but there are some errors in your math. Namely getPoint() and zone.point are vec3 values not vec2. Gotta use z instead of y. Just to ensure the its doing what you want it to do, adding parenthesis for math like that is also recommended. math.sqrt((xDiff * xDiff) + (yDiff * yDiff)) Could put it in a do script rather than a predicate to see if it crashes. 1 The right man in the wrong place makes all the difference in the world. Current Projects: Grayflag Server, Scripting Wiki Useful Links: Mission Scripting Tools MIST-(GitHub) MIST-(Thread) SLMOD, Wiki wishlist, Mission Editing Wiki!, Mission Building Forum
Cael Posted July 4, 2021 Author Posted July 4, 2021 (edited) Thanks for your help! I ended up ripping all the custom script out, which fixed the crashes, then I added it back in piece by piece. Eventually I ended up exactly where I started but the crashes stopped. Head scratcher, but glad it's working. Some more iteration and this is what I ended up with for my two trigger predicates, for anyone in the future who comes across this thread in a similar boat trying to deal with script-spawned cargo objects: -- This check looks to see whether AmmoPallet is delivered to CargoDelivery if StaticObject.getByName("AmmoPallet") == nil then return else local zone = trigger.misc.getZone("CargoDelivery") local cargo = StaticObject.getByName("AmmoPallet") local cargoPos = cargo:getPoint() local xCargo = cargoPos.x local zCargo = cargoPos.z local xZone = zone.point.x local zZone = zone.point.z local xDiff = xCargo - xZone local zDiff = zCargo - zZone local dist = math.sqrt((xDiff * xDiff) + (zDiff * zDiff)) local radius = zone.radius if StaticObject.getLife(cargo) > 1 and cargo:inAir() == false and dist <= radius then return true end end Another trigger looking to see if the cargo was destroyed: -- This check looks to see whether AmmoPallet is dead if StaticObject.getByName("AmmoPallet") ~= nil then local cargo = StaticObject.getByName("AmmoPallet") if StaticObject.getLife(cargo) < 1 then return true end else return end It looks like the inAir check isn't working (it's returning true while the cargo is still swinging from the helicopter), but that's a problem for another day Edited July 4, 2021 by Cael forgot code blocks
toutenglisse Posted July 4, 2021 Posted July 4, 2021 5 hours ago, Cael said: ... It looks like the inAir check isn't working (it's returning true while the cargo is still swinging from the helicopter), but that's a problem for another day You can compare distance between cargo position ( local cargoPos = cargo:getPoint() ) and projected point on ground ( local projPos = {x = cargoPos.x, y = land.getHeight({x = cargoPos.x, y = cargoPos.z}), z= cargoPos.z} ). If distance == 0 it is on land. 1
cfrag Posted July 5, 2021 Posted July 5, 2021 A slight improvement to toutenglisse's code: do not compare to zero. Look at the object's dimensions, and use the largest one, divide it by two, and add 0.5 and compare to that size. If you have a cube of 1x2x3 meters, check if the distance is smaller than 3/2 + 0.5 to be reasonably sure that the object is on the ground. The reason for this somewhat roundabout method is that the object's location is usually placed in it's center, and the collider around it will prevent it to ever get close enough to the ground for the distance to become zero.
toutenglisse Posted July 5, 2021 Posted July 5, 2021 1 hour ago, cfrag said: ... do not compare to zero... The only case where this operation doesn't return zero when pallet is on the ground seems to be when it sits on the top of a scenery object.
cfrag Posted July 5, 2021 Posted July 5, 2021 That's good to know, thanks, @toutenglisse! I could have sworn I ran into an issue with this some time ago - so my code never compares to zero. But it may have been something different, maybe idiotic me not taking the terrain's altitude into account. It's just that since distance can't ever go below zero, I'd rather allow for a small error than straight comparing to being equal to zero (simply feels wrong - my code head talking here ) As long as it works, use whatever is more comfortable to you 1
Cael Posted July 8, 2021 Author Posted July 8, 2021 I was playing around with delivering cargo to a ship, so I was thinking it might be better to look at velocity than elevation (assuming if it's stationary and within the radius, we can call it delivered). With the example block below (looking just at x, I tried all 3 axes), I was getting a reported velocity of zero, even while moving. Does sling loaded cargo not have its own velocity? local cargoVel = cargo:getVelocity() local cargoX = cargoVel.x trigger.action.outText('Vel X: ' .. cargoX, 20)
Recommended Posts