local statemachine = require("ai.statemachine")
local tablex = require("core.tablex")
local picklelib = require("core.pickle")
local DL = require("design.DesignerLibrary")
local timer = require("creature.timer")
local globalLuaHooks = require("design.GlobalLuaHooks")
globalLuaHooks.InstallHooks()
local traverselink = require("creature.traverselink")
traverselink.InstallHooks()
Brain_Core = require("behavior.corebrain")
constants = {}
global = {}
local powerLevel = "1"
local pLevelInt = 0
local variant, weaponObj
global.turretModeBreak = false
global.turretModeBreakRange = 0
local goPlayerCreature
local numSummoned = 0
local maxSummon = 0
function detectAggroStateFromSpawnMove(ai)
  local spawnContext = ai:GetContext()
  if DL.CheckCreatureContext(spawnContext, "INCOMBAT") then
    global.aggroState = "INCOMBAT"
  elseif DL.CheckCreatureContext(spawnContext, "UNAWARE") then
    global.aggroState = "UNAWARE"
  elseif DL.CheckCreatureContext(spawnContext, "NONHOSTILE") then
    global.aggroState = "NONHOSTILE"
  elseif DL.CheckCreatureContext(spawnContext, "PASSIVE") then
    global.aggroState = "PASSIVE"
  end
end
function OnWeaponApproaching(gameObject, attacker, weapon, side)
  local ai = gameObject:GetCreature():GetAI()
  if (ai:IsInNavigationMove() or ai:HasMarker("BlockEnterAvailable")) and ai:IsInAir() == false and game.Level.GetVariable("DEBUG_CBT_Disable_Defense") == false then
    ai:TriggerMoveEvent("kLEDarkOneWeaponApproach")
  end
end
function Brain_Core:OnUpdateCombat(ai, global, constants, dTreeParams)
  if ai:PickupIsAcquired("DarkOne_HeavySpear") then
    constants.fightKnowledgeInputs.CurrentZoneSet = "HeavyAttacker"
  elseif ai:PickupIsAcquired("DarkOne_Summoner") then
    constants.fightKnowledgeInputs.CurrentZoneSet = "Summoner"
  elseif ai:PickupIsAcquired("DarkOne_HiveFighter") then
    constants.fightKnowledgeInputs.CurrentZoneSet = "HiveFight"
  end
  if ai:PickupIsActive("DarkOne_PerchTurret") then
    global.DTree = "DTR_DARKONE00_PERCH"
  elseif ai:PickupIsActive("DarkOne_HiveFighter") then
    global.DTree = "DTR_DARKONE00_HIVE_FIGHTER"
  end
end
function Brain_Core:OnHitReaction(event, ai, global, constants)
end
function Brain_Core:OnUpdateMotion(ai, global, constants, actuatorData)
  if ai:PickupIsActive("DarkOne_PerchTurret") then
    actuatorData.Destination = ai:GetWorldPosition()
  end
end
function LuaHookDecision_CanFollowupShot(ai, data)
  local retVal = true
  if ai:PickupIsAcquired("DarkOne00_Elite") == false then
    local enemies = DL.FindLivingEnemies(goPlayerCreature, 40)
    for i = #enemies, 1, -1 do
      if enemies[i]:PickupIsAcquired("DarkOne_FollowupShot_Timer") then
        retVal = false
      end
    end
    if retVal == true then
      ai:PickupAcquire("DarkOne_FollowupShot_Timer")
    end
  end
  return retVal
end
function LuaHook_HiveFight_AxeLift(ai)
  if ai:HasMarker("HiveFight_AxeLift") == false then
    ai:AddMarker("HiveFight_AxeLift")
  end
end
function LuaHook_HiveFight_WeaponClash(ai)
  if ai:HasMarker("HiveFight_WeaponClash") == false then
    ai:AddMarker("HiveFight_WeaponClash")
  end
end
function GetSummonedAllyConfigString(pLevelInt)
  local charConfig = "Light01"
  local random = math.random(1, 2)
  if pLevelInt <= 2 then
    if random == 1 then
      charConfig = "Light01"
    else
      charConfig = "Light02"
    end
  elseif 3 <= pLevelInt and pLevelInt <= 4 then
    if random == 1 then
      charConfig = "Light01_hard"
    else
      charConfig = "Light02_hard"
    end
  elseif 5 <= pLevelInt then
    if random == 1 then
      charConfig = "Light01_veryhard"
    else
      charConfig = "Light02_veryhard"
    end
  end
  return charConfig
end
function LuaHook_SummonAllies(ai, data)
  local spawnJointIndex = ai:GetJointIndex("zerojoint")
  local navPos, navPos2
  if GetNumDarkOnesToSummon(ai) == 2 or maxSummon == 0 then
    local spawnPos = ai:GetWorldJointPosition(spawnJointIndex) + ai:GetWorldLeft() * 1 + ai:GetWorldForward() * 2
    local spawnPos2 = ai:GetWorldJointPosition(spawnJointIndex) - ai:GetWorldLeft() * 1 + ai:GetWorldForward() * 2
    navPos = game.NavMesh.ClosestPoint(spawnPos)
    navPos2 = game.NavMesh.ClosestPoint(spawnPos2)
  else
    local spawnPos = ai:GetWorldJointPosition(spawnJointIndex) + ai:GetWorldForward() * 2.5
    navPos = game.NavMesh.ClosestPoint(spawnPos)
  end
  if navPos ~= nil then
    local charConfig = GetSummonedAllyConfigString(pLevelInt)
    local summonedDarkOne = game.AI.Spawn(ai.Level, navPos, ai:GetWorldForward(), "CRT_DarkOne00", "BRA_SpawnSummoned", {PowerLevel = powerLevel, Variant = "QuickSpear"}, charConfig)
    numSummoned = numSummoned + 1
    game.Encounters.AddSpawnToEncounter(ai, summonedDarkOne)
  end
  if navPos2 ~= nil then
    local charConfig = GetSummonedAllyConfigString(pLevelInt)
    local summonedDarkOne2 = game.AI.Spawn(ai.Level, navPos2, ai:GetWorldForward(), "CRT_DarkOne00", "BRA_SpawnSummoned", {PowerLevel = powerLevel, Variant = "QuickSpear"}, charConfig)
    numSummoned = numSummoned + 1
    game.Encounters.AddSpawnToEncounter(ai, summonedDarkOne2)
  end
end
function LuaHookDecision_DarkOneBlockExitCheck(ai, data)
  local retVal = true
  local player = game.Player.FindPlayer()
  local enemies = DL.FindLivingEnemies(player, 40)
  for i = #enemies, 1, -1 do
    if enemies[i]:GetTargetCreature() == player and (enemies[i]:IsPlayingMove("MOV_AttTripleShot") == true or enemies[i]:IsPlayingMove("MOV_AttTripleShot") == true or enemies[i]:IsPlayingMove("MOV_AttTripleShot") == true) then
      retVal = false
    end
  end
  return retVal
end
function GetNumEnemiesRating()
  local numEnemies = 0
  local numDarkOnes = 0
  local player = game.Player.FindPlayer()
  local enemies = DL.FindLivingEnemies(player, 80)
  for i = #enemies, 1, -1 do
    numEnemies = numEnemies + 1
    if enemies[i]:GetName() == "darkone00" then
      numDarkOnes = numDarkOnes + 1
    end
  end
  return numDarkOnes + numEnemies
end
function GetNumDarkOnesToSummon(ai)
  local numDarkOnesToSummon = 0
  local numDarkOnes = 0
  local player = game.Player.FindPlayer()
  local enemies = DL.FindLivingEnemies(player, 200)
  for i = 1, #enemies do
    if enemies[i]:GetName() == "darkone00" then
      numDarkOnes = numDarkOnes + 1
    end
  end
  if numDarkOnes + 2 <= maxSummon then
    numDarkOnesToSummon = 2
  else
    numDarkOnesToSummon = 1
  end
  return numDarkOnesToSummon
end
function LuaHookDecision_SummonSpeedCheck(ai, data)
  local retVal = data:FindOutcomeBranchesEntry("Slow")
  local slownessRating = GetNumEnemiesRating()
  if slownessRating <= 6 then
    retVal = data:FindOutcomeBranchesEntry("Fast")
  end
  return retVal
end
function LuaHookDecision_DarkOneSummonCheck(ai, data)
  local retVal = true
  local numDarkOnes = 0
  local numEnemies = 0
  local player = game.Player.FindPlayer()
  local enemies = DL.FindLivingEnemies(player, 200)
  local darkOnePool = game.AI.PoolCount(ai.Level, "CRT_DarkOne00")
  for i = #enemies, 1, -1 do
    if enemies[i]:GetName() == "darkone00" then
      numDarkOnes = numDarkOnes + 1
      if enemies[i]:MeterGetValue("AllowSummonHack") < 100 then
        retVal = false
      end
    end
  end
  if darkOnePool == 0 then
    retVal = false
  end
  if 0 < maxSummon and numDarkOnes >= maxSummon then
    retVal = false
  end
  return retVal
end
function LuaHookDecision_DarkOneAttackCheck(ai, data)
  local retVal = true
  local enemies = DL.FindLivingEnemies(goPlayerCreature, 100)
  for i = #enemies, 1, -1 do
    if enemies[i]:GetName() == "darkone00" and (enemies[i]:IsPlayingMove("MOV_AttSpearRunStart") == true or enemies[i]:IsPlayingMove("MOV_AttSpearRun") == true or enemies[i]:IsPlayingMove("MOV_AttSpearRunLoop") == true or enemies[i]:IsPlayingMove("MOV_AttSpearRunExit") == true or enemies[i]:IsPlayingMove("MOV_AttSpearRunStart2") == true or enemies[i]:IsPlayingMove("MOV_AttSpearRun2") == true or enemies[i]:IsPlayingMove("MOV_AttSpearRunLoop2") == true or enemies[i]:IsPlayingMove("MOV_AttSpearRunExit2") == true or enemies[i]:IsPlayingMove("MOV_AttSpearRunExitHeavy") == true or enemies[i]:IsPlayingMove("MOV_AttSpearRunExitHeavy_FallLoopR") == true or enemies[i]:IsPlayingMove("MOV_AttSpearRunExitHeavy_LandR") == true or enemies[i]:IsPlayingMove("MOV_AttSpearRunExitHeavy_FallLoopL") == true or enemies[i]:IsPlayingMove("MOV_AttSpearRunExitHeavy_LandL") == true or enemies[i]:IsPlayingMove("MOV_AttSpearRunExitHeavy2") == true or enemies[i]:IsPlayingMove("MOV_BlockRecoil") == true or enemies[i]:IsPlayingMove("MOV_BlockRecoil02") == true) then
      retVal = false
    end
  end
  return retVal
end
function TriggerLuaEvent(ai, luaevent)
  Brain_Core:SetTarget(game.Player.FindPlayer(), global, constants)
  ai:RequestHighPriorityUpdate()
  timer.StartCreatureTimer(0.05, function()
    if ai:HasMarker("AllowFollowupAttack") then
      Brain_Core:SetTarget(game.Player.FindPlayer(), global, constants)
      ai:RequestHighPriorityUpdate()
      ai:TriggerMoveEvent(luaevent)
    end
  end)
end
function Shared_FollowupAttack(ai, data, luaevent, maxrange, allowNormal, allowHeavy)
  local retVal = false
  local player = game.Player.FindPlayer()
  local enemies = DL.GetAllEnemiesOnScreen(true)
  local maxDistance = maxrange
  local closestEnemy
  for i = #enemies, 1, -1 do
    if enemies[i] ~= ai and enemies[i]:GetName() == "darkone00" and enemies[i]:PickupIsAcquired("TurretMode") == false and enemies[i]:HasMarker("AllowFollowupAttack") and enemies[i]:GetTargetCreature() == player and ai:GetTargetCreature() == player and (allowNormal and enemies[i]:PickupIsAcquired("DarkOne_QuickSpear") or allowHeavy and enemies[i]:PickupIsAcquired("DarkOne_HeavySpear")) then
      local dist = game.AIUtil.Distance(enemies[i], ai)
      if maxDistance > dist then
        closestEnemy = enemies[i]
        maxDistance = dist
        break
      end
    end
  end
  if closestEnemy ~= nil then
    closestEnemy:CallScript("TriggerLuaEvent", luaevent)
    retVal = true
  end
  return retVal
end
function IsBlockValid(ai)
  if ai:IsPlayingMove("MOV_DefBlockEnter") == false and ai:IsPlayingMove("MOV_DefBlockIdle") == false and ai:HasMarker("Block") == false then
    return true
  end
  return false
end
function LuaHook_DarkOneDelayedBlock(ai, data)
  if IsBlockValid(ai) == true and ai:IsPlayingMove("MOV_DefBlockEnterDelayed") == false then
    timer.StartCreatureTimer(math.random() * 1, function()
      if IsBlockValid(ai) == true then
        ai:TriggerMoveEvent("LE_DelayedBlockExecute")
      end
    end)
  end
end
followupAttackCount = 5
function LuaHook_FollowupAttack(ai, data)
  if not goPlayerCreature:PickupIsAcquired("DarkOne_FollowupAttack_Timer") then
    goPlayerCreature:PickupAcquire("DarkOne_FollowupAttack_Timer")
    goPlayerCreature:PickupSetStage("DarkOne_FollowupAttack_Timer", 0)
  else
    goPlayerCreature:PickupSetStage("DarkOne_FollowupAttack_Timer", 0)
  end
  if not Shared_FollowupAttack(ai, data, "LE_FollowupAttack", 15, true, false) then
    Shared_FollowupAttack(ai, data, "LE_FollowupAttack", 20, false, true)
  end
end
function LuaHook_FollowupAttack2(ai, data)
  local finalAttack = true
  if goPlayerCreature:PickupIsAcquired("DarkOne_FollowupAttack_Timer") then
    local currentAttackCount = goPlayerCreature:PickupGetStage("DarkOne_FollowupAttack_Timer")
    currentAttackCount = currentAttackCount + 1
    if currentAttackCount < followupAttackCount then
      goPlayerCreature:PickupIncrementStage("DarkOne_FollowupAttack_Timer")
      finalAttack = false
    end
  end
  if finalAttack == true then
    if not Shared_FollowupAttack(ai, data, "LE_FollowupAttack2", 15, true, false) then
      Shared_FollowupAttack(ai, data, "LE_FollowupAttack2", 20, false, true)
    end
  elseif not Shared_FollowupAttack(ai, data, "LE_FollowupAttack", 15, true, false) then
    Shared_FollowupAttack(ai, data, "LE_FollowupAttack", 20, false, true)
  end
end
function LuaHook_FollowupAttackHeavyFinale(ai, data)
  if Shared_FollowupAttack(ai, data, "LE_FollowupAttack2", 15, false, true) then
    ai:TriggerMoveEvent("LE_Evade")
  end
end
function LuaHook_FollowupAttackTripleShot(ai, data)
  if not Shared_FollowupAttack(ai, data, "LE_FollowupAttack", 60, true, false) then
    Shared_FollowupAttack(ai, data, "LE_FollowupAttack", 60, false, true)
  end
end
function LuaHook_ForceTargetKratos(ai, data)
  Brain_Core:SetTarget(game.Player.FindPlayer(), global, constants)
  ai:RequestHighPriorityUpdate()
end
function LuaHook_RandomizeWeapon(ai)
  local randomWeapon = math.random(1, 2)
  if randomWeapon == 1 then
    ai:PickupAcquire("DarkOne_NoSpear")
  else
    ai:PickupAcquire("DarkOne_QuickSpear")
  end
end
function LuaHook_GetProjectileTarget(ai)
  local targetLocationOffset = engine.Vector.New(0, 1, 0)
  global.projectileTarget = global.target:GetWorldPosition() + targetLocationOffset
end
local targetLocation
local targetReverseDirection = false
function DarkOneShot(ai, forwardOffset, leftOffset, resetTarget, speedLimit)
  local targetForward = global.target:GetWorldForward()
  local targetLeft = global.target:GetWorldLeft()
  if targetReverseDirection then
    leftOffset = leftOffset * -1
  end
  if resetTarget then
    local kratosVelocity = global.target:GetVelocity()
    local angleFwd = DL.GetAngleBetweenVector(targetForward, kratosVelocity)
    print(angleFwd)
    if kratosVelocity:Length() > 0.5 and -135 <= angleFwd and angleFwd <= 135 then
      kratosVelocity = kratosVelocity:Normalized() * speedLimit
    else
      kratosVelocity = engine.Vector.New(math.random(), 0, math.random()):Normalized() * speedLimit
    end
    targetLocation = global.target:GetWorldPosition() + kratosVelocity
  end
  local arrowData = {}
  arrowData.Tweak = "ARR_TRIPLESHOT_BOMB"
  arrowData.Creator = ai
  arrowData.CreatorEmitJoint = "JOMeleeWeapon1"
  arrowData.TargetLocation = targetLocation
  arrowData.EmitOffset = engine.Vector.New(0, 0, -1.1)
  arrowData.TargetLocation = targetLocation + targetLeft * leftOffset + targetForward * forwardOffset
  game.Combat.EmitArrow(arrowData)
end
function LuaHook_DarkOneTestShotReverse(ai)
  targetReverseDirection = not targetReverseDirection
end
function LuaHook_DarkOneTestShot(ai)
  DarkOneShot(ai, 0, 0, true, 4.5)
end
function LuaHook_DarkOneTestShot2(ai)
  DarkOneShot(ai, 0, 0, true, 0)
end
function LuaHook_DarkOneTestShot3(ai)
  DarkOneShot(ai, 0, 0, true, 4)
  DarkOneShot(ai, 0, 0, true, 0)
end
function LuaHook_DarkOneTestShot4(ai)
  DarkOneShot(ai, 0, 2, true, 0)
end
function LuaHook_DarkOneTestShot5(ai)
  DarkOneShot(ai, 0, 0, true, 0)
end
function LuaHook_AttTripleShot(ai)
  local targetLocationOffset = engine.Vector.New(0, 1.25, 0)
  local targetLocation = global.target:GetWorldPosition() + targetLocationOffset
  if global.projectileTarget ~= nil then
    targetLocation = global.projectileTarget
  end
  local arrowData = {}
  arrowData.Tweak = "ARR_TRIPLESHOT_BURST"
  arrowData.Creator = ai
  arrowData.CreatorEmitJoint = "JOMeleeWeapon1"
  arrowData.TargetLocation = targetLocation
  arrowData.EmitOffset = engine.Vector.New(0, 0, -1.1)
  game.Combat.EmitArrow(arrowData)
end
function LuaHook_AttStickyMine_Left(ai)
  if global.target == nil then
    global.target = goPlayerCreature
  end
  local targetPosition = global.target:GetWorldPosition()
  local targetLocation = global.target:GetWorldPosition()
  local targetForward = global.target:GetWorldForward()
  local targetLeft = global.target:GetWorldLeft()
  local distanceFrontOfTarget = 1.25
  local distanceLeftOfTarget = 1.5
  local velocityMultiplier = 1.5
  local kratosVelocity = global.target:GetVelocity()
  kratosVelocity = kratosVelocity * velocityMultiplier
  local angleFwd = DL.GetAngleBetweenVector(targetForward, kratosVelocity)
  local angleLeft = DL.GetAngleBetweenVector(targetLeft, kratosVelocity)
  if kratosVelocity:Length() > 0.5 then
    kratosVelocity = kratosVelocity:Normalized() * velocityMultiplier
    if -45 <= angleFwd and angleFwd <= 45 then
      targetForward = targetForward * distanceFrontOfTarget + kratosVelocity
    else
      targetForward = targetForward * distanceFrontOfTarget
    end
    if -45 <= angleLeft and angleLeft <= 45 then
      targetLeft = targetLeft * distanceLeftOfTarget + kratosVelocity
    else
      targetLeft = targetLeft * distanceLeftOfTarget
    end
  end
  targetLocation = targetPosition + targetForward + targetLeft
  local arrowData = {}
  engine.DrawFillSphere(targetPosition, 0.25, 65280, 3)
  engine.DrawFillSphere(targetLocation, 0.25, 16711680, 3)
  arrowData.Tweak = "ARR_TRIPLESHOT_BOMB"
  arrowData.Creator = ai
  arrowData.CreatorEmitJoint = "JOMeleeWeapon1"
  arrowData.TargetLocation = targetLocation
  arrowData.EmitOffset = engine.Vector.New(0, 0, -1.1)
  game.Combat.EmitArrow(arrowData)
end
function LuaHook_AttStickyMine_Center(ai)
  if global.target == nil then
    global.target = goPlayerCreature
  end
  local targetPosition = global.target:GetWorldPosition()
  local targetLocation = global.target:GetWorldPosition()
  local targetForward = global.target:GetWorldForward()
  local targetLeft = global.target:GetWorldLeft()
  local distanceFrontOfTarget = 1.5
  local distanceLeftOfTarget = 0
  local velocityMultiplier = 2.5
  local kratosVelocity = global.target:GetVelocity()
  kratosVelocity = kratosVelocity * velocityMultiplier
  local angleFwd = DL.GetAngleBetweenVector(targetForward, kratosVelocity)
  local angleLeft = DL.GetAngleBetweenVector(targetLeft, kratosVelocity)
  if kratosVelocity:Length() > 0.5 then
    kratosVelocity = kratosVelocity:Normalized() * velocityMultiplier
    if -45 <= angleFwd and angleFwd <= 45 then
      targetForward = targetForward * distanceFrontOfTarget + kratosVelocity
    else
      targetForward = targetForward * distanceFrontOfTarget
    end
    if -45 <= angleLeft and angleLeft <= 45 then
      targetLeft = targetLeft * distanceLeftOfTarget + kratosVelocity
    elseif angleLeft <= -135 or 135 <= angleLeft then
      targetLeft = targetLeft * distanceLeftOfTarget + kratosVelocity
    else
      targetLeft = targetLeft * distanceLeftOfTarget
    end
  else
    targetForward = targetForward * distanceFrontOfTarget
    targetLeft = targetLeft * distanceLeftOfTarget
  end
  targetLocation = targetPosition + targetForward + targetLeft
  local arrowData = {}
  engine.DrawFillSphere(targetPosition, 0.25, 65280, 3)
  engine.DrawFillSphere(targetLocation, 0.25, 16711680, 3)
  arrowData.Tweak = "ARR_TRIPLESHOT_BOMB"
  arrowData.Creator = ai
  arrowData.CreatorEmitJoint = "JOMeleeWeapon1"
  arrowData.TargetLocation = targetLocation
  arrowData.EmitOffset = engine.Vector.New(0, 0, -1.1)
  game.Combat.EmitArrow(arrowData)
end
function LuaHook_AttStickyMineSingle_Center(ai)
  if global.target == nil then
    global.target = goPlayerCreature
  end
  local targetPosition = global.target:GetWorldPosition()
  local targetLocation = global.target:GetWorldPosition()
  local targetForward = global.target:GetWorldForward()
  local targetLeft = global.target:GetWorldLeft()
  local distanceFrontOfTarget = 1.5
  local distanceLeftOfTarget = 0
  local velocityMultiplier = 2.5
  local kratosVelocity = global.target:GetVelocity()
  kratosVelocity = kratosVelocity * velocityMultiplier
  local angleFwd = DL.GetAngleBetweenVector(targetForward, kratosVelocity)
  local angleLeft = DL.GetAngleBetweenVector(targetLeft, kratosVelocity)
  if kratosVelocity:Length() > 0.5 then
    kratosVelocity = kratosVelocity:Normalized() * velocityMultiplier
    if -45 <= angleFwd and angleFwd <= 45 then
      targetForward = targetForward * distanceFrontOfTarget + kratosVelocity
    else
      targetForward = targetForward * distanceFrontOfTarget
    end
    if -45 <= angleLeft and angleLeft <= 45 then
      targetLeft = targetLeft * distanceLeftOfTarget + kratosVelocity
    elseif angleLeft <= -135 or 135 <= angleLeft then
      targetLeft = targetLeft * distanceLeftOfTarget + kratosVelocity
    else
      targetLeft = targetLeft * distanceLeftOfTarget
    end
  else
    targetForward = targetForward * distanceFrontOfTarget
    targetLeft = targetLeft * distanceLeftOfTarget
  end
  targetLocation = targetPosition + targetForward + targetLeft
  local arrowData = {}
  engine.DrawFillSphere(targetPosition, 0.25, 65280, 3)
  engine.DrawFillSphere(targetLocation, 0.25, 16711680, 3)
  arrowData.Tweak = "ARR_SINGLESHOT_BOMB"
  arrowData.Creator = ai
  arrowData.CreatorEmitJoint = "JOMeleeWeapon1"
  arrowData.TargetLocation = targetLocation
  arrowData.EmitOffset = engine.Vector.New(0, 0, -1.1)
  game.Combat.EmitArrow(arrowData)
end
function LuaHook_AttStickyMineHive(ai)
  if global.target == nil then
    global.target = goPlayerCreature
  end
  local targetPosition = global.target:GetWorldPosition()
  local targetLocation = global.target:GetWorldPosition()
  local targetForward = global.target:GetWorldForward()
  local targetLeft = global.target:GetWorldLeft()
  local distanceFrontOfTarget = 1.5
  local distanceLeftOfTarget = 0
  local velocityMultiplier = 2.5
  local kratosVelocity = global.target:GetVelocity()
  kratosVelocity = kratosVelocity * velocityMultiplier
  local angleFwd = DL.GetAngleBetweenVector(targetForward, kratosVelocity)
  local angleLeft = DL.GetAngleBetweenVector(targetLeft, kratosVelocity)
  if kratosVelocity:Length() > 0.5 then
    kratosVelocity = kratosVelocity:Normalized() * velocityMultiplier
    if -45 <= angleFwd and angleFwd <= 45 then
      targetForward = targetForward * distanceFrontOfTarget + kratosVelocity
    else
      targetForward = targetForward * distanceFrontOfTarget
    end
    if -45 <= angleLeft and angleLeft <= 45 then
      targetLeft = targetLeft * distanceLeftOfTarget + kratosVelocity
    elseif angleLeft <= -135 or 135 <= angleLeft then
      targetLeft = targetLeft * distanceLeftOfTarget + kratosVelocity
    else
      targetLeft = targetLeft * distanceLeftOfTarget
    end
  else
    targetForward = targetForward * distanceFrontOfTarget
    targetLeft = targetLeft * distanceLeftOfTarget
  end
  targetLocation = targetPosition + targetForward + targetLeft
  local arrowData = {}
  engine.DrawFillSphere(targetPosition, 0.25, 65280, 3)
  engine.DrawFillSphere(targetLocation, 0.25, 16711680, 3)
  arrowData.Tweak = "ARR_HIVE_SHOT_BOMB"
  arrowData.Creator = ai
  arrowData.CreatorEmitJoint = "JOMeleeWeapon1"
  arrowData.TargetLocation = targetLocation
  arrowData.EmitOffset = engine.Vector.New(0, 0, -1.1)
  game.Combat.EmitArrow(arrowData)
end
function LuaHook_AttStickyMine_Right(ai)
  if global.target == nil then
    global.target = goPlayerCreature
  end
  local targetPosition = global.target:GetWorldPosition()
  local targetLocation = global.target:GetWorldPosition()
  local targetForward = global.target:GetWorldForward()
  local targetLeft = global.target:GetWorldLeft() * -1
  local distanceFrontOfTarget = 1.25
  local distanceLeftOfTarget = 1.5
  local velocityMultiplier = 1.5
  local kratosVelocity = global.target:GetVelocity()
  kratosVelocity = kratosVelocity * velocityMultiplier
  local angleFwd = DL.GetAngleBetweenVector(targetForward, kratosVelocity)
  local angleLeft = DL.GetAngleBetweenVector(targetLeft, kratosVelocity)
  if kratosVelocity:Length() > 0.5 then
    kratosVelocity = kratosVelocity:Normalized() * velocityMultiplier
    if -45 <= angleFwd and angleFwd <= 45 then
      targetForward = targetForward * distanceFrontOfTarget + kratosVelocity
    else
      targetForward = targetForward * distanceFrontOfTarget
    end
    if -45 <= angleLeft and angleLeft <= 45 then
      targetLeft = targetLeft * distanceLeftOfTarget + kratosVelocity
    else
      targetLeft = targetLeft * distanceLeftOfTarget
    end
  end
  targetLocation = targetPosition + targetForward + targetLeft
  local arrowData = {}
  engine.DrawFillSphere(targetPosition, 0.25, 65280, 3)
  engine.DrawFillSphere(targetLocation, 0.25, 16711680, 3)
  arrowData.Tweak = "ARR_TRIPLESHOT_BOMB"
  arrowData.Creator = ai
  arrowData.CreatorEmitJoint = "JOMeleeWeapon1"
  arrowData.TargetLocation = targetLocation
  arrowData.EmitOffset = engine.Vector.New(0, 0, -1.1)
  game.Combat.EmitArrow(arrowData)
end
function LuaHook_AttGrenadeShot(ai)
  local targetPosition = global.target:GetWorldPosition()
  local targetForward = global.target:GetWorldForward()
  local targetLeft = global.target:GetWorldLeft()
  local distanceFrontOfTarget = 1.5
  local distanceLeftOfTarget = 0
  local targetLocation = targetPosition + targetForward * distanceFrontOfTarget + targetLeft * distanceLeftOfTarget
  local arrowData = {}
  engine.DrawFillSphere(targetPosition, 0.25, 65280, 3)
  engine.DrawFillSphere(targetLocation, 0.25, 16711680, 3)
  arrowData.Tweak = "ARR_GRENADESHOT"
  arrowData.Creator = ai
  arrowData.CreatorEmitJoint = "JOMeleeWeapon1"
  arrowData.TargetLocation = targetLocation
  arrowData.EmitOffset = engine.Vector.New(0, 0, -1.1)
  game.Combat.EmitArrow(arrowData)
end
function LuaHook_Flank_CollisionCheck(ai, data)
  local distanceAmount = 6
  local jointIndex = ai:GetJointIndex("zeroJoint")
  local zeroJointFacingFwd = ai:GetWorldJointForward(jointIndex)
  local zeroJointFacingLeft = ai:GetWorldJointLeft(jointIndex)
  local offset = engine.Vector.New(0, 1.5, 0)
  local offsetZeroJoint = ai.WorldPosition + offset
  local toLeft = zeroJointFacingLeft * distanceAmount
  local offsetLeft = offsetZeroJoint + toLeft
  offsetLeft.y = offsetZeroJoint.y
  local hitLeft = game.World.RaycastCollision(offsetZeroJoint, offsetLeft, {SourceGameObject = ai, FindAnything = true})
  local toRight = zeroJointFacingLeft * -distanceAmount
  local offsetRight = offsetZeroJoint + toRight
  offsetRight.y = offsetZeroJoint.y
  local hitRight = game.World.RaycastCollision(offsetZeroJoint, offsetRight, {SourceGameObject = ai, FindAnything = true})
  if ai:DebugIsSelectedCreature() then
    engine.DrawLine(offsetZeroJoint, offsetLeft, 8388736)
    engine.DrawLine(offsetZeroJoint, offsetRight, 8388736)
  end
  if not hitRight and not hitLeft then
    return data:FindOutcomeBranchesEntry("EvadeAny")
  elseif not hitRight then
    return data:FindOutcomeBranchesEntry("EvadeRight")
  elseif not hitLeft then
    return data:FindOutcomeBranchesEntry("EvadeLeft")
  else
    return data:FindOutcomeBranchesEntry("EvadeFailed")
  end
end
function LuaHook_Evade_CollisionCheck(ai, data)
  local distanceAmount = 4
  local jointIndex = ai:GetJointIndex("zeroJoint")
  local zeroJointFacingFwd = ai:GetWorldJointForward(jointIndex)
  local zeroJointFacingLeft = ai:GetWorldJointLeft(jointIndex)
  local offset = engine.Vector.New(0, 0.5, 0)
  local offsetZeroJoint = ai.WorldPosition + offset
  local toLeftBack = zeroJointFacingLeft * distanceAmount + zeroJointFacingFwd * -distanceAmount
  local offsetLeftBack = offsetZeroJoint + toLeftBack
  offsetLeftBack.y = offsetZeroJoint.y
  local hitLeftBack = game.World.RaycastCollision(offsetZeroJoint, offsetLeftBack, {SourceGameObject = ai, FindAnything = true})
  local toRightBack = zeroJointFacingLeft * -distanceAmount + zeroJointFacingFwd * -distanceAmount
  local offsetRightBack = offsetZeroJoint + toRightBack
  offsetRightBack.y = offsetZeroJoint.y
  local hitRightBack = game.World.RaycastCollision(offsetZeroJoint, offsetRightBack, {SourceGameObject = ai, FindAnything = true})
  if ai:DebugIsSelectedCreature() then
    engine.DrawLine(offsetZeroJoint, offsetLeftBack, 8388736, 5)
    engine.DrawLine(offsetZeroJoint, offsetRightBack, 8388736, 5)
  end
  if not hitRightBack then
    return data:FindOutcomeBranchesEntry("EvadeRight")
  elseif not hitLeftBack then
    return data:FindOutcomeBranchesEntry("EvadeLeft")
  elseif ai:GetTargetCreature() == goPlayerCreature then
    return data:FindOutcomeBranchesEntry("EvadeFailed")
  else
    return data:FindOutcomeBranchesEntry("EvadeBlock")
  end
end
function LuaHook_AirRecover_CollisionCheck(ai, data)
  local distanceAmount = 4
  local jointIndex = ai:GetJointIndex("zeroJoint")
  local zeroJointFacingFwd = ai:GetWorldJointForward(jointIndex)
  local zeroJointFacingLeft = ai:GetWorldJointLeft(jointIndex)
  local offset = engine.Vector.New(0, 0.5, 0)
  local offsetZeroJoint = ai.WorldPosition + offset
  local toBack = zeroJointFacingFwd * -distanceAmount
  local offsetBack = offsetZeroJoint + toBack
  offsetBack.y = offsetZeroJoint.y
  local hitBack = game.World.RaycastCollision(offsetZeroJoint, offsetBack, {SourceGameObject = ai, FindAnything = true})
  local toLeft = zeroJointFacingLeft * distanceAmount
  local offsetLeft = offsetZeroJoint + toLeft
  offsetLeft.y = offsetZeroJoint.y
  local hitLeft = game.World.RaycastCollision(offsetZeroJoint, offsetLeft, {SourceGameObject = ai, FindAnything = true})
  local toRight = zeroJointFacingLeft * -distanceAmount
  local offsetRight = offsetZeroJoint + toRight
  offsetRight.y = offsetZeroJoint.y
  local hitRight = game.World.RaycastCollision(offsetZeroJoint, offsetRight, {SourceGameObject = ai, FindAnything = true})
  local toFront = zeroJointFacingFwd * distanceAmount
  local offsetFront = offsetZeroJoint + toFront
  offsetFront.y = offsetZeroJoint.y
  local hitFront = game.World.RaycastCollision(offsetZeroJoint, offsetFront, {SourceGameObject = ai, FindAnything = true})
  if ai:DebugIsSelectedCreature() then
    engine.DrawLine(offsetZeroJoint, offsetBack, 8388736, 5)
    engine.DrawLine(offsetZeroJoint, offsetFront, 8388736, 5)
    engine.DrawLine(offsetZeroJoint, offsetLeft, 8388736, 5)
    engine.DrawLine(offsetZeroJoint, offsetRight, 8388736, 5)
  end
  if not hitBack then
    return data:FindOutcomeBranchesEntry("RecoverBack")
  elseif not hitRight then
    return data:FindOutcomeBranchesEntry("RecoverRight")
  elseif not hitLeft then
    return data:FindOutcomeBranchesEntry("RecoverLeft")
  else
    return data:FindOutcomeBranchesEntry("RecoverForward")
  end
end
function LuaHook_RingOut_CollisionCheck(ai, data)
  local currentPosition = ai:GetWorldPosition()
  local horizontalDistance = 6
  local verticalDistance = goPlayerCreature:GetWorldPosition().y - 0.25
  local jointIndex = ai:GetJointIndex("zeroJoint")
  local zeroJointFacingFwd = ai:GetWorldJointForward(jointIndex)
  local zeroJointFacingLeft = ai:GetWorldJointLeft(jointIndex)
  local offset = engine.Vector.New(0, 0.5, 0)
  local offsetZeroJoint = ai.WorldPosition + offset
  local toBack = zeroJointFacingFwd * -horizontalDistance
  local offsetBack = offsetZeroJoint + toBack
  offsetBack.y = verticalDistance
  local hitBack = game.World.RaycastCollision(offsetZeroJoint, offsetBack, {SourceGameObject = ai, FindAnything = true})
  local toLeft = zeroJointFacingLeft * horizontalDistance
  local offsetLeft = offsetZeroJoint + toLeft
  offsetLeft.y = verticalDistance
  local hitLeft = game.World.RaycastCollision(offsetZeroJoint, offsetLeft, {SourceGameObject = ai, FindAnything = true})
  local toRight = zeroJointFacingLeft * -horizontalDistance
  local offsetRight = offsetZeroJoint + toRight
  offsetRight.y = verticalDistance
  local hitRight = game.World.RaycastCollision(offsetZeroJoint, offsetRight, {SourceGameObject = ai, FindAnything = true})
  local toFront = zeroJointFacingFwd * horizontalDistance
  local offsetFront = offsetZeroJoint + toFront
  offsetFront.y = verticalDistance
  local hitFront = game.World.RaycastCollision(offsetZeroJoint, offsetFront, {SourceGameObject = ai, FindAnything = true})
  if ai:DebugIsSelectedCreature() then
    engine.DrawLine(offsetZeroJoint, offsetBack, 8388736, 5)
    engine.DrawLine(offsetZeroJoint, offsetFront, 8388736, 5)
    engine.DrawLine(offsetZeroJoint, offsetLeft, 8388736, 5)
    engine.DrawLine(offsetZeroJoint, offsetRight, 8388736, 5)
  end
  if hitBack then
    engine.DrawFillSphere(hitBack.Position, 0.1, 16711680, 3)
    return data:FindOutcomeBranchesEntry("RecoverBack")
  elseif hitRight then
    engine.DrawFillSphere(hitRight.Position, 0.1, 16711680, 3)
    return data:FindOutcomeBranchesEntry("RecoverRight")
  elseif hitLeft then
    engine.DrawFillSphere(hitLeft.Position, 0.1, 16711680, 3)
    return data:FindOutcomeBranchesEntry("RecoverLeft")
  elseif hitFront then
    engine.DrawFillSphere(hitFront.Position, 0.1, 16711680, 3)
    return data:FindOutcomeBranchesEntry("RecoverForward")
  else
    return data:FindOutcomeBranchesEntry("RecoverFailed")
  end
end
function LuaHookDecision_Hive_Escape(ai, data)
  local availableZones = {
    "CombatFlyZone_1",
    "CombatFlyZone_2",
    "CombatFlyZone_3",
    "CombatFlyZone_4",
    "CombatFlyZone_5",
    "CombatFlyZone_6",
    "CombatFlyZone_7",
    "CombatFlyZone_8",
    "CombatFlyZone_9",
    "CombatFlyZone_10",
    "CombatFlyZone_11",
    "CombatFlyZone_12",
    "CombatFlyZone_13",
    "CombatFlyZone_14",
    "CombatFlyZone_15"
  }
  local kratosCurrentZone, myCurrentZone
  for i = #availableZones, 1, -1 do
    if goPlayerCreature:InsideZone(availableZones[i]) then
      kratosCurrentZone = i
      print("KRATOS IN ZONE: " .. kratosCurrentZone)
    end
    if ai:InsideZone(availableZones[i]) then
      myCurrentZone = i
      print("I AM IN ZONE: " .. myCurrentZone)
    end
  end
  if kratosCurrentZone == nil then
    print("!!!!!!!!!!!!!!!KRATOS ZONE IS NIL!!!!!!!!!!!!!!!!!!")
  elseif myCurrentZone == nil then
    print("!!!!!!!!!!!!!!!DARK ONE ZONE IS NIL!!!!!!!!!!!!!!!!!!")
  end
  if kratosCurrentZone ~= nil and myCurrentZone ~= nil then
    if kratosCurrentZone > myCurrentZone or kratosCurrentZone == 13 then
      return true
    else
      return false
    end
  end
end
function OnAIPostSpawn(ai)
  goPlayerCreature = game.Player.FindPlayer()
  setupCharacter(ai)
  local positioning = Brain_Core:GetPositioning()
  positioning.AddStandardPositioningZone("HiveFight", constants.fightPosDataHiveFight, constants.fightKnowledgeInputs)
  positioning.AddStandardPositioningZone("HeavyAttacker", constants.fightPosDataHeavyAttacker, constants.fightKnowledgeInputs)
  positioning.AddStandardPositioningZone("Summoner", constants.fightPosDataSummoner, constants.fightKnowledgeInputs)
end
function Brain_Core:OnSetPowerlevelOverrideCustom(ai, global, constants, level, isElite, forced)
  powerLevel = level
  ToggleCharacterConfig(ai, forced)
end
function setupCharacter(ai)
  local moveName = ""
  local aggroState = ""
  local spawnContext = ai:GetContext()
  ai:PickupAcquire("Barefoot_MFX_Pickup", 0)
  if StartConfig ~= nil then
    if StartConfig.PowerLevel ~= nil then
      powerLevel = StartConfig.PowerLevel
    end
    if StartConfig.Variant ~= nil then
      variant = StartConfig.Variant
    end
    if StartConfig.EliteDifficulty ~= nil and StartConfig.EliteDifficulty and not ai:PickupIsAcquired("DarkOne00_Elite") then
      ai:PickupAcquire("DarkOne00_Elite")
    end
    if StartConfig.AggroState ~= nil then
      DL.switch(StartConfig.AggroState):caseof({
        Unaware = function()
          aggroState = "UNAWARE"
        end,
        Passive = function()
          aggroState = "PASSIVE"
        end,
        NonHostile = function()
          aggroState = "NONHOSTILE"
        end,
        InCombat = function()
          aggroState = "INCOMBAT"
        end
      })
    end
    if StartConfig.TurretMode then
      ai:PickupAcquire("TurretMode")
      global.TurretMode = true
      if ai.SetDirectAimingModeIsEnabled then
        ai:SetDirectAimingModeIsEnabled(true)
      end
      if StartConfig.TurretModeBreakRange ~= nil then
        global.turretModeBreakRange = StartConfig.TurretModeBreakRange
        if 0 < global.turretModeBreakRange then
          global.turretModeBreak = true
        end
      end
    end
    if StartConfig.MaxSummon ~= nil then
      maxSummon = StartConfig.MaxSummon
    end
    if StartConfig.SpawnMove ~= nil then
      moveName = StartConfig.SpawnMove
    end
  end
  ToggleCharacterConfig(ai, not game.CHECK_FEATURE("PREEMPT_SPAWN_CONFIG"))
  if aggroState == "" then
    if DL.CheckCreatureContext(spawnContext, "UNAWARE") then
      aggroState = "UNAWARE"
    elseif DL.CheckCreatureContext(spawnContext, "NONHOSTILE") then
      aggroState = "NONHOSTILE"
    else
      aggroState = "INCOMBAT"
    end
  end
  global.aggroState = aggroState
  if moveName ~= "" then
    ai:ForceMove(moveName)
  end
  DL.NewGamePlusLevelBoost(ai, "DarkOne00_PowerLevel")
end
function ToggleClothNodes(ai, bodyType)
  ai:HideJoint(ai:GetJointIndex("CNfrontClothPatch1"))
  ai:HideJoint(ai:GetJointIndex("CNrearClothPatch1"))
  ai:HideJoint(ai:GetJointIndex("CNleftClothPatch1"))
  ai:HideJoint(ai:GetJointIndex("CNrightClothPatch1"))
  ai:HideJoint(ai:GetJointIndex("CNHeadClothPatches1"))
  ai:HideJoint(ai:GetJointIndex("CNHeadJewelryClothPatches1"))
  if bodyType == "light" then
    ai:ShowJoint(ai:GetJointIndex("CNfrontClothPatch1"))
    ai:ShowJoint(ai:GetJointIndex("CNrearClothPatch1"))
    ai:ShowJoint(ai:GetJointIndex("CNleftClothPatch1"))
    ai:ShowJoint(ai:GetJointIndex("CNrightClothPatch1"))
    ai:ShowJoint(ai:GetJointIndex("CNHeadClothPatches1"))
    ai:ShowJoint(ai:GetJointIndex("CNHeadJewelryClothPatches1"))
  elseif bodyType == "heavy" then
    ai:ShowJoint(ai:GetJointIndex("CNfrontClothPatch1"))
    ai:ShowJoint(ai:GetJointIndex("CNrearClothPatch1"))
    ai:ShowJoint(ai:GetJointIndex("CNleftClothPatch1"))
    ai:ShowJoint(ai:GetJointIndex("CNrightClothPatch1"))
    ai:ShowJoint(ai:GetJointIndex("CNHeadJewelryClothPatches1"))
  elseif bodyType == "summoner" then
    ai:ShowJoint(ai:GetJointIndex("CNfrontClothPatch1"))
    ai:ShowJoint(ai:GetJointIndex("CNrearClothPatch1"))
    ai:ShowJoint(ai:GetJointIndex("CNleftClothPatch1"))
    ai:ShowJoint(ai:GetJointIndex("CNrightClothPatch1"))
    ai:ShowJoint(ai:GetJointIndex("CNHeadJewelryClothPatches1"))
  elseif bodyType == "hive" then
    ai:ShowJoint(ai:GetJointIndex("CNfrontClothPatch1"))
    ai:ShowJoint(ai:GetJointIndex("CNrearClothPatch1"))
    ai:ShowJoint(ai:GetJointIndex("CNleftClothPatch1"))
    ai:ShowJoint(ai:GetJointIndex("CNrightClothPatch1"))
    ai:ShowJoint(ai:GetJointIndex("CNHeadClothPatches1"))
    ai:ShowJoint(ai:GetJointIndex("CNHeadJewelryClothPatches1"))
  end
end
function ToggleCharacterConfig(ai, override)
  if powerLevel == "1" then
    pLevelInt = 1
  elseif powerLevel == "2" then
    pLevelInt = 2
  elseif powerLevel == "3" then
    pLevelInt = 3
  elseif powerLevel == "4" then
    pLevelInt = 4
  elseif powerLevel == "5" then
    pLevelInt = 5
  elseif powerLevel == "6" then
    pLevelInt = 6
  elseif powerLevel == "7" then
    pLevelInt = 7
  elseif powerLevel == "8" then
    pLevelInt = 8
  else
    pLevelInt = powerLevel
  end
  if variant ~= nil then
    if variant == "QuickSpear" then
      if not ai:PickupIsAcquired("DarkOne_QuickSpear") then
        ai:PickupAcquire("DarkOne_QuickSpear")
      end
      if override ~= nil and override == true then
        local random = math.random(1, 2)
        if pLevelInt <= 2 then
          if random == 1 then
            ai:SetCharacterConfig("Light01")
          else
            ai:SetCharacterConfig("Light02")
          end
        elseif 3 <= pLevelInt and pLevelInt <= 4 then
          if random == 1 then
            ai:SetCharacterConfig("Light01_hard")
          else
            ai:SetCharacterConfig("Light02_hard")
          end
        elseif 5 <= pLevelInt then
          if random == 1 then
            ai:SetCharacterConfig("Light01_veryhard")
          else
            ai:SetCharacterConfig("Light02_veryhard")
          end
        end
      end
      ToggleClothNodes(ai, "light")
    elseif variant == "HeavySpear" then
      if not ai:PickupIsAcquired("DarkOne_HeavySpear") then
        ai:PickupAcquire("DarkOne_HeavySpear")
      end
      if override ~= nil and override == true then
        if pLevelInt <= 2 then
          ai:SetCharacterConfig("Heavy01")
        elseif 3 <= pLevelInt and pLevelInt <= 4 then
          ai:SetCharacterConfig("Heavy01_hard")
        elseif 5 <= pLevelInt then
          ai:SetCharacterConfig("Heavy01_veryhard")
        end
      end
      ToggleClothNodes(ai, "heavy")
    elseif variant == "Summoner" then
      if not ai:PickupIsAcquired("DarkOne_Summoner") then
        ai:PickupAcquire("DarkOne_Summoner")
      end
      if override ~= nil and override == true then
        if pLevelInt <= 2 then
          ai:SetCharacterConfig("Spawner01")
        elseif 3 <= pLevelInt and pLevelInt <= 4 then
          ai:SetCharacterConfig("Spawner01_hard")
        elseif 5 <= pLevelInt then
          ai:SetCharacterConfig("Spawner01_veryhard")
        end
      end
      ToggleClothNodes(ai, "summoner")
    elseif variant == "HiveFighter" then
      if not ai:PickupIsAcquired("DarkOne_HiveFighter") then
        ai:PickupAcquire("DarkOne_HiveFighter")
        ai:PickupSetStage("DarkOne_HiveFighter", 0)
      end
      if ai:PickupIsAcquired("HealthThreshold") then
        ai:PickupRelinquish("HealthThreshold")
      end
      if override ~= nil and override == true then
        local random = math.random(1, 2)
        if random == 1 then
          ai:SetCharacterConfig("Light01")
        else
          ai:SetCharacterConfig("Light02")
        end
      end
      ToggleClothNodes(ai, "hive")
    elseif variant == "HiveFighterWeak" then
      if not ai:PickupIsAcquired("DarkOne_HiveFighter") then
        ai:PickupAcquire("DarkOne_HiveFighter")
        ai:PickupSetStage("DarkOne_HiveFighter", 1)
      end
      if ai:PickupIsAcquired("HealthThreshold") then
        ai:PickupRelinquish("HealthThreshold")
      end
      if override ~= nil and override == true then
        local random = math.random(1, 2)
        if random == 1 then
          ai:SetCharacterConfig("Light01")
        else
          ai:SetCharacterConfig("Light02")
        end
      end
      ToggleClothNodes(ai, "hive")
    end
    if global.TurretMode and not global.turretModeBreak then
      if ai:PickupIsAcquired("HealthThreshold") then
        ai:PickupRelinquish("HealthThreshold")
      end
      if ai:PickupIsAcquired("DarkOne_HeavySpear") then
        ai:PickupRelinquish("DarkOne_HeavySpear")
        ai:PickupAcquire("DarkOne_QuickSpear")
        ai:PickupSetStage("DarkOne_QuickSpear", 1)
      elseif ai:PickupIsAcquired("DarkOne_QuickSpear") then
        ai:PickupSetStage("DarkOne_QuickSpear", 1)
      end
    end
  end
  if weaponObj == nil then
    for activeWeapon in ai:IterateActiveWeapons() do
      weaponObj = activeWeapon.Weapon
    end
  end
  timer.StartCreatureTimer(0.075, function()
    for activeWeapon in ai:IterateActiveWeapons() do
      local gameobj = activeWeapon.Weapon
      if gameobj:GetName() == "darkonespear00" then
        if variant == "HeavySpear" then
          gameobj:SetCharacterConfig("mace")
        elseif variant == "Summoner" then
          gameobj:SetCharacterConfig("spawnerMace")
        else
          gameobj:SetCharacterConfig("spear")
        end
      end
    end
  end)
end
function LuaHook_AlfStrongLightOneTakeDown()
  game.Audio.StartMusic("SND_MX_ALF_light_one_murdered")
end
function OnAIUpdate(ai)
  traverselink.OnUpdate(ai)
  if ai:PickupIsAcquired("DarkOne_HiveFighter") and ai:HasMarker("nooffscreen") == false then
    ai:AddMarker("nooffscreen")
  end
end
function _G.OnAICreateLuaState(ai)
  _G.OnAICreateLuaState = nil
end
picklelib.Install()
function Pickle(GO)
  return {
    global = global
  }
end
function Unpickle(GO, t)
  global = t.global
end
