--DESCRIPTION: [MSG$="Inspect the object? (E)"] --DESCRIPTION: [INSPECTMSG$="This is..."] --DESCRIPTION: [PICKUPRANGE=100] --DESCRIPTION: [PICKUPANGLE=35] --DESCRIPTION: [XPOS=0] --DESCRIPTION: [YPOS=30] --DESCRIPTION: [ZPOS=30] --DESCRIPTION: [XSPD=60] --DESCRIPTION: [YSPD=60] --DESCRIPTION: [FOCUSDELAY=5] --DESCRIPTION: [AXOFFSET=0(0,360)] --DESCRIPTION: [AYOFFSET=0(0,360)] --DESCRIPTION: [AZOFFSET=0(0,360)] g_inspect_object = {} U = require "scriptbank\\utillib" Q = require "scriptbank\\quatlib" state = {} local startpos = {} local targetpos = {} local posq = {} local rotq = {} local myfocustime = 0 pressed = false local rad = math.rad local deg = math.deg function inspect_object_init(e) Include("utillib.lua") Include("quatlib.lua") inspect_object_properties(e, "Inspect the object? (E)", "This is...", 100,35, 0,30,30, 60,60, 5, 0,0,0) end function inspect_object_properties(e, msg, inspectmsg, pickuprange,pickupangle, xpos,ypos,zpos, xspd,yspd, focusdelay, axoffset,ayoffset,azoffset) g_inspect_object[e] = {} local ins = g_inspect_object[e] ins.msg = msg ins.inspectmsg = inspectmsg ins.pickuprange = pickuprange ins.pickupangle = pickupangle ins.xpos = xpos ins.ypos = ypos ins.zpos = zpos ins.xspd = xspd ins.yspd = yspd ins.focusdelay = focusdelay / 10 ins.axoffset = axoffset ins.ayoffset = ayoffset ins.azoffset = azoffset state[e] = "wait for pick up" end function inspect_object_main(e) local ins = g_inspect_object[e] if state[e] == "wait for pick up" then if U.PlayerLookingNear(e, ins.pickuprange, ins.pickupangle) == true then PromptLocal(e, ins.msg) if g_KeyPressE == 1 then if pressed == false then SetCameraOverride(3) local ex,ey,ez, eax,eay,eaz = GetEntityPosAng(e) startpos = {x = ex, y = ey, z = ez, ax = eax, ay = eay, az = eaz} local px,py,pz, pax,pay,paz = GetPlayerPosAng() -- work out the offset based on the player position and angle local ox,oy,oz = U.Rotate3D(ins.xpos, ins.ypos, ins.zpos, rad(pax), rad(pay), rad(paz)) -- update the target position based on the player position and angle -- we use the player y angle only so we can look at it from any side targetpos = { x = px+ox, y = py+oy, z = pz+oz, ax = ins.axoffset, ay = pay + ins.ayoffset, az = ins.azoffset } posq[1] = {x = startpos.x, y = startpos.y, z = startpos.z, w = 1} posq[2] = {x = targetpos.x, y = targetpos.y, z = targetpos.z, w = 1} rotq[1] = Q.FromEuler(rad(eax),rad(eay),rad(eaz)) rotq[2] = Q.FromEuler(rad(targetpos.ax),rad(targetpos.ay),rad(targetpos.az)) myfocustime = 0 CollisionOff(e) GravityOff(e) state[e] = "move to inspect" end pressed = true else pressed = false end end elseif state[e] == "move to inspect" then myfocustime = myfocustime + GetElapsedTime() if myfocustime < ins.focusdelay then local t = myfocustime / ins.focusdelay -- moves the object from it's starting position to the focus / inspect position over time local nq = Q.SLerp(posq[1],posq[2], t) SetPosition(e, nq.x, nq.y, nq.z) -- rotates the object over time to the inspect rotation nq = Q.SLerp(rotq[1],rotq[2], t) SetRotation(e, deg(nq.x), deg(nq.y), deg(nq.z)) else SetPosition(e, targetpos.x, targetpos.y, targetpos.z) SetRotation(e, targetpos.ax, targetpos.ay, targetpos.az) PlaySound(e,0) state[e] = "inspecting" end elseif state[e] == "inspecting" then PromptLocal(e,ins.inspectmsg) local ft = GetElapsedTime() * 100 if g_KeyPressW == 1 then RotateX(e, ins.yspd * ft) elseif g_KeyPressS == 1 then RotateX(e, -ins.yspd * ft) end if g_KeyPressA == 1 then RotateY(e, -ins.xspd * ft) elseif g_KeyPressD == 1 then RotateY(e, ins.xspd * ft) end if g_KeyPressE == 1 then if pressed == false then myfocustime = 0 local ex,ey,ez, eax,eay,eaz = GetEntityPosAng(e) posq[2] = {x = ex, y = ey, z = ez, w = 1} rotq[2] = Q.FromEuler(rad(eax),rad(eay),rad(eaz)) state[e] = "stop inspecting" end pressed = true else pressed = false end elseif state[e] == "stop inspecting" then -- we're doing the opposite of the focus here so move from target to start myfocustime = myfocustime + GetElapsedTime() if myfocustime < ins.focusdelay then local t = myfocustime / ins.focusdelay -- moves the object from it's starting position to the focus / inspect position over time local nq = Q.SLerp(posq[2],posq[1], t) SetPosition(e, nq.x, nq.y, nq.z) -- rotates the object over time to the inspect rotation nq = Q.SLerp(rotq[2],rotq[1], t) SetRotation(e, deg(nq.x), deg(nq.y), deg(nq.z)) else SetPosition(e, startpos.x, startpos.y, startpos.z) SetRotation(e, startpos.ax, startpos.ay, startpos.az) SetCameraOverride(0) state[e] = "wait for pick up" end end --Prompt(state[e].." , "..myfocustime.." , "..ins.focusdelay.." x = "..g_Entity[e].x.." y = "..g_Entity[e].y.." z = "..g_Entity[e].z) end function GetPlayerPosAng() local ppx,ppy,ppz = g_PlayerPosX,g_PlayerPosY,g_PlayerPosZ local ppax,ppay,ppaz = g_PlayerAngX,g_PlayerAngY,g_PlayerAngZ return ppx,ppy,ppz, ppax,ppay,ppaz end function QuatLerp( qa, qb, t) local x, y, z, w = QuatLERP( qa.x, qa.y, qa.z, qa.w, qb.x, qb.y, qb.z, qb.w, t ) return {w = w, x = x, y = y, z = z } end