GE Lua Documentation

Press F to search!

finalizeSpawnPoint

Definition


-- @/lua/ge/extensions/gameplay/traffic/trafficUtils.lua:240

local function finalizeSpawnPoint(pos, dir, mapNode1, mapNode2, options) -- snaps a spawn point to a lane of the road, plus other options
  -- dir, mapNode1, mapNode2, and options are optional
  local mapNodes = map.getMap().nodes

  if not mapNode1 or not mapNode2 or not mapNodes[mapNode1] or not mapNodes[mapNode2] then
    local dist
    mapNode1, mapNode2, dist = map.findClosestRoad(pos)
    if not mapNode1 or dist > 30 then
      if M.debugMode then
        log('W', logTag, 'Failed to find nearby road for spawn point adjustment')
      end
      return pos, dir
    end
  end

  local newPos, newDir = vec3(), vec3()
  options = options or {}

  p1:set(mapNodes[mapNode1].pos)
  p2:set(mapNodes[mapNode2].pos)

  if not dir or options.legalDirection then
    if not dir then dir = vec3() end
    dir:setSub2(p2, p1)
    dir:normalize()
    options.legalDirection = true -- defaults to true if no direction is provided
  end

  local xnorm = clamp(pos:xnormOnLine(p1, p2), 0, 1)
  local radius = lerp(mapNodes[mapNode1].radius, mapNodes[mapNode2].radius, xnorm)
  local normal = mapNodes[mapNode1].normal:slerp(mapNodes[mapNode2].normal, xnorm):normalized()
  local link = mapNodes[mapNode1].links[mapNode2] or mapNodes[mapNode2].links[mapNode1]

  local legalSide = map.getRoadRules().rightHandDrive and -1 or 1
  local roadWidth = radius * 2
  local laneWidth = roadWidth >= 6.1 and 3.05 or 2.2 -- gets modified for very narrow roads

  options.minLane = math.min(0, options.minLane or -10)
  options.maxLane = math.max(0, options.maxLane or 10)
  options.roadDir = sign2(options.roadDir or math.random() * 2 - 1) -- negative = away from you, positive = towards you

  local laneChoice, roadDir, offsetVec

  local laneCount = math.max(1, math.floor(roadWidth / laneWidth)) -- estimated number of lanes (this will change when real lanes exist)
  if not link.oneWay and laneCount % 2 ~= 0 then -- two way roads currently have an even amount of expected lanes
    laneCount = math.max(1, laneCount - 1)
  end

  if options.legalDirection then
    if link.oneWay then
      roadDir = link.inNode == mapNode1 and 1 or -1 -- spawn facing the correct way
    else
      roadDir = laneCount == 1 and 1 or options.roadDir
    end
  else
    roadDir = options.roadDir
  end

  if link.oneWay then
    laneChoice = math.random(laneCount)
  else
    if laneCount == 1 then
      laneChoice = 1
    else
      if options.legalDirection then
        local minLane = roadDir == -1 and 1 or math.max(1, math.floor(laneCount * 0.5) + 1)
        local maxLane = roadDir == -1 and math.max(1, math.floor(laneCount * 0.5)) or laneCount
        laneChoice = math.random(math.max(minLane, options.minLane), math.min(maxLane, options.maxLane))
      else
        laneChoice = math.random(math.max(1, options.minLane), math.min(laneCount, options.maxLane))
      end
    end
  end

  if options.roadLateralXnorm then -- overrides lanes by directly adjusting the position along the lateral xnorm (from -1 to 1)
    offsetVec = dir:cross(normal) * radius * options.roadLateralXnorm
  else
    local offset = (laneChoice - (laneCount * 0.5 + 0.5)) * (roadWidth / laneCount) * legalSide
    offsetVec = dir:cross(normal) * offset
  end

  newPos:setAdd2(pos, offsetVec)
  newDir:setScaled2(dir, roadDir)

  return newPos, newDir
end

Callers

@/lua/ge/extensions/gameplay/traffic.lua

    local pos, dir = gameplay_traffic_trafficUtils.finalizeSpawnPoint(spawnData.pos, spawnData.dir, spawnData.n1, spawnData.n2, placeData)
    local normal = map.surfaceNormal(pos, 1)
    local spawnData = gameplay_traffic_trafficUtils.findSafeSpawnPoint(nil, nil, minDist, maxDist, targetDist)
    local newPos, newRot = gameplay_traffic_trafficUtils.finalizeSpawnPoint(spawnData.pos, spawnData.dir, spawnData.n1, spawnData.n2, {legalDirection = true})
    newRot = quatFromDir(newRot, map.surfaceNormal(newPos))