Files
2021-12-03 01:19:31 +00:00

625 lines
20 KiB
Lua

--------------------------------------------------
---- CINEMATIC CAM FOR FIVEM MADE BY KIMINAZE ----
--------------------------------------------------
--------------------------------------------------
------------------- VARIABLES --------------------
--------------------------------------------------
-- main variables
local cam = nil
local offsetRotX = 0.0
local offsetRotY = 0.0
local offsetRotZ = 0.0
local offsetCoords = {}
offsetCoords.x = 0.0
offsetCoords.y = 0.0
offsetCoords.z = 0.0
local counter = 0
local precision = 1.0
local currPrecisionIndex
local precisions = {}
for i = Cfg.minPrecision, Cfg.maxPrecision + 0.01, Cfg.incrPrecision do
table.insert(precisions, tostring(i))
counter = counter + 1
if (tostring(i) == "1.0") then
currPrecisionIndex = counter
end
end
local speed = 1.0
local currFilter = 1
local currFilterIntensity = 10
local filterInten = {}
for i=0.1, 2.01, 0.1 do table.insert(filterInten, tostring(i)) end
local freeFly = false
local isAttached = false
local entity
local camCoords
local pointEntity = false
-- menu variables
local _menuPool = NativeUI.CreatePool()
local camMenu
local itemCamPrecision
local itemFilter
local itemFilterIntensity
local itemAttachCam
local itemPointEntity
-- print error if no menu access was specified
if (not(Cfg.useButton or Cfg.useCommand)) then
print(Cfg.strings.noAccessError)
end
--------------------------------------------------
---------------------- LOOP ----------------------
--------------------------------------------------
Citizen.CreateThread(function()
local pressedCount = 0
camMenu = NativeUI.CreateMenu(Cfg.strings.menuTitle, Cfg.strings.menuSubtitle)
_menuPool:Add(camMenu)
while true do
Citizen.Wait(1)
-- process menu
if (_menuPool:IsAnyMenuOpen()) then
_menuPool:ProcessMenus()
end
-- open / close menu on button press
if (Cfg.useButton) then
if (IsDisabledControlPressed(1, Cfg.controls.controller.openMenu)) then
pressedCount = pressedCount + 1
elseif (IsDisabledControlJustReleased(1, Cfg.controls.controller.openMenu)) then
pressedCount = 0
end
if (IsDisabledControlJustReleased(1, Cfg.controls.keyboard.openMenu) or pressedCount >= 60) then
if (pressedCount >= 60) then pressedCount = 0 end
if (camMenu:Visible()) then
camMenu:Visible(false)
else
GenerateCamMenu()
camMenu:Visible(true)
end
end
end
-- process cam controls if cam exists
if (cam) then
ProcessCamControls()
end
end
end)
Citizen.CreateThread(function()
while true do
Citizen.Wait(500)
if (camMenu:Visible() and cam) then
local tempEntity = GetEntityInFrontOfCam()
local txt = "-"
if (DoesEntityExist(tempEntity)) then
txt = tostring(GetEntityModel(tempEntity))
if (IsEntityAVehicle(tempEntity)) then
txt = GetLabelText(GetDisplayNameFromVehicleModel(GetEntityModel(tempEntity)))
end
end
itemAttachCam:RightLabel(txt)
if (isAttached and not DoesEntityExist(entity)) then
isAttached = false
ClearFocus()
StopCamPointing(cam)
end
end
end
end)
--------------------------------------------------
---------------------- MENU ----------------------
--------------------------------------------------
function GenerateCamMenu()
_menuPool:Remove()
_menuPool = NativeUI.CreatePool()
collectgarbage()
camMenu = NativeUI.CreateMenu(Cfg.strings.menuTitle, Cfg.strings.menuSubtitle)
_menuPool:Add(camMenu)
-- add additional control help
--camMenu:AddInstructionButton({GetControlInstructionalButton(1, 38, true), ""})
--camMenu:AddInstructionButton({GetControlInstructionalButton(1, 44, true), Cfg.strings.ctrlHelpRoll})
--camMenu:AddInstructionButton({GetControlInstructionalButton(1, 36, true), ""})
--camMenu:AddInstructionButton({GetControlInstructionalButton(1, 21, true), ""})
--camMenu:AddInstructionButton({GetControlInstructionalButton(1, 30, true), ""})
--camMenu:AddInstructionButton({GetControlInstructionalButton(1, 31, true), Cfg.strings.ctrlHelpMove})
--camMenu:AddInstructionButton({GetControlInstructionalButton(1, 2, true), ""})
--camMenu:AddInstructionButton({GetControlInstructionalButton(1, 1, true), Cfg.strings.ctrlHelpRotate})
local itemToggleCam = NativeUI.CreateCheckboxItem(Cfg.strings.toggleCam, DoesCamExist(cam), Cfg.strings.toggleCamDesc)
camMenu:AddItem(itemToggleCam)
itemCamPrecision = NativeUI.CreateListItem(Cfg.strings.precision, precisions, currPrecisionIndex, Cfg.strings.precisionDesc)
camMenu:AddItem(itemCamPrecision)
local submenuFilter = _menuPool:AddSubMenu(camMenu, Cfg.strings.filter, Cfg.strings.filterDesc)
camMenu.Items[#camMenu.Items]:SetLeftBadge(15)
itemFilter = NativeUI.CreateListItem(Cfg.strings.filter, Cfg.filterList, currFilter, Cfg.strings.filterDesc)
submenuFilter:AddItem(itemFilter)
itemFilterIntensity = NativeUI.CreateListItem(Cfg.strings.filterInten, filterInten, currFilterIntensity, Cfg.strings.filterIntenDesc)
submenuFilter:AddItem(itemFilterIntensity)
local itemDelFilter = NativeUI.CreateItem(Cfg.strings.delFilter, Cfg.strings.delFilterDesc)
submenuFilter:AddItem(itemDelFilter)
local itemShowMap = NativeUI.CreateCheckboxItem(Cfg.strings.showMap, not IsRadarHidden(), Cfg.strings.showMapDesc)
camMenu:AddItem(itemShowMap)
local itemToggleFreeFlyMode = NativeUI.CreateCheckboxItem(Cfg.strings.freeFly, freeFly, Cfg.strings.freeFlyDesc)
camMenu:AddItem(itemToggleFreeFlyMode)
itemAttachCam = NativeUI.CreateItem(Cfg.strings.attachCam, Cfg.strings.attachCamDesc)
camMenu:AddItem(itemAttachCam)
--itemPointEntity = NativeUI.CreateCheckboxItem(Cfg.strings.pointEntity, pointEntity, Cfg.strings.pointEntityDesc)
--camMenu:AddItem(itemPointEntity)
itemToggleCam.CheckboxEvent = function(menu, item, checked)
ToggleCam(checked, GetGameplayCamFov())
end
itemCamPrecision.OnListChanged = function(menu, item, newindex)
ChangePrecision(newindex)
end
itemShowMap.CheckboxEvent = function(menu, item, checked)
ToggleUI(checked)
end
itemToggleFreeFlyMode.CheckboxEvent = function(menu, item, checked)
ToggleFreeFlyMode(checked)
end
camMenu.OnItemSelect = function(menu, item, index)
if (item == itemAttachCam) then
ToggleAttachMode()
end
end
--[[itemPointEntity.CheckboxEvent = function(menu, item, checked)
TogglePointing(checked)
end]]
itemFilter.OnListChanged = function(menu, item, newindex)
ApplyFilter(newindex)
end
itemFilterIntensity.OnListChanged = function(menu, item, newindex)
ChangeFilterIntensity(newindex)
end
submenuFilter.OnItemSelect = function(menu, item, index)
if (item == itemDelFilter) then
ResetFilter()
end
end
_menuPool:ControlDisablingEnabled(false)
_menuPool:MouseControlsEnabled(false)
_menuPool:RefreshIndex()
end
--------------------------------------------------
------------------- FUNCTIONS --------------------
--------------------------------------------------
-- initialize camera
function StartFreeCam(fov)
ClearFocus()
local playerPed = PlayerPedId()
cam = CreateCamWithParams("DEFAULT_SCRIPTED_CAMERA", GetEntityCoords(playerPed), 0, 0, 0, fov * 1.0)
SetCamActive(cam, true)
RenderScriptCams(true, false, 0, true, false)
SetCamAffectsAiming(cam, false)
if (isAttached and DoesEntityExist(entity)) then
offsetCoords = GetOffsetFromEntityGivenWorldCoords(entity, GetCamCoord(cam))
AttachCamToEntity(cam, entity, offsetCoords.x, offsetCoords.y, offsetCoords.z, true)
end
end
-- destroy camera
function EndFreeCam()
ClearFocus()
RenderScriptCams(false, false, 0, true, false)
DestroyCam(cam, false)
offsetRotX = 0.0
offsetRotY = 0.0
offsetRotZ = 0.0
isAttached = false
speed = 1.0
precision = 1.0
currFov = GetGameplayCamFov()
cam = nil
end
-- process camera controls
function ProcessCamControls()
local playerPed = PlayerPedId()
-- disable 1st person as the 1st person camera can cause some glitches
DisableFirstPersonCamThisFrame()
-- block weapon wheel (reason: scrolling)
BlockWeaponWheelThisFrame()
-- disable character/vehicle controls
for k, v in pairs(Cfg.disabledControls) do
DisableControlAction(0, v, true)
end
if (isAttached) then
-- calculate new position
offsetCoords = ProcessNewPosition(offsetCoords.x, offsetCoords.y, offsetCoords.z)
-- focus entity
SetFocusEntity(entity)
-- set coords
AttachCamToEntity(cam, entity, offsetCoords.x, offsetCoords.y, offsetCoords.z, true)
-- reset coords of cam if too far from entity
if (Vdist(0.0, 0.0, 0.0, offsetCoords.x, offsetCoords.y, offsetCoords.z) > Cfg.maxDistance) then
AttachCamToEntity(cam, entity, offsetCoords.x, offsetCoords.y, offsetCoords.z, true)
end
-- set rotation
local entityRot = GetEntityRotation(entity, 2)
SetCamRot(cam, entityRot.x + offsetRotX, entityRot.y + offsetRotY, entityRot.z + offsetRotZ, 2)
else
local camCoords = GetCamCoord(cam)
-- calculate new position
local newPos = ProcessNewPosition(camCoords.x, camCoords.y, camCoords.z)
-- focus cam area
SetFocusArea(newPos.x, newPos.y, newPos.z, 0.0, 0.0, 0.0)
-- set coords of cam
SetCamCoord(cam, newPos.x, newPos.y, newPos.z)
-- set rotation
SetCamRot(cam, offsetRotX, offsetRotY, offsetRotZ, 2)
end
end
function ProcessNewPosition(x, y, z)
local _x = x
local _y = y
local _z = z
--gegenkathete = z
--ankathete = y
--hypotenuse = 1
--alpha = GetCamRot(cam).x
-- keyboard
if (IsInputDisabled(0)) then
if (IsDisabledControlPressed(1, Cfg.controls.keyboard.forwards)) then
local multX = Sin(offsetRotZ)
local multY = Cos(offsetRotZ)
local multZ = Sin(offsetRotX)
_x = _x - (0.1 * speed * multX)
_y = _y + (0.1 * speed * multY)
if (freeFly) then
_z = _z + (0.1 * speed * multZ)
end
end
if (IsDisabledControlPressed(1, Cfg.controls.keyboard.backwards)) then
local multX = Sin(offsetRotZ)
local multY = Cos(offsetRotZ)
local multZ = Sin(offsetRotX)
_x = _x + (0.1 * speed * multX)
_y = _y - (0.1 * speed * multY)
if (freeFly) then
_z = _z - (0.1 * speed * multZ)
end
end
if (IsDisabledControlPressed(1, Cfg.controls.keyboard.left)) then
local multX = Sin(offsetRotZ + 90.0)
local multY = Cos(offsetRotZ + 90.0)
local multZ = Sin(offsetRotY)
_x = _x - (0.1 * speed * multX)
_y = _y + (0.1 * speed * multY)
if (freeFly) then
_z = _z + (0.1 * speed * multZ)
end
end
if (IsDisabledControlPressed(1, Cfg.controls.keyboard.right)) then
local multX = Sin(offsetRotZ + 90.0)
local multY = Cos(offsetRotZ + 90.0)
local multZ = Sin(offsetRotY)
_x = _x + (0.1 * speed * multX)
_y = _y - (0.1 * speed * multY)
if (freeFly) then
_z = _z - (0.1 * speed * multZ)
end
end
if (IsDisabledControlPressed(1, Cfg.controls.keyboard.up)) then
_z = _z + (0.1 * speed)
end
if (IsDisabledControlPressed(1, Cfg.controls.keyboard.down)) then
_z = _z - (0.1 * speed)
end
if (IsDisabledControlPressed(1, Cfg.controls.keyboard.hold)) then
-- hotkeys for speed
if (IsDisabledControlPressed(1, Cfg.controls.keyboard.speedUp)) then
if ((speed + 0.1) < Cfg.maxSpeed) then
speed = speed + 0.1
else
speed = Cfg.maxSpeed
end
elseif (IsDisabledControlPressed(1, Cfg.controls.keyboard.speedDown)) then
if ((speed - 0.1) > Cfg.minSpeed) then
speed = speed - 0.1
else
speed = Cfg.minSpeed
end
end
else
-- hotkeys for FoV
if (IsDisabledControlPressed(1, Cfg.controls.keyboard.zoomOut)) then
ChangeFov(1.0)
elseif (IsDisabledControlPressed(1, Cfg.controls.keyboard.zoomIn)) then
ChangeFov(-1.0)
end
end
-- rotation
offsetRotX = offsetRotX - (GetDisabledControlNormal(1, 2) * precision * 8.0)
offsetRotZ = offsetRotZ - (GetDisabledControlNormal(1, 1) * precision * 8.0)
if (IsDisabledControlPressed(1, Cfg.controls.keyboard.rollLeft)) then
offsetRotY = offsetRotY - precision
end
if (IsDisabledControlPressed(1, Cfg.controls.keyboard.rollRight)) then
offsetRotY = offsetRotY + precision
end
-- controller
else
local multX = Sin(offsetRotZ)
local multY = Cos(offsetRotZ)
local multZ = Sin(offsetRotX)
_x = _x - (0.1 * speed * multX * GetDisabledControlNormal(1, 32))
_y = _y + (0.1 * speed * multY * GetDisabledControlNormal(1, 32))
if (freeFly) then
_z = _z + (0.1 * speed * multZ * GetDisabledControlNormal(1, 32))
end
_x = _x + (0.1 * speed * multX * GetDisabledControlNormal(1, 33))
_y = _y - (0.1 * speed * multY * GetDisabledControlNormal(1, 33))
if (freeFly) then
_z = _z - (0.1 * speed * multZ * GetDisabledControlNormal(1, 33))
end
multX = Sin(offsetRotZ + 90.0)
multY = Cos(offsetRotZ + 90.0)
local multZ = Sin(offsetRotY)
_x = _x - (0.1 * speed * multX * GetDisabledControlNormal(1, 34))
_y = _y + (0.1 * speed * multY * GetDisabledControlNormal(1, 34))
if (freeFly) then
_z = _z + (0.1 * speed * multZ * GetDisabledControlNormal(1, 34))
end
_x = _x + (0.1 * speed * multX * GetDisabledControlNormal(1, 35))
_y = _y - (0.1 * speed * multY * GetDisabledControlNormal(1, 35))
if (freeFly) then
_z = _z - (0.1 * speed * multZ * GetDisabledControlNormal(1, 35))
end
-- FoV, Speed, Up/Down Movement
if (GetDisabledControlNormal(1, 228) ~= 0.0) then
if (IsDisabledControlPressed(1, Cfg.controls.controller.holdFov)) then
ChangeFov(GetDisabledControlNormal(1, 228))
elseif (IsDisabledControlPressed(1, Cfg.controls.controller.holdSpeed)) then
local newSpeed = speed - (0.1 * GetDisabledControlNormal(1, 228))
if (newSpeed > Cfg.minSpeed) then
speed = newSpeed
else
speed = Cfg.minSpeed
end
else
_z = _z - (0.1 * speed * GetDisabledControlNormal(1, 228))
end
end
if (GetDisabledControlNormal(1, 229) ~= 0.0) then
if (IsDisabledControlPressed(1, Cfg.controls.controller.holdFov)) then
ChangeFov(- GetDisabledControlNormal(1, 229))
elseif (IsDisabledControlPressed(1, Cfg.controls.controller.holdSpeed)) then
local newSpeed = speed + (0.1 * GetDisabledControlNormal(1, 229))
if (newSpeed < Cfg.maxSpeed) then
speed = newSpeed
else
speed = Cfg.maxSpeed
end
else
_z = _z + (0.1 * speed * GetDisabledControlNormal(1, 229))
end
end
-- rotation
offsetRotX = offsetRotX - (GetDisabledControlNormal(1, 2) * precision)
offsetRotZ = offsetRotZ - (GetDisabledControlNormal(1, 1) * precision)
if (IsDisabledControlPressed(1, Cfg.controls.controller.rollLeft)) then
offsetRotY = offsetRotY - precision
end
if (IsDisabledControlPressed(1, Cfg.controls.controller.rollRight)) then
offsetRotY = offsetRotY + precision
end
end
if (offsetRotX > 90.0) then offsetRotX = 90.0 elseif (offsetRotX < -90.0) then offsetRotX = -90.0 end
if (offsetRotY > 90.0) then offsetRotY = 90.0 elseif (offsetRotY < -90.0) then offsetRotY = -90.0 end
if (offsetRotZ > 360.0) then offsetRotZ = offsetRotZ - 360.0 elseif (offsetRotZ < -360.0) then offsetRotZ = offsetRotZ + 360.0 end
return {x = _x, y = _y, z = _z}
end
function ToggleCam(flag, fov)
if (flag) then
StartFreeCam(fov)
_menuPool:RefreshIndex()
else
EndFreeCam()
_menuPool:RefreshIndex()
end
end
function ChangeFov(changeFov)
if (DoesCamExist(cam)) then
local currFov = GetCamFov(cam)
local newFov = currFov + changeFov
if ((newFov >= Cfg.minFov) and (newFov <= Cfg.maxFov)) then
SetCamFov(cam, newFov)
end
end
end
function ChangePrecision(newindex)
precision = itemCamPrecision.Items[newindex]
currPrecisionIndex = newindex
end
function ToggleUI(flag)
DisplayRadar(flag)
end
function ToggleFreeFlyMode(flag)
freeFly = flag
end
function GetEntityInFrontOfCam()
local camCoords = GetCamCoord(cam)
local offset = {x = camCoords.x - Sin(offsetRotZ) * 100.0, y = camCoords.y + Cos(offsetRotZ) * 100.0, z = camCoords.z + Sin(offsetRotX) * 100.0}
local rayHandle = StartShapeTestRay(camCoords.x, camCoords.y, camCoords.z, offset.x, offset.y, offset.z, 10, 0, 0)
local a, b, c, d, entity = GetShapeTestResult(rayHandle)
return entity
end
function ToggleAttachMode()
if (not isAttached) then
entity = GetEntityInFrontOfCam()
if (DoesEntityExist(entity)) then
offsetCoords = GetOffsetFromEntityGivenWorldCoords(entity, GetCamCoord(cam))
Citizen.Wait(1)
local camCoords = GetCamCoord(cam)
AttachCamToEntity(cam, entity, GetOffsetFromEntityInWorldCoords(entity, camCoords.x, camCoords.y, camCoords.z), true)
isAttached = true
end
else
ClearFocus()
DetachCam(cam)
isAttached = false
end
end
function TogglePointing(flag)
if (flag and isAttached) then
pointEntity = true
PointCamAtEntity(cam, entity, 0.0, 0.0, 0.0, 1)
else
pointEntity = false
StopCamPointing(cam)
end
end
function ApplyFilter(filterIndex)
SetTimecycleModifier(Cfg.filterList[filterIndex])
currFilter = filterIndex
end
function ChangeFilterIntensity(intensityIndex)
SetTimecycleModifier(Cfg.filterList[currFilter])
SetTimecycleModifierStrength(tonumber(filterInten[intensityIndex]))
currFilterIntensity = intensityIndex
end
function ResetFilter()
ClearTimecycleModifier()
itemFilter._Index = 1
currFilter = 1
itemFilterIntensity._Index = 10
currFilterIntensity = 10
end
--------------------------------------------------
-------------------- COMMANDS --------------------
--------------------------------------------------
-- register command if specified in config
if (Cfg.useCommand) then
RegisterCommand(Cfg.command, function(source, args, raw)
if (not camMenu:Visible()) then
GenerateCamMenu()
camMenu:Visible(true)
end
end)
end
--void POINT_CAM_AT_ENTITY(Cam cam, Entity entity, float p2, float p3, float p4, BOOL p5);
--void POINT_CAM_AT_COORD(Cam cam, float x, float y, float z);
--void GET_CAM_MATRIX(Cam camera, Vector3* rightVector, Vector3* forwardVector, Vector3* upVector, Vector3* position);
--gegenkathete = x
--ankathete = y
--hypotenuse = 1
--alpha = GetCamRot(cam).z