you can look for a crater.
I believe it's
nearestobject [player, "Crater"]
There are limitations:
A) Craters are only created if the player or viewpoint is near them.
B) nearestobject only works within 50m
C) if there's a crater nearer, it will be detected.
D) this doesn't tell you when the crater was created.
You can fix a few of these by getting excessively fancy. for example, you can delete every crater detected and camcreate a custom subclass (like my_crater) on the spot, hopefully without the wisp of smoke. That way NO will only pick up undetected craters. You can filter out craters that have been around a while by deleting and replacing craters beyond say 20m distance without triggering them (so if the dude walks into a field of craters).
the end result will probably not be ideal though.
If you have control over the munitions themselves, a trick I'm working with now is a smokeless smokeshell. Make a subclass of the smokeshell with the smoke settings set to be invisible, and a model that's invisible, with the same properties as the shell you're tracking. When the round is fired,track it at say .5 second intervals, recording direction, velocity and position. When the position goes to 0,0,0, taket he last reading, camcreate the smokeless smokeshell there, setdir and kick it int he velocity vector. It should land in approximately the same place (unfortunately, AoA has an effect on shell ballistics, so it won't be precise. But with the proper polling interval, it otta work).,