[ML] (error) testoviy: cannot resume non-suspended coroutine
stack traceback:
	[C]: in function '__index'
	...username\Desktop\GTA San Andreas\moonloader\testoviy.lua:266: in function 'applyMoveForce'
	...username\Desktop\GTA San Andreas\moonloader\testoviy.lua:115: in function <...username\Desktop\GTA San Andreas\moonloader\testoviy.lua:57>
[ML] (error) testoviy: Script died due to an error. (065AF354)

почему?
вот код

script_name('testoviy')

--ЗАВИСИМОСТИ
local memory = require 'memory'
local samem = require 'SAMemory'

samem.require 'CVehicle'
samem.require 'tHandlingData'
samem.require 'CAutomobile'

--ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ И КОНСТАНТЫ
local CAR_WHEEL_FRONT_LEFT  = 0
local CAR_WHEEL_REAR_LEFT   = 1
local CAR_WHEEL_FRONT_RIGHT = 2
local CAR_WHEEL_REAR_RIGHT  = 3

local UP        = 0
local DOWN      = 1
local LEFT      = 2
local RIGHT     = 3
local FORWARD   = 4    
local BACK      = 5

local dirVecs = {
 [0] = { x = 0.0,  y = 0.0,  z = 1.0  }, -- UP
 [1] = { x = 0.0,  y = 0.0,  z = -1.0 }, -- DOWN
 [2] = { x = -1.0, y = 0.0,  z = 0.0  }, -- LEFT
 [3] = { x = 1.0,  y = 0.0,  z = 0.0  }, -- RIGHT
 [4] = { x = 0.0,  y = 1.0,  z = 0.0  }, -- FORWARD
 [5] = { x = 0.0,  y = -1.0, z = 0.0  }  -- BACK
}

--НАСТРОЙКИ

-- speedLowerThreshold	– минимальное пороговое значение скорости, при достижении которого активируется скрипт
-- по умолчанию скрипт использует значение 0.02. у оригинальной механики игры это ограничение отсутствует
-- для достижения похоже эффекта можно установить значение отрицательной бесконечности (-math.huge)
-- однако, поскольку скрипт не отключает оригинальную механику игры, это ПРИВЕДЕТ К НЕКОТОРЫМ КОНФЛИКТАМ !!!

-- speedUpperThreshold	– максимальное пороговое значение скорости, при превышении которого деактивируется скрипт
-- по умолчанию скрипт использует значение бесконечности (math.huge), то есть верхний предел отстутствует
-- у оригинальной механики игры этот предел имеет значение 0.02.

-- ОБРАТИТЕ ВНИМАНИЕ, что скорость измеряется в ХУЙ ПОЙМИ КАКИХ единицах,
-- эти единицы - половина значения от скорости, используемой гамбитом на спидометре 
-- что там с другими серверами не знаю ¯\_(ツ)_/¯

-- rollOnToWheelsForce	– величина силы, возвращающей автомобиль на колеса
-- по умолчанию скрипт использует значение 0.0050. а оригинальная механика игры 0.0025

local speedLowerThreshold	= 0.02		 -- (0.02)		- ПОРОГ СКОРОСТИ ПОСЛЕ КОТОРОГО НАЧИНАЕТ РАБОТАТЬ СКРИПТ
local speedUpperThreshold   = math.huge	 -- (math.huge)	- ПОРОГ СКОРОСТИ ПОСЛЕ КОТОРОГО ПЕРЕСТАЕТ РАБОТАТЬ СКРИПТ
local rollOnToWheelsForce   = 0.0050	 -- (0.0025)	- ВЕЛИЧИНА СИЛЫ ПЕРЕВОРАЧИВАЮЩЕЙ МАШИНУ НА КОЛЕСА


--ОСНОВНАЯ ФУНКЦИЯ
function main()
	while not isPlayerPlaying(PLAYER_HANDLE) do wait(100) end
	wait(1000)

	while true do wait(0)
		if isCharInAnyCar(playerPed) then
			local car = storeCarCharIsInNoSave(playerPed)
			if doesVehicleExist(car) then
				local carPointer = getCarPointer(car)
				local vehicle = samem.cast("CVehicle *", carPointer)
				if vehicle ~= samem.nullptr then
					if vehicle.nVehicleClass == 0 then -- на самом деле это не класс, а тип. VEHICLE_TYPE_AUTOMOBILE  = 0
						local automobile = samem.cast('CAutomobile *', vehicle)
			
						-- не был уверен что getCarSpeed выдает скорость относительно оси Y
						-- поэтому использовал такой костыль с получением скорости из вектора
						local moveSpeed							= {}
							  moveSpeed.x,
							  moveSpeed.y,
							  moveSpeed.z						= getCarSpeedVector(car)
						local forwardDirection					= getCarSide(car, FORWARD)
						local forwardSpeed						= dot(moveSpeed, forwardDirection)
						local m_fWheelsSuspensionCompression	= automobile.wheelsDistancesToGround1
						local m_fMass							= automobile.fMass
						local m_fTurnMass						= automobile.fTurnMass
						local x1, y1, z1, x2, y2, z2			= getModelDimensions(getCarModel(car))
						local m_vecMax_x						= math.max(x1, x2)
						
--						if forwardSpeed < speedThreshold then ~~> В ОРИГИНАЛЕ СДЕЛАНО ТАК, НО СКРИПТ НЕ ДОЛЖЕН С НИМ КОНФЛИКТОВАТЬ, ВЕРНО?
						if forwardSpeed > speedLowerThreshold and forwardSpeed < speedUpperThreshold then
							local fDir = 0.0
							local leftSuspended = m_fWheelsSuspensionCompression[CAR_WHEEL_FRONT_LEFT] == 1.0 and
												  m_fWheelsSuspensionCompression[CAR_WHEEL_REAR_LEFT] == 1.0 and
												  (m_fWheelsSuspensionCompression[CAR_WHEEL_FRONT_RIGHT] < 1.0 or 
												  m_fWheelsSuspensionCompression[CAR_WHEEL_REAR_RIGHT] < 1.0)
												  
							local rightSuspended = m_fWheelsSuspensionCompression[CAR_WHEEL_FRONT_RIGHT] == 1.0 and
												   m_fWheelsSuspensionCompression[CAR_WHEEL_REAR_RIGHT]== 1.0 and
												   (m_fWheelsSuspensionCompression[CAR_WHEEL_FRONT_LEFT] < 1.0 or 
												   m_fWheelsSuspensionCompression[CAR_WHEEL_REAR_LEFT] < 1.0)

							if leftSuspended then
								fDir = 1.0
							elseif rightSuspended then
								fDir = -1.0
							end

							if fDir ~= 0.0 then
								local right = cross(getCarSide(car, FORWARD), dirVecs[UP])
								
								if math.abs(dot(right, getCarSide(car, RIGHT))) < 0.6 then
															
									local force = multiply(getCarSide(car, UP), fDir * rollOnToWheelsForce * m_fTurnMass)
									local point = multiply(getCarSide(car, RIGHT), m_vecMax_x)
									
									--print(inspect(force, point))
									--print(inspect(multiply(negative(right), rollOnToWheelsForce * m_fMass * fDir)))
									applyTurnForce(car, force, point)
									applyMoveForce(automobile, multiply(multiply(multiply(negative(right), rollOnToWheelsForce), m_fMass), fDir))
									-- лол тут не используется эта функция, нахуя я ее сюда перенес applyForce(car, vecForce, point, bUpdateTurnSpeed)
									--ApplyMoveForce(-right * rollOnToWheelsForce * m_fMass * fDir)
									--applyForceToCar(car, point.x, point.y, point.z, force.x, force.y, force.z)
									--renderDrawBox(500, 200, 500, 50, 0xFFD00000)
								end
							end
						end
					end
				end
			end
		end
	end
end

function getCarSide(car, side)   
    local baseVector = dirVecs[side]
    
    local qx, qy, qz, qw = getVehicleQuaternion(car)
    local rotatedVector = rotateVectorByQuaternion(baseVector, qx, qy, qz, qw)
    
    return rotatedVector
end


function getCarMass(car)
    if doesVehicleExist(car) then
		value = getCarModel(car)
		value = memory.getint32(value * 0x4 + 0xA9B0C8, false)
		value = memory.getint16(value + 0x4A, false)
		
		local mass = memory.getfloat(value * 0xE0 + 0xC2B9DC + 0x4, false)
		local turnMass = memory.getfloat(value * 0xE0 + 0xC2B9DC + 0xC, false)
		
		--print (mass, turnMass)
		return mass, turnMass
	end
end

-- Dot product function
function dot(v, u)
  return v.x * u.x + v.y * u.y + v.z * u.z
end

-- Cross product function
function cross(v, u)
  return {
    x = v.y * u.z - v.z * u.y,
    y = v.z * u.x - v.x * u.z,
    z = v.x * u.y - v.y * u.x
  }
end

function rotateVectorByQuaternion(vector, qx, qy, qz, qw)
    local ix = qw * vector.x + qy * vector.z - qz * vector.y
    local iy = qw * vector.y + qz * vector.x - qx * vector.z
    local iz = qw * vector.z + qx * vector.y - qy * vector.x
    local iw = -qx * vector.x - qy * vector.y - qz * vector.z

    return {
        x = ix * qw + iw * -qx + iy * -qz - iz * -qy,
        y = iy * qw + iw * -qy + iz * -qx - ix * -qz,
        z = iz * qw + iw * -qz + ix * -qy - iy * -qx
    }
end

function multiply(vector, scalar)
    return {
        x = vector.x * scalar,
        y = vector.y * scalar,
        z = vector.z * scalar
    }
end

function negative(vector)
    return {
        x = vector.x * -1,
        y = vector.y * -1,
        z = vector.z * -1
    }
end

function subtract(v1, v2)
    return {
        x = v1.x - v2.x,
        y = v1.y - v2.y,
        z = v1.z - v2.z
    }
end

function add(v1, v2)
    return {
        x = v1.x + v2.x,
        y = v1.y + v2.y,
        z = v1.z + v2.z
    }
end

function divide(vector, scalar)
    if scalar ~= 0 then
		return {
			x = vector.x / scalar,
			y = vector.y / scalar,
			z = vector.z / scalar
		}
	end
end


-- Define function for applying turn force
function applyTurnForce(car, force, point)
    if doesVehicleExist(car) then
		local carPointer = getCarPointer(car)
		local vehicle = samem.cast("CVehicle *", carPointer)
		if vehicle ~= samem.nullptr then
			if vehicle.nVehicleClass == 0 then -- на самом деле это не класс, а тип. VEHICLE_TYPE_AUTOMOBILE  = 0
				local automobile = samem.cast('CAutomobile *', vehicle)
				local qx, qy, qz, qw = getVehicleQuaternion(car)
				--local wheelsSuspensionCompression = automobile.wheelsDistancesToGround1
				--print(automobile.vLastCollisionPosn.x, automobile.vLastCollisionPosn.y, automobile.vLastCollisionPosn.z )
				--automobile.nPhysicalFlags.bSubmergedInWater = 1

				if not (automobile.nPhysicalFlags.bDisableTurnForce == 1) then

					local vecCentreOfMassMultiplied = {}
					if not (automobile.nPhysicalFlags.bInfiniteMass == 1) then

						vecCentreOfMassMultiplied = rotateVectorByQuaternion(automobile.vCentreOfMass, qx, qy, qz, qw) --getMatrix(physical):transformVector(physical.m_vecCentreOfMass)
					end

					if (automobile.nPhysicalFlags.bDisableMoveForce == 1) then

						point.z = 0.0
						force.z = 0.0
					end

					local vecDifference = subtract(point, vecCentreOfMassMultiplied)
					--print(automobile.vTurnSpeed.x, automobile.vTurnSpeed.y, automobile.vTurnSpeed.z)
					-- неправильный рассчет вроде как не тот порядок automobile.vTurnSpeed = divide(add(automobile.vTurnSpeed, cross(vecDifference, force)), automobile.fTurnMass)
					automobile.vTurnSpeed = add(automobile.vTurnSpeed, divide(cross(vecDifference, force), automobile.fTurnMass))
					--print(automobile.vTurnSpeed.x, automobile.vTurnSpeed.y, automobile.vTurnSpeed.z)
				end
			end
		end
	end
end

function applyMoveForce(automobile, force)
    --if automobile ~= samem.nullptr then
		local automobile = samem.cast('CAutomobile *', vehicle)
				
		if not (automobile.nPhysicalFlags.bInfiniteMass == 1) and not (automobile.nPhysicalFlags.bDisableMoveForce == 1) then
			if (automobile.nPhysicalFlags.bDisableZ == 1) then
				force.z = 0.0
			end
			automobile.vMoveSpeed = add(automobile.vMoveSpeed, divide(force, automobile.fMass))
		end	
	--end
end


когда выношу получение automobile в функцию  applyMoveForce из main то все норм становится