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