local U = require "scriptbank\\utillib" local Q = require "scriptbank\\quatlib" local lights = {} attachLightToMe = attachLightToMe or {} local rad = math.rad function light_npc_init( e ) Include( "utillib.lua" ) Include( "quatlib.lua" ) lights[ e ] = { lightNum = GetEntityLightNumber( e ), attachTo = nil } end local function sqrd( x1, z1, x2, z2 ) return ( x1 - x2 )^2 + ( z1 - z2 )^2 end local function getOffset( p1, q1, p2, q2 ) local cq = Q.Conjugate( q1 ) local xa, ya, za = Q.ToEuler( cq ) local xo, yo, zo = U.Rotate3D( p2.x - p1.x, p2.y - p1.y, p2.z - p1.z, xa, ya, za ) return { xo = xo, yo = yo, zo = zo}, Q.Mul( cq, q2 ) end function light_npc_main( e ) local light = lights[ e ] if light == nil then return end if light.attachTo == nil then local x1, y1, z1 = GetLightPosition( light.lightNum ) local dist1 = math.huge local closest = nil for _, v in pairs( attachLightToMe ) do if v ~= nil then local x2, y2, z2 = GetEntityPosAng( v ) local dist2 = sqrd( x1, z1, x2, z2 ) if dist2 < dist1 then closest = v dist1 = dist2 end end end if closest == nil then light.attachTo = -1 return end attachLightToMe[ closest ] = nil light.attachTo = closest --get the entity pos & angles values we are attaching too local ex, ey, ez, eax, eay, eaz = GetEntityPosAng( closest ) --get our own (light) values local lx, ly, lz, lax, lay, laz = GetEntityPosAng( e ) -- convert euler angles to quats local eq, lq = Q.FromEuler( rad( eax ), rad( eay ), rad( eaz ) ), Q.FromEuler( rad( lax ), rad( lay ), rad( laz ) ) light.posOffs, light.angOff = getOffset( { x = eax, y = eay, z = eaz }, eq, { x = lax, y = lay, z = laz }, lq ) elseif light.attachTo ~= -1 then --this part is run during the update --get the new values for our attached entity local x, y, z, Ax, Ay, Az = GetEntityPosAng( light.attachTo ) Ax, Ay, Az = rad( Ax ), rad( Ay ), rad( Az ) local quat = Q.FromEuler( Ax, Ay, Az ) --place the light based on the new position + our offset local xo, yo, zo = U.Rotate3D( light.posOffs.xo, light.posOffs.yo, light.posOffs.zo, Ax, Ay, Az ) SetLightPosition ( light.lightNum, x + xo, y + yo, z + zo ) --work out the light angle quat = Q.Mul( quat, light.angOff ) -- !! Do any rotation here !! Ax, Ay, Az = Q.ToEuler( quat ) local xv, yv, zv = U.Rotate3D( 0, 0, 1, Ax, Ay, Az ) SetLightAngle( light.lightNum, xv, yv, zv ) end end