local Timer = require("level.timer")
local color = require("core.color")
local player, luaTable, spawnZone
function OnScriptLoaded(level, obj)
  game.SubObject.SetForgetOnCheckpoint(obj)
  game.SubObject.Sleep(obj)
  player = game.Player.FindPlayer()
  luaTable = {
    spawnZone = obj:GetLuaTableAttribute("SpawnZone"),
    spawnRate = obj:GetLuaTableAttribute("SpawnRate"),
    speed = 0,
    fadeStart = 50,
    fadeEnd = 75
  }
  local character = obj:GetLuaTableAttribute("Character")
  local underscore = string.find(character, "_")
  if underscore then
    luaTable.character = string.sub(character, 1, underscore - 1)
    luaTable.spawnMove = "MOV" .. string.sub(character, underscore, string.len(character))
  else
    luaTable.character = character
    luaTable.spawnMove = "MOV_Spawn"
  end
  game.SubObject.Sleep(obj)
end
function OnStart(level, obj)
  spawnZone = GameObjects[luaTable.spawnZone]
  StartSpawnTimer(0, level, obj)
  game.SubObject.Sleep(obj)
end
function StartSpawnTimer(time, level, obj)
  Timer.StartLevelTimer(time, TimerCallback, level, obj)
end
function TimerCallback(timer, level, obj)
  StartSpawnTimer(luaTable.spawnRate, level, obj)
  if ShouldSpawn() then
    Spawn(level, obj)
  end
end
function ShouldSpawn()
  local playerPosition = player.WorldPosition
  local closestPoint = spawnZone:GetClosestPointInZone(playerPosition)
  local offset = closestPoint - playerPosition
  local distanceXZ = math.sqrt(offset.x * offset.x + offset.z * offset.z)
  local distanceY = math.abs(offset.y)
  if 75 < distanceXZ then
    return false
  end
  if 5 < distanceY then
    return false
  end
  return true
end
local startOffset = engine.Vector.New(0, 0.5, 0)
local endOffset = engine.Vector.New(0, -0.5, 0)
local range = engine.Vector.New(0, 10, 0)
function GetSpawnPosition()
  local randomPoint = spawnZone:GetRandomPointInZone()
  local navmeshLocation = game.NavMesh.ClosestLocation(randomPoint, {Range = range})
  if not navmeshLocation then
    return
  end
  local navmeshPosition = navmeshLocation.Position
  local lineStart = navmeshPosition + startOffset
  local lineEnd = navmeshPosition + endOffset
  local hit = game.World.RaycastCollision(lineStart, lineEnd)
  if hit then
    return hit.Position
  end
end
function GetSpawnFacing()
  return engine.Vector.New(0, 0, -1):RotateXZ(math.random() * 360)
end
function GetSpawnInfo()
  local info = {}
  info.position = GetSpawnPosition()
  info.facing = GetSpawnFacing()
  return info
end
local spawnInfo
function Spawn(level, obj)
  spawnInfo = GetSpawnInfo()
  if not spawnInfo.position or not spawnInfo.facing then
    return
  end
  obj:SpawnWildlife({
    FleeDistance = 0,
    RespawnTime = 0,
    Speed = 0.3,
    Acceleration = 0.6,
    BankLimit = 0,
    StartIdle = false,
    RandomStartPos = false,
    Character = luaTable.character,
    Curve = "",
    SpawnMove = luaTable.spawnMove,
    Type = 2,
    Position = spawnInfo.position,
    Facing = spawnInfo.facing
  })
end
