local U = require "scriptbank\\utillib" local Q = require "scriptbank\\quatlib" local lightNum = {} local attachTo = {} local offx,offy,offz,offax,offay,offaz = {},{},{},{},{},{} attachLightToMe = {} local rad = math.rad local mode = {} local offq = {} --[[ *light modes* use name "spin" for a spinning light effect use name "search" for a searching effect use name "fade" for a fade in / out effect --]] local spin_speed = {} local spin_axis = {} local search_speed = {} local search_axis = {} local search_range = {} local fade_speed = {} local fade_range = {} local start_angle = {} local start_fade = {} local fade_direction = {} local search_direction = {} function light_npc_init_name(e,name) --mode settings info --[[ spin settings; spin_speed[e] = higher = faster, negative = opposite direction spin_axis[e] = "x" / "y" / "z" search settings; search_speed[e] = higher = faster search_axis[e] = "x" / "y" / "z" search_range[e] = the amount the light will rotate before changing direction = 1~359 fade settings; fade_speed[e] = higher = faster flicker fade_range[e] = change in intensity of light = higher = more change --you should set this based on the 'range' value of the light's property panel --]] --change the mode settings here spin_speed[e] = 1 spin_axis[e] = "y" search_speed[e] = 1 search_axis[e] = "y" search_range[e] = 90 fade_speed[e] = 10 fade_range[e] = 2500 --done with mode settings lightNum[e] = GetEntityLightNumber(e)--change 2 to the entity number of the light --change 'nil' to the entity number of the npc --or place the light next to entity for automatic assignment --*make sure entity has 'attachLightToMe[e] = e' in the script* attachTo[e] = nil mode[e] = name if string.find(mode[e],string.lower("spin")) ~= nil then mode[e] = "spin" elseif string.find(mode[e],string.lower("search")) ~= nil then mode[e] = "search" elseif string.find(mode[e],string.lower("fade")) ~= nil then mode[e] = "fade" end if mode[e] == "spin" then if search_axis[e] == "x" then start_angle[e] = GetEntityAngleX(e) elseif search_axis[e] == "z" then start_angle[e] = GetEntityAngleZ(e) else start_angle[e] = GetEntityAngleY(e) end elseif mode[e] == "search" then start_angle[e] = 0 if search_speed[e] > 0 then search_direction[e] = 1 else search_direction[e] = -1 end elseif mode[e] == "fade" then start_fade[e] = GetLightRange(lightNum[e]) if fade_speed[e] > 0 then fade_direction[e] = 1 else fade_direction[e] = -1 end end end function light_npc_main(e) if attachTo[e] == nil then local x1,y1,z1 = GetLightPosition(lightNum[e]) local dist1 = 999999 for a,_ in pairs (attachLightToMe) do local x2,y2,z2 = GetEntityPosAng(a) local dist2 = sqrd(x1,z1,x2,z2) if dist2 < dist1 then attachTo[e] = a dist1 = dist2 end end if attachTo[e] == nil then attachTo[e] = -1 return end --get the entity pos & angles values we are attaching too local x, y, z, Ax, Ay, Az = GetEntityPosAng(attachTo[e]) --get our own (light) values local lx,ly,lz = GetLightPosition(lightNum[e]) local lax,lay,laz = GetEntityAngleX(e),GetEntityAngleY(e),GetEntityAngleZ(e) --work out the offsets (done once at map start) offx[e] = lx-x offy[e] = ly-y offz[e] = lz-z --workout and store the angle offset of the light as vector for later offax[e] = rad(GetEntityAngleX(e)) offay[e] = rad(GetEntityAngleY(e)) offaz[e] = rad(GetEntityAngleZ(e)) else --this part is run during the update if attachTo[e] == -1 then return end --place the light based on the new position + our offset local x, y, z, Ax, Ay, Az = GetEntityPosAng(attachTo[e]) local xA, yA, zA = rad( Ax ), rad( Ay ), rad( Az ) --work out the angle of the entity + our angle offset local xv, yv, zv = U.Rotate3D( 0, 0, 1, xA+offax[e], yA+offay[e], zA+offaz[e]) local xo, yo, zo = U.Rotate3D( offx[e], offy[e], offz[e], xA, yA, zA ) if mode[e] == "fade" then local fade = GetLightRange(lightNum[e]) fade = fade + (fade_speed[e]*fade_direction[e]) if fade < start_fade[e]-fade_range[e] or fade > start_fade[e]+fade_range[e] then fade_direction[e] = fade_direction[e]*-1 end --PromptLocal(e,fade) SetLightRange(lightNum[e],fade) xo, yo, zo = U.Rotate3D( offx[e], offy[e], offz[e], xA, yA, zA ) elseif mode[e] == "spin" then start_angle[e] = start_angle[e] + spin_speed[e] if start_angle[e] > 359 then start_angle[e] = start_angle[e]-360 elseif start_angle[e] < 0 then start_angle[e] = start_angle[e]+360 end --PromptLocal(e,round(start_angle[e],2)) start_angle[e] = rad(start_angle[e]) if spin_axis[e] == "x" then xv, yv, zv = U.Rotate3D( 0, 0, 1, (xA+start_angle[e])+offax[e], yA+offay[e], zA+offaz[e]) xo,yo,zo = U.Rotate3D( offx[e], offy[e], offz[e], xA+start_angle[e], yA, zA ) elseif spin_axis[e] == "z" then xv, yv, zv = U.Rotate3D( 0, 0, 1, xA+offax[e], yA+offay[e], (zA+start_angle[e])+offaz[e]) xo, yo, zo = U.Rotate3D( offx[e], offy[e], offz[e], xA, yA, zA+start_angle[e] ) else xv, yv, zv = U.Rotate3D( 0, 0, 1, xA+offax[e], (yA+start_angle[e])+offay[e], zA+offaz[e]) xo, yo, zo = U.Rotate3D( offx[e], offy[e], offz[e], xA, yA+start_angle[e], zA ) end start_angle[e] = math.deg(start_angle[e]) elseif mode[e] == "search" then start_angle[e] = start_angle[e] + (search_speed[e]*search_direction[e]) if start_angle[e] > search_range[e] or start_angle[e] < search_range[e]*-1 then search_direction[e] = search_direction[e]*-1 end start_angle[e] = rad(start_angle[e]) if search_axis[e] == "x" then xv, yv, zv = U.Rotate3D( 0, 0, 1, (xA+start_angle[e])+offax[e], yA+offay[e], zA+offaz[e]) xo,yo,zo = U.Rotate3D( offx[e], offy[e], offz[e], xA+start_angle[e], yA, zA ) elseif search_axis[e] == "z" then xv, yv, zv = U.Rotate3D( 0, 0, 1, xA+offax[e], yA+offay[e], (zA+start_angle[e])+offaz[e]) xo, yo, zo = U.Rotate3D( offx[e], offy[e], offz[e], xA, yA, zA+start_angle[e] ) else xv, yv, zv = U.Rotate3D( 0, 0, 1, xA+offax[e], (yA+start_angle[e])+offay[e], zA+offaz[e]) xo, yo, zo = U.Rotate3D( offx[e], offy[e], offz[e], xA, yA+start_angle[e], zA ) end start_angle[e] = math.deg(start_angle[e]) end SetLightPosition ( lightNum[e], x + xo, y + yo, z + zo ) SetLightAngle( lightNum[e], xv, yv, zv ) --PromptLocal(e,round(xv,2).." "..round(yv,2).." "..round(zv,2)) end end function sqrd( x1, z1, x2, z2 ) local dx, dz = x1 - x2, z1 - z2 return dx*dx+dz*dz end function Q.Sub (q1, q2) return { w = q1.w - q2.w, x = q1.x - q2.x, y = q1.y - q2.y, z = q1.z - q2.z } end function round(num, numDecimalPlaces) local mult = 10^(numDecimalPlaces or 0) return math.floor(num * mult + 0.5) / mult end