-- REAbodyRoll.lua
-- Feature 6: Wank-/Schaukel-Simulation beim Kurvenfahren (Ultra C, aber mit Massenskalierung)

REAbodyRoll = {}
REAbodyRoll.version = "1.0.0"

REAbodyRoll.CONFIG = {
    baseRollGain   = 0.012,  -- Grundstärke des Rollens
    speedGain      = 0.002,  -- Einfluss der Geschwindigkeit auf das Ziel-Rollmoment
    damping        = 0.22,   -- Dämpfung (geringer = mehr Nachschwingen)
    maxRollAngle   = 0.25,   -- ~14° maximale Seitenneigung
    lightMass      = 6000,   -- unterhalb: stärkerer Effekt
    heavyMass      = 16000,  -- oberhalb: gedämpfter Effekt
}

local function clamp(v, a, b)
    if v < a then return a end
    if v > b then return b end
    return v
end

function REAbodyRoll:loadMap(name)
    print(string.format("REAbodyRoll v%s geladen (Wank/Schaukel Ultra, skaliert nach Fahrzeugmasse)", REAbodyRoll.version))
end

function REAbodyRoll:update(dt)
    if g_currentMission == nil or g_currentMission.vehicles == nil then
        return
    end

    local dtSec = dt / 1000

    for _, vehicle in pairs(g_currentMission.vehicles) do
        if vehicle ~= nil and vehicle.isAddedToPhysics and vehicle.spec_drivable ~= nil then
            REAbodyRoll:updateVehicle(vehicle, dtSec)
        end
    end
end

function REAbodyRoll:getMassFactor(vehicle)
    local cfg = REAbodyRoll.CONFIG
    local mass = 0
    if vehicle.getTotalMass ~= nil then
        mass = vehicle:getTotalMass()
    else
        mass = vehicle.mass or 8000
    end

    if mass <= cfg.lightMass then
        return 1.0      -- volle Härte für leichte Fahrzeuge
    elseif mass >= cfg.heavyMass then
        return 0.4      -- stark gedämpft für sehr schwere Maschinen
    else
        local t = (mass - cfg.lightMass) / (cfg.heavyMass - cfg.lightMass)
        return 1.0 - 0.6 * t
    end
end

function REAbodyRoll:updateVehicle(vehicle, dtSec)
    local drv = vehicle.spec_drivable
    if drv == nil then
        return
    end

    local speedKmh = math.abs((vehicle.lastSpeedReal or vehicle.lastSpeed or 0) * 3600)
    local massFactor = self:getMassFactor(vehicle)

    vehicle.REA_rollState = vehicle.REA_rollState or 0

    if speedKmh < 3 then
        vehicle.REA_rollState = vehicle.REA_rollState * (1 - REAbodyRoll.CONFIG.damping * dtSec * 12)
    else
        local steer = 0
        if drv.lastInputValues ~= nil and drv.lastInputValues.steering ~= nil then
            steer = drv.lastInputValues.steering
        elseif drv.axisSteer ~= nil then
            steer = drv.axisSteer
        end

        local targetRoll = steer * speedKmh * REAbodyRoll.CONFIG.baseRollGain * massFactor
        local delta = (targetRoll - vehicle.REA_rollState)
        vehicle.REA_rollState = vehicle.REA_rollState + delta * (dtSec * 4.5)
        vehicle.REA_rollState = vehicle.REA_rollState * (1.0 - REAbodyRoll.CONFIG.damping * dtSec * 8)
    end

    vehicle.REA_rollState = clamp(vehicle.REA_rollState,
        -REAbodyRoll.CONFIG.maxRollAngle,
         REAbodyRoll.CONFIG.maxRollAngle)

    local rx, ry, rz = getRotation(vehicle.rootNode)
    setRotation(vehicle.rootNode, rx, ry, vehicle.REA_rollState)
end

addModEventListener(REAbodyRoll)
