"explosionEvent" handler returning an explosion's position offset relative to a vehicle's position if caused on a vehicle

I could’ve probably phrased the title better, but here we go:

My explosion log script, which looks like this:

local webhookId = Config.Webhooks.ExplosionLogger
local square = math.sqrt;

local getDistance = function(a, b, noZ)
	local x, y, z = a.x-b.x, a.y-b.y, a.z-b.z;
	if noZ then 
		return square(x*x+y*y);
	else
		return square(x*x+y*y+z*z);
	end
end;
AddEventHandler('explosionEvent', function(source, ev)
	types = {'DONTCARE', 'GRENADE', 'GRENADELAUNCHER', 'STICKYBOMB', 'MOLOTOV', 'ROCKET', 'TANKSHELL', 'HI_OCTANE', 'CAR', 'PLANE', 'PETROL_PUMP', 'BIKE', 'DIR_STEAM', 'DIR_FLAME', 'DIR_WATER_HYDRANT', 'DIR_GAS_CANISTER', 'BOAT', 'SHIP_DESTROY', 'TRUCK', 'BULLET', 'SMOKEGRENADELAUNCHER', 'SMOKEGRENADE', 'BZGAS', 'FLARE', 'GAS_CANISTER', 'EXTINGUISHER', 'PROGRAMMABLEAR', 'TRAIN', 'BARREL', 'PROPANE', 'BLIMP', 'DIR_FLAME_EXPLODE', 'TANKER', 'PLANE_ROCKET', 'VEHICLE_BULLET', 'GAS_TANK', 'BIRD_CRAP', 'RAILGUN', 'BLIMP2', 'FIREWORK', 'SNOWBALL', 'PROXMINE', 'VALKYRIE_CANNON', 'AIR_DEFENCE', 'PIPEBOMB', 'VEHICLEMINE', 'EXPLOSIVEAMMO', 'APCSHELL', 'BOMB_CLUSTER', 'BOMB_GAS', 'BOMB_INCENDIARY', 'BOMB_STANDARD', 'TORPEDO', 'TORPEDO_UNDERWATER', 'BOMBUSHKA_CANNON', 'BOMB_CLUSTER_SECONDARY', 'HUNTER_BARRAGE', 'HUNTER_CANNON', 'ROGUE_CANNON', 'MINE_UNDERWATER', 'ORBITAL_CANNON', 'BOMB_STANDARD_WIDE', 'EXPLOSIVEAMMO_SHOTGUN', 'OPPRESSOR2_CANNON', 'MORTAR_KINETIC', 'VEHICLEMINE_KINETIC', 'VEHICLEMINE_EMP', 'VEHICLEMINE_SPIKE', 'VEHICLEMINE_SLICK', 'VEHICLEMINE_TAR', 'SCRIPT_DRONE', 'RAYGUN', 'BURIEDMINE', 'SCRIPT_MISSIL'}
	whitelistedTypes = {["MOLOTOV"]=1,["CAR"]=1,["PLANE"]=1,["BIKE"]=1,["DIR_FLAME"]=1,["BOAT"]=1,["SHIP_DESTROY"]=1,["TRUCK"]=1,["BULLET"]=1,["FLARE"]=1,["TANKER"]=1,["GAS_TANK"]=1,["SNOWBALL"]=1, ['DIR_WATER_HYDRANT']=1}
	if ev.explosionType ~= nil and ev.explosionType < -1 or ev.explosionType > 72 then
		ev.explosionType = "UNKNOWN"
	else
		ev.explosionType = types[ev.explosionType+2]
	end
	local msg
	local username = GetPlayerName(source)
	if  (ev.posX == 0.0 or ev.posY == 0.0 or ev.posZ == -1700.0) then
		--CancelEvent()
		return
	end
	local pPos = math.floor(GetEntityCoords(GetPlayerPed(source)))
	local ePos = math.floor(vector3(ev.posX,ev.posY,ev.posZ))
	local distance = math.floor(getDistance(pPos, ePos))
	local distance2d = math.floor(getDistance(pPos, ePos, true))
	if not whitelistedTypes[ev.explosionType] or ev.damageScale > 1.0 or ev.cameraShake >= 1.0 or not ev.isAudible or ev.isInvisible or distance2d > 70 then
		TriggerClientEvent("ExplosionLogger:clear", -1, ev.posX, ev.posY, ev.posZ, 7.0)
		local reason = not whitelistedTypes[ev.explosionType] and "Blacklisted Explosion Type" or ev.damageScale > 1.0 and "Modder Explosion (DamageScale)" or ev.cameraShake >= 1.0 and "Modder Explosion (CameraShake)" or not ev.isAudible and "Modder Explosion (non-audible explosion)" or ev.isInvisible and "Modder Explosion (Invisible explosion)" or distance2d > 70.0 and "Far away explosion ("..distance2d.." meters away without up-down vector)"
		msg = "**"..username.." caused a "..ev.explosionType.." explosion.\n HIGH PRIORITY EXPLOSION. REASON: ``"..reason.."`` <@&696179187773603912>\n	•DamageScale: ``"..ev.damageScale.."``\n	•isAudible: ``"..tostring(ev.isAudible).."``\n	•isInvisible: ``"..tostring(ev.isInvisible).."``\n	•cameraShake: ``"..ev.cameraShake.."``\n	•Position: ``("..ePos.x..", "..ePos.y..", "..ePos.z..")``\n 	•Player Position: ``("..pPos.x..", "..pPos.y..", "..pPos.z..")``\n	•Distance from explosion: ``"..distance.." meters``**"
		CancelEvent()
	else
		msg = username.." caused a "..ev.explosionType.." explosion at ``("..ePos.x..", "..ePos.y..", "..ePos.z..")``. Player's Position: ``("..pPos.x..", "..pPos.y..", "..pPos.z..")`` Distance from explosion: ``"..distance.." meters``"
	end
	if ev.explosionType == "DIR_WATER_HYDRANT" then return end
	PerformHttpRequest(Config.Webhooks.ExplosionLogger, function(err, text, headers) end, 'POST', json.encode({username = "Explosion Log", content = msg}), { ['Content-Type'] = 'application/json' })
end)

works fine when throwing a molotov, shooting a rocket, or anything else at something that is NOT a vehicle.
However, as soon as you shoot it at a vehicle, it will return the explosion’s offset relative to that vehicle. an example:


In this, the molotov’s explosion will be (2.5, 0, 0). I just can’t figure out how to return the correct position.

EDIT: This actually happens with ANY props, not only vehicles.

Edit 2: After fiddling around with explosion for a few hours, I’ve discovered that it in fact IS possible to get the “real” explosion position.

1 Like

can you share how you got the real position ?

I did some testing on this last night and the below bit of code should return the correct coordinates of an explosion, regardless if it’s from a stickybomb attached to an object or if it’s just an explosion.

AddEventHandler('explosionEvent', function(sender, ev)
    ev.explosionCoords        = GetExplosionCoords(ev)
    print(ev.explosionCoords)
end)

GetExplosionCoords = function(data)
    if data.f210 ~= 0 then 
        return GetEntityCoords(NetworkGetEntityFromNetworkId(data.f210))
    else
        return vector3(data.posX, data.posY, data.posZ)
    end
end
2 Likes

This will only get the car’s position, not the explosion’s position. Here’s my solution:

local ePos = math.floor(vector3(ev.posX,ev.posY,ev.posZ))
	if ev.f210 ~= 0 then -- The vehicle's network ID exists
		local entityId = NetworkGetEntityFromNetworkId(ev.f210)
		if NetworkGetEntityOwner(entityId) ~= NetworkGetNetworkIdFromEntity(GetPlayerPed(src)) then
		end
		local vPos = GetEntityCoords(entityId)
		if ev.f190 then -- Car explosion was caused by a bomb
			ePos = vPos+ePos
		else
			ePos = vPos
		end
	end
5 Likes

can u send me the whole folder? where it works fine?