GE Lua Documentation

Press F to search!

_setupRacer

Definition


-- @/lua/ge/extensions/gameplay/drag/general.lua:181

local function setupRacer(vehicleId, lane)
  if not dragData then return end

  if not vehicleId then
    log('E', logTag, 'No vehicle id')
    return
  end

  local vehicle = scenetree.findObjectById(vehicleId)
  if not vehicle or vehicle.className ~= "BeamNGVehicle" then
    log('E', logTag, 'Object with ID: ' .. vehicleId .. ' is not a vehicle')
    return
  end

  local oldData = gameplay_drag_saveSystem.getDialTimes()
  local timesKey = gameplay_drag_saveSystem.generateHashFromFile(vehicleId)

  local dial = 10
  if oldData[timesKey] then
    dial = oldData[timesKey].time_1_4 or 10
  else
    if core_vehicles.getVehicleDetails(vehicleId).configs["Drag Times"] then
      dial = core_vehicles.getVehicleDetails(vehicleId).configs["Drag Times"].time_1_4 or 10
    end
  end

  local racer = {
    vehId = vehicleId,
    phases = {},
    currentPhase = 1,
    isPlayable = true,
    lane = lane,
    isDesqualified = false,
    desqualifiedReason = "None",
    isFinished = false,
    wheelsOffsets = {},
    currentCorners = {},
    canBeTeleported = dragData.canBeTeleported,
    canBeReseted = dragData.canBeReseted,
    treeStarted = false,
    timersStarted = false,
    damage = 0,
    timers = {
      dial = {type = "dialTimer", value = dial, isSet = true},
      timer = {type = "timer", value = 0},
      reactionTime = {type = "distanceTimer", value = 0, distance = 0.178, isSet = false, label = "Reaction Time"},
      time_60 = {type = "distanceTimer", value = 0, distance = 18.288, isSet = false, label = "Distance: 60ft / 18.28m"},
      time_330 = {type = "distanceTimer", value = 0, distance = 100.584, isSet = false, label = "Distance: 330ft / 100.58m"},
      time_1_8 = {type = "distanceTimer", value = 0, distance = 201.168, isSet = false, label = "Distance: 1/8th mile / 201.16m"},
      time_1000 = {type = "distanceTimer", value = 0, distance = 304.8, isSet = false, label = "Distance: 1000ft / 304.8m"},
      time_1_4 = {type = "distanceTimer", value = 0, distance = 402.336, isSet = false, label = "Distance: 1/4th mile / 402.34m"},
      velAt_1_8 = {type = "velocity", value = 0, distance = 201.168, isSet = false, label = "Distance: 1/8th mile / 201.16m"},
      velAt_1_4 = {type = "velocity", value = 0, distance = 402.336, isSet = false, label = "Distance: 1/4th mile / 402.34m"},
      time_0_60 = {type = "timeToVelocity", value = 0, velocity = 26.8224, isSet = false},
      brakingG = {type = "brakingG", value = 0, isSet = false, deltaTime = 1},
    },
  }

  -- Initialize vector fields
  racer.vehPos = vec3()
  racer.vehDirectionVector = vec3()
  racer.vehDirectionVectorUp = vec3()
  racer.vehRot = quat()
  racer.vehVelocity = vec3()
  racer.prevSpeed = 0
  racer.vehSpeed = 0
  racer.vehObj = nil

  -- Calculate wheel offsets
  local wheelCount = vehicle:getWheelCount()-1
  local wheelsByFrontness = {}
  local maxFrontness = -math.huge

  if wheelCount > 0 then
    local vehiclePos = vehicle:getPosition()
    local forward = vehicle:getDirectionVector()
    local up = vehicle:getDirectionVectorUp()
    local vehicleRot = quatFromDir(forward, up)
    local x, y, z = vehicleRot * vec3(1,0,0), vehicleRot * vec3(0,1,0), vehicleRot * vec3(0,0,1)
    local center = vehicle:getSpawnWorldOOBB():getCenter()

    for i = 0, wheelCount do
      local axisNodes = vehicle:getWheelAxisNodes(i)
      local nodePos = vec3(vehicle:getNodePosition(axisNodes[1]))
      local wheelNodePos = vehiclePos + nodePos

      local frontness = forward:dot(wheelNodePos - center)

      for key, _ in pairs(wheelsByFrontness) do
        if math.abs(tonumber(key) - frontness) < 0.2 then
          frontness = key
        end
      end

      local pos = vec3(nodePos:dot(x), nodePos:dot(y), nodePos:dot(z))
      wheelsByFrontness[frontness] = wheelsByFrontness[frontness] or {}
      table.insert(wheelsByFrontness[frontness], pos)

      maxFrontness = math.max(frontness, maxFrontness)
    end
  end

  if not next(wheelsByFrontness) then
    log('E', logTag, 'Couldnt find front wheels for ' .. vehicleId .. '! will use OOBB as wheel offsets')

    local vehiclePos = vehicle:getPosition()
    local forward = vehicle:getDirectionVector()
    local up = vehicle:getDirectionVectorUp()
    local vehicleRot = quatFromDir(forward, up)
    local x, y, z = vehicleRot * vec3(1,0,0), vehicleRot * vec3(0,1,0), vehicleRot * vec3(0,0,1)
    local frontLeft, frontRight = vehicle:getSpawnWorldOOBB():getPoint(0) - vehiclePos, vehicle:getSpawnWorldOOBB():getPoint(3) - vehiclePos

    local posL = vec3(frontLeft:dot(x), frontLeft:dot(y), frontLeft:dot(z))
    local posR = vec3(frontRight:dot(x), frontRight:dot(y), frontRight:dot(z))
    maxFrontness = "oobb"
    wheelsByFrontness[maxFrontness] = {posL, posR}
  end

  racer.allWheelsOffsets = wheelsByFrontness
  racer.wheelsCenter = {}
  racer.beamState = {}
  racer.frontWheelId = maxFrontness

  for k, v in pairs(racer.allWheelsOffsets) do
    racer.wheelsCenter[k] = {pos = vec3(), wheelCountInv = 1 / #racer.allWheelsOffsets[k]}
    racer.beamState[k] = {preStage = false, stage = false}
  end

  -- Initialize phases
  for _, phase in ipairs(dragData.phases) do
    table.insert(racer.phases, {
      name = phase.name,
      started = false,
      completed = false,
      dependency = phase.dependency,
      timerOffset = 0,
      startedOffset = phase.startedOffset,
    })
  end

  local details = core_vehicles.getVehicleDetails(vehicleId)
  if details then
    racer.niceName = (details.model.Brand or "") .. " " .. (details.configs.Name or "Unknown")
  end

  local status, ret = xpcall(function() return type(deserialize(vehicle.partConfig)) end, nop)
  racer.stock = not ret
  racer.licenseText = core_vehicles.getVehicleLicenseText(vehicle)

  if debugModule.getDebugMenu() then
    debugModule.selectElement(vehicleId)
  end

  dragData.racers[vehicleId] = racer

  -- Initialize frameHistory for timers that need it (times extension might have loaded before racers existed)
  -- This ensures frameHistory exists even if times extension onExtensionLoaded ran before racers were created
  local addFrameHistoryDebug = {
    reactionTime = true,
  }
  for timerId, timer in pairs(racer.timers) do
    if timer.type ~= "dialTimer" and addFrameHistoryDebug[timerId] and not timer.frameHistory then
      timer.frameHistory = {}
    end
  end
end

Callers

@/lua/ge/extensions/gameplay/drag/dragBridge.lua
M.setupRacer = function(vehicleId, lane)
  return gameplay_drag_general._setupRacer(vehicleId, lane)
end
  for _, data in ipairs(vehicleIds) do
    gameplay_drag_general._setupRacer(data.id, data.lane)
    if not dragData.racers[data.id] then