Неактуально Заказ [SAMP, lua func] Функция поворота самолета или вертолота в лево или вправо (возможно использование quaternion)

yorenov

Участник
Автор темы
45
36
Так. Страшное слово «кватернион»!
Поехали к тз.
Необходимо реализовать функционал поворота самолета или вертолета влево и вправо (аналогично нажатию клавиш `Q` или `E` в игре). Решение должно быть реализовано без эмуляции нажатия клавиш или отправки клавиши в окно игры.

1. Функция должна работать в свернутом режиме.
2. Поворот должен выполняться только по горизонтали (не затрагивая угол наклона самолета/вертолета).

Попытки решения:
1. Базовая функция поворота через изменение угла объекта
lua:
function rotate(left)
    if isCharInAnyCar(playerPed) then
        local car = storeCarCharIsInNoSave(playerPed)
        local angle = getCarHeading(car)
        setCarHeading(car, angle + (left and 1 or -1) / 3.14)
    end
end
**Проблема:** Если самолет наклонен, он становится ровным после вызова функции.

---

2. Использование матрицы объекта для изменения угла поворота
lua:
local ffi = require("ffi")
local CPlaceable__GetMatrix = ffi.cast("uintptr_t(__thiscall*)(uintptr_t)", 0x411990)
local CMatrix__SetRotateZOnly = ffi.cast("int(__thiscall*)(uintptr_t, float)", 0x59B020)

function setEntityHeading(p_entity, heading)
    local p_matrix = CPlaceable__GetMatrix(p_entity)
    if p_matrix ~= ffi.NULL then
        CMatrix__SetRotateZOnly(p_matrix, heading)
    end
end

function changeEntityHeading(angleChange)
    local currentHeading = getCharHeading(PLAYER_PED)
    local newHeading = (currentHeading + angleChange) % 360
    if newHeading < 0 then
        newHeading = newHeading + 360
    end
    setEntityHeading(getCarPointer(storeCarCharIsInNoSave(playerPed)), math.rad(newHeading))
end

-- Пример использования
if fin_right == true then
    changeEntityHeading(-0.10)
end
if fin_left == true then
    changeEntityHeading(0.10)
end
**Проблема:** Аналогично первому решению, если самолет наклонен, он становится ровным.

---

3. Синхронизация транспорта


lua:
[SIZE=5]function samp.onSendVehicleSync(data)
    if left == true then
        data.keysData = data.keysData + 64
    elseif right == true then
        data.keysData = data.keysData + 256
    end
end[/SIZE]


**Проблема:** Только после я понял то что ничего не увижу, ибо синхра.

---

4. САМОЕ СТРАШНОЕ СЛОВО

lua:
function rotateVehicle(angle, direction)
    -- angle - градусы (не алкоголь)
    -- direction: 1 для поворота вправо, -1 для поворота влево

    local vehicle = getCarPointer(storeCarCharIsInNoSave(playerPed)) -- Получаем указатель на транспорт игрока

    if not vehicle or vehicle == 0 then
        sampAddChatMessage("Вы не находитесь в транспорте!", -1)
        return
    end
    local qW, qX, qY, qZ = getCharQuaternion(PLAYER_PED) 
    local rotationAngle = math.rad(angle * direction) -- Преобразуем угол в радианы
    local cosA = math.cos(rotationAngle / 2)
    local sinA = math.sin(rotationAngle / 2)
    local qx = 0
    local qy = 0
    local qz = sinA
    local qw = cosA
    local newQW = qW*qw - qX*qx - qY*qy - qZ*qz
    local newQX = qW*qx + qX*qw + qY*qz - qZ*qy
    local newQY = qW*qy - qX*qz + qY*qw + qZ*qx
    local newQZ = qW*qz + qX*qy - qY*qx + qZ*qw
    local length = math.sqrt(newQW*newQW + newQX*newQX + newQY*newQY + newQZ*newQZ)
    if length == 0 then
        sampAddChatMessage("Ошибка при вычислении кватерниона!", -1)
        return
    end
    newQW = newQW / length
    newQX = newQX / length
    newQY = newQY / length
    newQZ = newQZ / length

    -- Применяем новый кватернион к транспорту
    setCharQuaternion(PLAYER_PED, newQW, newQX, newQY, newQZ)
end
**Проблема:** Если getVehicleQuaternion - то все равно нулю. А если getCharQuaternion - то ниче не воркает . Кто там, а, @Vintik
---

5. Хз что и как но:
lua:
function rotateWithTiltPreservation(left)
    if isCharInAnyCar(playerPed) then
        local car = storeCarCharIsInNoSave(playerPed)
        local roll, pitch = getCarRoll(car), getCarPitch(car)
       
        local angle = getCarHeading(car)
        
        setCarHeading(car, angle + (left and 1 or -1) / 3.14)
        
        setCarRoll(car, roll)
        --setCarPitch(car, pitch), увы но такого не существует(((
    end
end
**Проблема:** такая же как и в попытке первого решения

Кто сделает функцию которая будет работать и не будет ресетать положение самолета - получит 1.5к
ОПЛАТА СБЕР ИЛИ ТИНЬКОФФ, КОРОЧЕ, РУ КАРТА
 
  • Клоун
  • Ха-ха
Реакции: Corenale и Vespan

ARMOR

Мне кажется, я всё проебал
Модератор
5,021
7,079
Попробуй это
 
  • Нравится
Реакции: whyega52