local zoom=10 --how far is camera target from ufo
local mouseFrameDelay = 0
local ratio = 3 --how many times distance from camera to ufo is smaller then distance from ufo to camera target
local mouseSensetivity = 0.25 --ovbious much?
local width, height = guiGetScreenSize()
local PI = math.pi
local hit
local zOffset = 3 --how much the camera is higher then ufo itself.
-- state variables
local speed = 0
local rotX, rotY = 0,0
-- configurable parameters
local options = {
invertMouseLook = false,
normalMaxSpeed = 2,
slowMaxSpeed = 0.2,
fastMaxSpeed = 12,
smoothMovement = true,
acceleration = 0.3,
decceleration = 0.15,
maxYAngle = 188,
key_fastMove = "lshift",
key_slowMove = "lalt",
key_forward = "w",
}
local rootElement = getRootElement()
local getKeyState = getKeyState
do
local mta_getKeyState = getKeyState
function getKeyState(key)
if isMTAWindowActive() then
return false
else
return mta_getKeyState(key)
end
end
end
--heavily modified freecam resource's core
function freecamFrame()
local cameraAngleX = rotX
local cameraAngleY = rotY
local freeModeAngleZ = math.sin(cameraAngleY)
local freeModeAngleY = math.cos(cameraAngleY) * math.cos(cameraAngleX)
local freeModeAngleX = math.cos(cameraAngleY) * math.sin(cameraAngleX)
local camPosX, camPosY, camPosZ = getElementPosition(ufo)
local camPosZ = camPosZ + zOffset
local mspeed = options.normalMaxSpeed
if getKeyState ( options.key_fastMove ) then
mspeed = options.fastMaxSpeed
elseif getKeyState ( options.key_slowMove ) then
mspeed = options.slowMaxSpeed
end
if options.smoothMovement then
local acceleration = options.acceleration
local decceleration = options.decceleration
-- Check to see if the forwards key are pressed
local speedKeyPressed = false
if getKeyState ( options.key_forward ) then
speed = speed + acceleration
speedKeyPressed = true
end
-- If no forwards key were pressed, then gradually slow down the movement towards 0
if not speedKeyPressed then
speed = speed - decceleration
end
-- Check the ranges of values - set the speed to 0 if its very close to 0 (stops jittering), and limit to the maximum speed
if speed < decceleration then
speed = 0
elseif speed > mspeed then
speed = mspeed
end
else
speed = 0
if getKeyState ( options.key_forward ) then speed = mspeed end
end
-- Update the camera position based on the forwards/backwards speed
camPosX = camPosX + freeModeAngleX * speed
camPosY = camPosY + freeModeAngleY * speed
-- calculate a target based on the current position and an offset based on the angle
local camTargetX = camPosX + freeModeAngleX * zoom
local camTargetY = camPosY + freeModeAngleY * zoom
local camTargetZ = camPosZ + freeModeAngleZ * zoom
camPosX = camPosX - ( camTargetX - camPosX ) / ratio
camPosY = camPosY - ( camTargetY - camPosY ) / ratio
camPosZ = camPosZ - ( camTargetZ - camPosZ ) / ratio
if not isLineOfSightClear(camPosX,camPosY,camPosZ,camPosX,camPosY,camPosZ,true,true,true,true,false,true,false,localPlayer) then
_,camPosX,camPosY,camPosZ=processLineOfSight(camPosX,camPosY,camPosZ,camPosX,camPosY,camPosZ,true,true,true,true,false,true,false,false,localPlayer)
end
-- Set the new camera position and target
setElementRotation(ufo,0,0,math.deg(rotX))
setCameraMatrix ( camPosX, camPosY, camPosZ, camTargetRealX, camTargetRealY, camTargetRealZ )
end
function freecamMouse(_,_,aX,aY)
--ignore mouse movement if the cursor or MTA window is on
--and do not resume it until at least 5 frames after it is toggled off
--(prevents cursor mousemove data from reaching this handler)
if isCursorShowing() or isMTAWindowActive() then
mouseFrameDelay = 5
return
elseif mouseFrameDelay > 0 then
mouseFrameDelay = mouseFrameDelay - 1
return
end
if options.invertMouseLook then
aY = -aY
end
-- how far have we moved the mouse from the screen center?
aX = aX - width / 2
aY = aY - height / 2
rotX = rotX + aX * 0.01745 * mouseSensetivity
rotY = rotY - aY * 0.01745 * mouseSensetivity
if rotX > PI then
rotX = rotX - 2 * PI
elseif rotX < -PI then
rotX = rotX + 2 * PI
end
if rotY > PI then
rotY = rotY - 2 * PI
elseif rotY < -PI then
rotY = rotY + 2 * PI
end
-- limit the camera to stop it going too far up or down - PI/2 is the limit, but we can't let it quite reach that or it will lock up
-- and strafeing will break entirely as the camera loses any concept of what is 'up'
if rotY < -PI / 3 then
rotY = -PI / 3
elseif rotY > PI / 3 then
rotY = PI / 3
end
-- work out an angle in radians based on the number of pixels the cursor has moved (ever)
end
report bugs if any.
ufo elem is ur ufo btw.