- 126
- 135
- Версия MoonLoader
- .026-beta
Не так давно я работал над избеганием объектов с помощью лучей и столкнулся с проблемой: лучи могут столкнуться с холмами или дорогами под наклоном. Я пробовал испустить еще один луч и отразить его от нормали, чтобы получить отраженный направляющий луч. Затем, я попытался изменить угол наклона лучей на угол наклона направляющего луча, который был отражен от нормали, но получилось уебищно.
Этот способ хуево работает, ищу тут варианты решения, а если вы филантроп от мира кодинга, то можете еще и готовый код написать.
Все еще не решено
Этот способ хуево работает, ищу тут варианты решения, а если вы филантроп от мира кодинга, то можете еще и готовый код написать.
Lua:
local VK_S = 0x53
local VK_A = 0x41
local VK_D = 0x44
local font = renderCreateFont("Arial", 8, 8)
local DrivingAssistant = {}
DrivingAssistant.__index = DrivingAssistant
function DrivingAssistant.new()
local self = setmetatable({}, DrivingAssistant)
self.drivingEnabled = false
self.lastTurnDirection = nil
self.userInputMultiplier = 5
return self
end
function DrivingAssistant:toggleDriving()
self.drivingEnabled = not self.drivingEnabled
local message = self.drivingEnabled and 'Ассистент двух колес включен.' or 'Ассистент двух колес выключен.'
sampAddChatMessage(message, -1)
end
function DrivingAssistant:processDriving()
if not isCharInAnyCar(PLAYER_PED) then
sampAddChatMessage('Вы должны сесть на байк.', -1)
return
end
local playerCoords, playerHeading = getPlayerCoordsAndHeading()
local radOffset, offsetZ = math.rad(-playerHeading), playerCoords[3]
local offsetX, offsetY = getOffsetCoords(playerCoords, radOffset)
local obstacleInfo, allLinesOccupied = self:detectObstacles(playerCoords, playerHeading, radOffset, offsetZ, offsetX, offsetY)
self:handleObstacles(obstacleInfo, allLinesOccupied)
end
function DrivingAssistant:detectObstacles(playerCoords, playerHeading, radOffset, offsetZ, offsetX, offsetY)
local obstacleInfo = {
detected = {left = false, right = false, front = false, center = false},
specific = {}
}
local pitch = getCarPitch(getCarCharIsUsing(PLAYER_PED))
local radPitch = math.rad(pitch)
local allLinesOccupied = true
for i = -4, 4 do
local radian = math.rad(-playerHeading + 2 * i)
local sinRadian, cosRadian = math.sin(radian), math.cos(radian)
local multiplier = self:getMultiplier(i)
local targetX, targetY, targetZ = self:getTargetCoords(offsetX, offsetY, offsetZ, sinRadian, cosRadian, radPitch, multiplier)
local obstacle = isObstacleInFront(offsetX, offsetY, offsetZ, targetX, targetY, targetZ)
if i ~= 0 then
allLinesOccupied = allLinesOccupied and obstacle
end
local color = obstacle and 0xFFFF0000 or 0xFFFFFFFF
renderLine3D(offsetX, offsetY, offsetZ, targetX, targetY, targetZ, 2, color)
self:processObstacleDetection(obstacleInfo, obstacle, i)
local textPosX, textPosY = getScreenCoordsFrom3D(targetX, targetY, targetZ)
if textPosX and textPosY then
renderFontDrawText(font, tostring(i), textPosX, textPosY, color)
end
end
return obstacleInfo, allLinesOccupied
end
function DrivingAssistant:getMultiplier(index)
local speedVector = { getCarSpeedVector(getCarCharIsUsing(PLAYER_PED), true) }
local speed = math.sqrt(speedVector[1]^2 + speedVector[2]^2 + speedVector[3]^2)
local speedFactor = 1 + speed / 10
if index == 0 then
return 0.5 * speedFactor
else
local baseMultiplier = (self.userInputMultiplier - 0.2 * math.abs(index)) * speedFactor
return baseMultiplier
end
end
function DrivingAssistant:getTargetCoords(offsetX, offsetY, offsetZ, sinRadian, cosRadian, radPitch, multiplier)
local targetX = offsetX + multiplier * sinRadian
local targetY = offsetY + multiplier * cosRadian
local targetZ = offsetZ + multiplier * math.sin(radPitch)
return targetX, targetY, targetZ
end
function DrivingAssistant:processObstacleDetection(obstacleInfo, obstacle, index)
if obstacle then
addOneOffSound(0.0, 0.0, 0.0, 1139)
printStringNow("DETECTED", 100)
obstacleInfo.detected.center = obstacleInfo.detected.center or index == 0
obstacleInfo.detected.right = obstacleInfo.detected.right or (index > 0)
obstacleInfo.detected.left = obstacleInfo.detected.left or (index < 0)
obstacleInfo.detected.front = obstacleInfo.detected.front or (index ~= 0)
obstacleInfo.specific[index] = true
end
end
function DrivingAssistant:handleObstacles(obstacleInfo, allLinesOccupied)
if obstacleInfo.detected.center then
lua_thread.create(function()
setVirtualKeyDown(VK_S, true)
wait(1000)
setVirtualKeyDown(VK_S, false)
end)
end
if allLinesOccupied then
if self.lastTurnDirection == 'right' then
lua_thread.create(function()
setVirtualKeyDown(VK_D, true)
wait(250)
setVirtualKeyDown(VK_D, false)
end)
elseif self.lastTurnDirection == 'left' then
lua_thread.create(function()
setVirtualKeyDown(VK_A, true)
wait(250)
setVirtualKeyDown(VK_A, false)
end)
else
print("Неизвестно")
end
elseif obstacleInfo.detected.front then
local leftCount = 0
local rightCount = 0
for i = -4, 4 do
if i ~= 0 and obstacleInfo.specific[i] then
if i < 0 then
leftCount = leftCount + 1
elseif i > 0 then
rightCount = rightCount + 1
end
end
end
if leftCount > rightCount then
self.lastTurnDirection = 'right'
lua_thread.create(function()
setVirtualKeyDown(VK_D, true)
wait(250)
setVirtualKeyDown(VK_D, false)
end)
elseif rightCount > leftCount then
self.lastTurnDirection = 'left'
lua_thread.create(function()
setVirtualKeyDown(VK_A, true)
wait(250)
setVirtualKeyDown(VK_A, false)
end)
end
end
end
function getPlayerCoordsAndHeading()
return { getCharCoordinates(PLAYER_PED) }, getCharHeading(PLAYER_PED)
end
function getOffsetCoords(playerCoords, radOffset)
assert(type(playerCoords[1]) == "number" and type(playerCoords[2]) == "number", "?")
local offsetX, offsetY
if isCharInAnyCar(PLAYER_PED) then
offsetX, offsetY = playerCoords[1] + 0.6 * math.sin(radOffset), playerCoords[2] + 0.6 * math.cos(radOffset)
else
offsetX, offsetY = playerCoords[1], playerCoords[2]
end
return offsetX, offsetY
end
function isObstacleInFront(x, y, z, targetX, targetY, targetZ)
return processLineOfSight(x, y, z, targetX, targetY, targetZ, true, true, true, true, true, false, false, false)
end
function getScreenCoordsFrom3D(x, y, z)
local result, screenX, screenY = convert3DCoordsToScreenEx(x, y, z)
if result then
return screenX, screenY
end
end
function renderLine3D(x1, y1, z1, x2, y2, z2, width, color)
local res1, screenX1, screenY1 = convert3DCoordsToScreenEx(x1, y1, z1)
local res2, screenX2, screenY2 = convert3DCoordsToScreenEx(x2, y2, z2)
if res1 and res2 and ({convert3DCoordsToScreenEx(x1, y1, z1)})[4] > 0 and isPointOnScreen(x2, y2, z2, 1.0) then
renderDrawLine(screenX1, screenY1, screenX2, screenY2, width, color)
end
end
function main()
local assistant = DrivingAssistant.new()
local VK_F5 = 0x74
local F5L = false
while not isSampAvailable() do wait(0) end
sampRegisterChatCommand('helpmedrive', function()
assistant:toggleDriving()
end)
sampRegisterChatCommand('setmultiplier', function(param)
local value = tonumber(param)
if value then
assistant.userInputMultiplier = value
sampAddChatMessage("Множитель дистанции установлен на: " .. value, -1)
else
sampAddChatMessage("Ошибка: Неверное значение множителя.", -1)
end
end)
while true do
wait(0)
local F5T = isKeyDown(VK_F5)
if F5T and not F5L then
assistant:toggleDriving()
end
F5L = F5T
if assistant.drivingEnabled then
local status, err = pcall(function() assistant:processDriving() end)
if not status then
print("ERROR: " .. err, -1)
end
end
end
end
Все еще не решено
Последнее редактирование: