local ffi = require("ffi")
local samem = require("SAMemory")
local mad = require("MoonAdditions")

samem.require("CVehicle")
local player_vehicle = samem.cast('CVehicle **', samem.player_vehicle)
samem.require("vector3d")

local CShadows__StoreCarLightShadow = ffi.cast("void(__cdecl*)(CVehicle*, int, uintptr_t, vector3d*, float, float, float, float, unsigned char, unsigned char, unsigned char, float)", 0x70C500)


--HOOKS
local hook = {hooks = {}}
addEventHandler('onScriptTerminate', function(scr)
    if scr == script.this then
        for i, hook in ipairs(hook.hooks) do
            if hook.status then
                hook.stop()
            end
        end
    end
end)
ffi.cdef [[
    int VirtualProtect(void* lpAddress, unsigned long dwSize, unsigned long flNewProtect, unsigned long* lpflOldProtect);
]]
function hook.new(cast, callback, hook_addr, size)
    jit.off(callback, true) --off jit compilation | thx FYP
    local size = size or 5
    local new_hook = {}
    local detour_addr = tonumber(ffi.cast('intptr_t', ffi.cast('void*', ffi.cast(cast, callback))))
    local void_addr = ffi.cast('void*', hook_addr)
    local old_prot = ffi.new('unsigned long[1]')
    local org_bytes = ffi.new('uint8_t[?]', size)
    ffi.copy(org_bytes, void_addr, size)
    local hook_bytes = ffi.new('uint8_t[?]', size, 0x90)
    hook_bytes[0] = 0xE9
    ffi.cast('uint32_t*', hook_bytes + 1)[0] = detour_addr - hook_addr - 5
    new_hook.call = ffi.cast(cast, hook_addr)
    new_hook.status = false
    local function set_status(bool)
        new_hook.status = bool
        ffi.C.VirtualProtect(void_addr, size, 0x40, old_prot)
        ffi.copy(void_addr, bool and hook_bytes or org_bytes, size)
        ffi.C.VirtualProtect(void_addr, size, old_prot[0], old_prot)
    end
    new_hook.stop = function() set_status(false) end
    new_hook.start = function() set_status(true) end
    new_hook.start()
    table.insert(hook.hooks, new_hook)
    return setmetatable(new_hook, {
        __call = function(self, ...)
            self.stop()
            local res = self.call(...)
            self.start()
            return res
        end
    })
end
--HOOKS

local functionAddress = 0x6D64F0

function vehicleHookCallback(this)
	print("CVehicle::SetupRender is called for vehicle: ", this)
	--renderShadow()
	-- Вызовите оригинальную функцию, чтобы сохранить её функциональность
	if isCharInAnyCar(playerPed) then
		renderShadow()
	end
	vehicleHook(this)
	-- vehicleHook.stop()
	-- vehicleHook.call(this)
	-- vehicleHook.start()
end

function main()
    while not isSampAvailable() do wait(80) end
	
	--void(__thiscall *)(void *this, CVehicle*)
	
	vehicleHook = hook.new('void (__thiscall *)(CVehicle*)', vehicleHookCallback, functionAddress)
    while true do wait(0) 
		--renderShadow()
    end
end

function renderShadow()
	if isCharInAnyCar(playerPed) then
		local playerVehicle = samem.player_vehicle[0]
		if playerVehicle ~= samem.nullptr then
			local vehicle = storeCarCharIsInNoSave(playerPed)
			
			local x, y, z = mad.get_vehicle_dummy_element_position(vehicle, 6, true)
			--print(x, y, z)
	
			local lightPosition = ffi.new("vector3d")
			lightPosition.x, lightPosition.y, lightPosition.z = x, y, z
	
			local textureMemory = mad.texture.from_memory(0xC403F4)
			local texturePointer = textureMemory:get_pointer()
			sampAddChatMessage("texturePointer = " .. tostring(texturePointer), -1)
	
			local frontDirectionX, frontDirectionY = 0.5, 0
			local sideDirectionX, sideDirectionY = 0, 0.5
			local lightColorRed, lightColorGreen, lightColorBlue = 155, 155, 155
			local maxViewAngle = 255
	
			CShadows__StoreCarLightShadow(
				playerVehicle, 
				2, 
				texturePointer, 
				lightPosition, 
				frontDirectionX, 
				frontDirectionY, 
				sideDirectionX, 
				sideDirectionY, 
				lightColorRed, 
				lightColorGreen, 
				lightColorBlue, 
				maxViewAngle
			)
	
			sampAddChatMessage("stored!", -1)
		end
	end
end





отрефактори код, названия переменных, структуру, все такое