GE Lua Documentation

Press F to search!

findSpawnPointRadial

Definition


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

local function findSpawnPointRadial(startPos, startDir, minDist, maxDist, targetDist, options) -- returns a spawn point, from random radials away from the origin
  -- all args are optional, will use camera transform by default
  options = options or {}
  startPos, startDir, minDist, maxDist, targetDist = getDefaultValues(startPos, startDir, minDist, maxDist, targetDist)

  local spawnData = {pos = vec3(), dir = vec3()}
  local valid = false
  local mapNodes = map.getMap().nodes
  local currDist = minDist

  options.gap = options.gap or 50
  options.usePrivateRoads = options.usePrivateRoads and true or false
  options.minDrivability = options.minDrivability or M.defaults.drivability
  options.minRadius = options.minRadius or M.defaults.halfWidth

  if M.debugMode then
    log('I', logTag, string.format('Spawn search params: minDist = %d, maxDist = %d, targetDist = %d', minDist, maxDist, targetDist))
  end

  --[[
  ---- RADIAL SEARCH ----
  Points from a radius will be checked until a valid road to spawn on has been found.
  ]]--

  repeat
    local angleRad = math.rad(math.random() * 360)
    spawnData.dir:set(math.sin(angleRad), math.cos(angleRad), 0)
    spawnData.dir:setScaled(currDist)
    spawnData.pos:setAdd2(startPos, spawnData.dir)

    local n1, n2 = map.findClosestRoad(spawnData.pos)
    if checkRoad(n1, n2, options) then
      p1:set(mapNodes[n1].pos)
      p2:set(mapNodes[n2].pos)
      spawnData.pos:set(linePointFromXnorm(p1, p2, clamp(spawnData.pos:xnormOnLine(p1, p2), 0, 1)))

      if currDist >= targetDist or checkRayCast(spawnData.pos, startPos) then
        tempDir:setSub2(p2, p1)
        tempDir:normalize()
        if spawnData.dir:dot(tempDir) < 0 then
          tempDir:setScaled(-1)
        end
        spawnData.dir:set(tempDir)

        if checkSpawnPoint(spawnData.pos, nil, minDist) then
          spawnData.n1, spawnData.n2 = n1, n2
          valid = true

          if M.debugMode then
            log('I', logTag, string.format('Spawn point found at distance: %d', math.floor(spawnData.pos:distance(startPos))))
          end
        end
      end
    end

    currDist = currDist + options.gap
  until (valid or currDist > maxDist)

  if not valid then
    spawnData.dir:normalize()
    if M.debugMode then
      log('W', logTag, 'Failed to validate spawn point (radial method)')
    end
  end

  return spawnData, valid
end

Callers

@/lua/ge/extensions/gameplay/traffic/trafficUtils.lua
    -- some of this feels hacky; will look into this another time
    spawnData, valid = findSpawnPointRadial(startPos, startDir, 200, 1000, 0, options) -- small radial search
    if not valid then
      options.minDrivability = 0.5
      spawnData, valid = findSpawnPointRadial(startPos, startDir, 200, 2000, 0, options) -- large radial search, more permissive options
      if not valid then
      if not valid then
        spawnData, valid = findSpawnPointRadial(startPos, startDir, 10000, 10000, 0, options) -- temporary solution?
        spawnData.pos.z = 1 -- above ground plane