script_name("CamHack")
script_author("sanek a.k.a Maks_Fender, edited by ANIKI")
require "lib.moonloader"
local mad = require "MoonAdditions"

-- ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ И КОНСТАНТЫ 
local camHack_posX, camHack_posY, camHack_posZ	= 0, 0, 0	-- Координаты позиции камеры
local camHack_angZ, camHack_angY				= 0, 0		-- Углы обзора камеры
local camHack_speed								= 1.0		-- Скорость камеры

local camHack_flyModeActive	= 0 -- Режим полета: 0 - отключен, 1 - включен

function main()
	while true do
		wait(0)
		
		if camHack_flyModeActive == 0 then
			--checkFlyModeActivation()
			if isKeyDown(VK_C) and isKeyDown(VK_1) then
				enterFlyMode()
			end
		else
			--handleFlyMode()
			if not sampIsChatInputActive() and not isSampfuncsConsoleActive() then
				adjustCameraAngles()
				moveCamera()
				drawDebugText()
				adjustSpeed()
				--checkFlyModeExit()
				if isKeyDown(VK_C) and isKeyDown(VK_2) then
					exitFlyMode()
				end
			end
		end
	end
end

function enterFlyMode()
	displayRadar(false)
	displayHud(false)
	camHack_posX, camHack_posY, camHack_posZ = getCharCoordinates(playerPed)
	camHack_angZ = -getCharHeading(playerPed) -- Inverted for correct orientation
	camHack_angY = 0.0
	setFixedCameraPosition(camHack_posX, camHack_posY, camHack_posZ, 0.0, 0.0, 0.0)
	lockPlayerControl(true)
	camHack_flyModeActive = 1
end

function exitFlyMode()
	lockPlayerControl(false)
	restoreCameraJumpcut()
	setCameraBehindPlayer()
	camHack_flyModeActive = 0
end

function adjustCameraAngles()
	local offMouX, offMouY = getPcMouseMovement()
	camHack_angZ = (camHack_angZ + offMouX / 4.0) % 360
	camHack_angY = math.max(math.min(camHack_angY + offMouY / 4.0, 89.0), -89.0)
end

function moveCamera()
	local movX, movY, movZ = calculateMovementVectors()
	
	if isKeyDown(VK_W) then
		movePosition(movX, movY, movZ)
	elseif isKeyDown(VK_S) then
		movePosition(-movX, -movY, -movZ)
	end

	if isKeyDown(VK_A) or isKeyDown(VK_D) then
		sideMove(isKeyDown(VK_A) and -math.pi / 2 or math.pi / 2)
	end

	if isKeyDown(VK_SPACE) then
		camHack_posZ = camHack_posZ + camHack_speed
	elseif isKeyDown(VK_SHIFT) then
		camHack_posZ = camHack_posZ - camHack_speed
	end
	
	updateCamera()
end

function calculateMovementVectors()
	local radZ, radY = math.rad(camHack_angZ), math.rad(camHack_angY)
	local sinZ, cosZ, sinY, cosY = math.sin(radZ), math.cos(radZ), math.sin(radY), math.cos(radY)
	return cosY * sinZ, cosY * cosZ, sinY
end

function movePosition(movX, movY, movZ)
	camHack_posX = camHack_posX + movX * camHack_speed
	camHack_posY = camHack_posY + movY * camHack_speed
	camHack_posZ = camHack_posZ + movZ * camHack_speed
end

function sideMove(angleOffset)
	local sideZ = math.sin(math.rad(camHack_angZ) + angleOffset)
	local sideX = math.cos(math.rad(camHack_angZ) + angleOffset)
	camHack_posX = camHack_posX + sideZ * camHack_speed
	camHack_posY = camHack_posY + sideX * camHack_speed
end

function updateCamera()
	setFixedCameraPosition(camHack_posX, camHack_posY, camHack_posZ, 0.0, 0.0, 0.0)
	local movX, movY, movZ = calculateMovementVectors()
	pointCameraAtPoint(camHack_posX + movX, camHack_posY + movY, camHack_posZ + movZ, 2)
end

function adjustSpeed()
	if isKeyDown(187) then
		camHack_speed = camHack_speed + 0.01
	elseif isKeyDown(189) then
		camHack_speed = math.max(camHack_speed - 0.01, 0.01)
	end
	printStringNow(string.format("Speed: %.2f", camHack_speed), 1000)
end

function drawDebugText()
	local movX, movY, movZ = calculateMovementVectors()
	local text = string.format(
		"~p~~h~CamHack Debug Info :3~n~" ..
		"~p~~h~~h~Position:~n~" ..
		" X: ~p~~h~%.2f ~p~~h~~h~ Y: ~p~~h~%.2f ~p~~h~~h~ Z: ~p~~h~%.2f~n~" ..
		"~p~~h~~h~Direction:~n~" ..
		" X: ~p~~h~%.2f ~p~~h~~h~ Y: ~p~~h~%.2f ~p~~h~~h~ Z: ~p~~h~%.2f~n~" ..
		"~p~~h~~h~Angles:~n~" ..
		" Z: ~p~~h~%.2f ~p~~h~~h~degrees~n~" ..
		" Y: ~p~~h~%.2f ~p~~h~~h~degrees~n~" ..
		"~p~~h~~h~Speed:~n~" ..
		" Current: ~p~~h~%.2f ~p~~h~~h~units/sec~n~",
		camHack_posX, camHack_posY, camHack_posZ,
		camHack_posX + movX, camHack_posY + movY, camHack_posZ + movZ,
		camHack_angZ, camHack_angY, camHack_speed
	)
	mad.draw_text(text, 45, 240, mad.font_style.BEFORE_TEXT, 0.48, 1.12, mad.font_align.LEFT, 9999, true, false, 
	              255, 255, 255, 255, 1, 2, 0, 0, 0, 150)
end

local sampev = require "lib.samp.events"

function sampev.onPlayerChatBubble(id, col, dist, dur, msg)
	if camHack_flyModeActive == 1 then return {id, col, 1488, dur, msg} end
end



на каких механизмах работает этот камхак, какие использует принципы и математические штуки