local statemachine = require("ai.statemachine")
local DL = require("design.DesignerLibrary")
local tablex = require("core.tablex")
local picklelib = require("core.pickle")
local components = require("design.components")
local traverselink = require("creature.traverselink")
traverselink.InstallHooks()
local globalLuaHooks = require("design.GlobalLuaHooks")
globalLuaHooks.InstallHooks()
local lookAtConsts = require("game.lookAtConsts")
local timer = require("creature.timer")
local contextactionlibrary = require("level.contextactionlibrary")
contextactionlibrary.InstallHooks()
engine.SetIncrementalGCTime(500)
local luahooks = require("draugr00.luahooks")
Brain_Core = require("behavior.corebrain")
attachments = {}
constants = {}
global = {}
global.TurretMode = false
global.powerArmEnchantAmmo = 0
global.firstimeshot = false
global.allowDebug = false
global.spawnConfigs = {
  "medium_Pristine1",
  "medium_Pristine2",
  "light_Pristine1",
  "light_Pristine2",
  "heavy_Pristine1",
  "heavy_Pristine2"
}
local weaponConfigs = {
  "veryEasy",
  "easy",
  "easy",
  "moderate",
  "moderate",
  "hard",
  "hard",
  "veryHard"
}
global.turretModeBreak = false
global.turretModeBreakRange = 0
dontDropLoot = false
_G.thisLookAtEntry = nil
local powerLevel = "1"
local powerLevelInt = 1
local currentCharConfig = ""
local currentWeaponType, luaSpawnerBodyType
local activePowerArmL = false
local activePowerArmR = false
local activePowerBody = false
local activePowerLegs = false
local tempPadDown = false
local tempDebugAble = true
local debugType = 0
function ToggleClothNodes(ai, configString)
  ai:HideJoint(ai:GetJointIndex("CNlight_frontSkirtPatch1"))
  ai:HideJoint(ai:GetJointIndex("CNlight_rearSkirtPatch1"))
  ai:HideJoint(ai:GetJointIndex("CNlight01_leftHeadPatch1"))
  ai:HideJoint(ai:GetJointIndex("CNlight01_rightHeadPatch1"))
  ai:HideJoint(ai:GetJointIndex("CNlight00_leftHelmetPatch1"))
  ai:HideJoint(ai:GetJointIndex("CNlight00_rightHelmetPatch1"))
  ai:HideJoint(ai:GetJointIndex("CNmedium_frontSkirtPatch1"))
  ai:HideJoint(ai:GetJointIndex("CNmedium_rearSkirtPatch1"))
  ai:HideJoint(ai:GetJointIndex("CNmedium_leftHelmetPatch1"))
  ai:HideJoint(ai:GetJointIndex("CNmedium_rightHelmetPatch1"))
  ai:HideJoint(ai:GetJointIndex("medium00_torsoChainPatches1"))
  ai:HideJoint(ai:GetJointIndex("medium00_strapPatches1"))
  ai:HideJoint(ai:GetJointIndex("CNheavy_frontSkirtPatch1"))
  ai:HideJoint(ai:GetJointIndex("CNheavy_rearSkirtPatch1"))
  ai:HideJoint(ai:GetJointIndex("heavy_sideSkirtPatches1"))
  if configString == "light" then
    ai:ShowJoint(ai:GetJointIndex("CNlight_frontSkirtPatch1"))
    ai:ShowJoint(ai:GetJointIndex("CNlight_rearSkirtPatch1"))
    if powerLevelInt == 4 or powerLevelInt == 5 then
      ai:ShowJoint(ai:GetJointIndex("CNlight01_leftHeadPatch1"))
      ai:ShowJoint(ai:GetJointIndex("CNlight01_rightHeadPatch1"))
    elseif 6 <= powerLevelInt then
      ai:ShowJoint(ai:GetJointIndex("CNlight00_leftHelmetPatch1"))
      ai:ShowJoint(ai:GetJointIndex("CNlight00_rightHelmetPatch1"))
    end
  elseif configString == "medium" then
    ai:ShowJoint(ai:GetJointIndex("CNmedium_frontSkirtPatch1"))
    ai:ShowJoint(ai:GetJointIndex("CNmedium_rearSkirtPatch1"))
    if powerLevelInt == 2 or powerLevelInt == 3 then
      ai:ShowJoint(ai:GetJointIndex("medium00_strapPatches1"))
      ai:ShowJoint(ai:GetJointIndex("medium00_torsoChainPatches1"))
    elseif powerLevelInt == 4 or powerLevelInt == 5 then
      ai:ShowJoint(ai:GetJointIndex("medium00_strapPatches1"))
      ai:ShowJoint(ai:GetJointIndex("medium00_torsoChainPatches1"))
      ai:ShowJoint(ai:GetJointIndex("CNmedium_leftHelmetPatch1"))
      ai:ShowJoint(ai:GetJointIndex("CNmedium_rightHelmetPatch1"))
    elseif powerLevelInt == 6 or powerLevelInt == 7 then
      ai:ShowJoint(ai:GetJointIndex("CNmedium_leftHelmetPatch1"))
      ai:ShowJoint(ai:GetJointIndex("CNmedium_rightHelmetPatch1"))
    elseif powerLevelInt == 8 then
      ai:ShowJoint(ai:GetJointIndex("CNmedium_leftHelmetPatch1"))
      ai:ShowJoint(ai:GetJointIndex("CNmedium_rightHelmetPatch1"))
    end
  elseif configString == "heavy" then
    ai:ShowJoint(ai:GetJointIndex("CNheavy_frontSkirtPatch1"))
    ai:ShowJoint(ai:GetJointIndex("CNheavy_rearSkirtPatch1"))
    if 4 <= powerLevelInt then
      ai:ShowJoint(ai:GetJointIndex("heavy_sideSkirtPatches1"))
    end
  end
end
function LuaHook_ClearArrow(ai, data)
  game.Combat.RemoveArrows(ai)
end
function LuaHook_DraugrFXOff(ai, data)
  if ai:PickupIsAcquired("DraugrLoopingFX") then
    ai:PickupRelinquish("DraugrLoopingFX")
  end
  if ai:PickupIsAcquired("DraugrPowerArmsR") then
    ai:PickupSetStage("DraugrPowerArmsR", 4)
  end
  if ai:PickupIsAcquired("DraugrPowerArmsL") then
    ai:PickupSetStage("DraugrPowerArmsL", 4)
  end
end
function LuaHook_DraugrFXOn(ai, data)
  LuaHook_DraugrLoopFX(ai, data)
  if ai:PickupIsAcquired("DraugrPowerArmsR") then
    ai:PickupSetStage("DraugrPowerArmsR", 0)
  end
  if ai:PickupIsAcquired("DraugrPowerArmsL") then
    ai:PickupSetStage("DraugrPowerArmsL", 0)
  end
end
function LuaHook_DraugrLoopFX(ai, data)
  if ai:PickupIsAcquired("DraugrLoopingFX") then
    ai:PickupRelinquish("DraugrLoopingFX")
  end
  if ai:PickupIsAcquired("DraugrTwoHand") == false then
    ai:PickupAcquire("DraugrLoopingFX")
  end
end
function ToggleCharacterConfig(ai, configString, override)
  if configString ~= "" and configString ~= nil then
    if powerLevel == "1" then
      powerLevelInt = 1
    elseif powerLevel == "2" then
      powerLevelInt = 2
    elseif powerLevel == "3" then
      powerLevelInt = 3
    elseif powerLevel == "4" then
      powerLevelInt = 4
    elseif powerLevel == "5" then
      powerLevelInt = 5
    elseif powerLevel == "6" then
      powerLevelInt = 6
    elseif powerLevel == "7" then
      powerLevelInt = 7
    elseif powerLevel == "8" then
      powerLevelInt = 8
    else
      powerLevelInt = powerLevel
    end
    currentCharConfig = configString
    timer.StartCreatureTimer(0.1, function()
      InitializeJoints(ai)
    end)
    InitializeJoints(ai)
    if currentWeaponType ~= nil then
      activateWeaponType(ai, currentWeaponType)
      LuaHook_DraugrLoopFX(ai, nil)
    end
    if override ~= nil and override == true then
      LuaHook_DraugrConfigSetup(ai, nil)
    end
    ToggleClothNodes(ai, currentCharConfig)
    activateBodyType(ai, currentCharConfig)
  end
end
function LuaHook_DraugrConfigSetup(ai, data)
  local shieldString = ""
  if ai:PickupIsAcquired("DraugrShield") then
    shieldString = "_ArmShield"
  end
  local difficulty = "_veryeasy"
  if powerLevelInt == 1 then
    difficulty = "_veryeasy"
  elseif 1 < powerLevelInt and powerLevelInt < 4 then
    difficulty = "_easy"
  elseif 4 <= powerLevelInt and powerLevelInt < 6 then
    difficulty = "_moderate"
  elseif 6 <= powerLevelInt and powerLevelInt < 8 then
    difficulty = "_hard"
  else
    difficulty = "_veryhard"
  end
  global.currentCharConfigFull = "d_" .. currentCharConfig .. difficulty .. shieldString
  ai:SetCharacterConfig(global.currentCharConfigFull)
end
function LuaHook_Draugr_FixShards(ai, data)
  FixShards(ai)
end
function FixShards(ai)
  for weapon in ai:IterateActiveWeapons() do
    if weapon ~= nil and weapon.Weapon ~= nil then
      local wep = weapon.Weapon
      local wepName = wep:GetName()
      if wepName == "draugrrightarmshards00" or wepName == "draugrleftarmshards00" then
        if currentCharConfig == "heavy" then
          wep:SetCharacterConfig("heavy")
        else
          wep:SetCharacterConfig("light_medium")
        end
      end
    end
  end
end
local tempClothVis = false
function DoDebugStuff(ai)
  local player = game.Player.FindPlayer()
  if player.Pad.L1Down == true and tempDebugAble == true then
    if player.Pad.LeftDown == true then
      SetLimbHidden(ai, "LeftArms")
    elseif player.Pad.RightDown == true then
      SetLimbHidden(ai, "RightArms")
      ai:HideJoint(ai:GetJointIndex("JOMeleeWeapon1"))
    end
  elseif player.Pad.LeftDown == true and tempPadDown == false then
    tempDebugAble = false
    if tempClothVis then
      tempClothVis = false
    else
      tempClothVis = true
    end
    tempPadDown = true
  elseif tempDebugAble == true then
    if player.Pad.DownDown == true and tempPadDown == false then
      tempPadDown = true
      if currentCharConfig == "medium" then
        activateBodyType(ai, "light")
      elseif currentCharConfig == "light" then
        activateBodyType(ai, "heavy")
      elseif currentCharConfig == "heavy" then
        activateBodyType(ai, "medium")
      end
    elseif player.Pad.UpDown == true and tempPadDown == false then
      tempPadDown = true
      if ai:PickupIsAcquired("DraugrPowerHead") then
        ai:PickupRelinquish("DraugrPowerHead")
      end
      if ai:PickupIsAcquired("DraugrPowerBody") then
        ai:PickupRelinquish("DraugrPowerBody")
      end
      if ai:PickupIsAcquired("DraugrPowerLegs") then
        ai:PickupRelinquish("DraugrPowerLegs")
      end
      if ai:PickupIsAcquired("DraugrPowerArmsL") then
        ai:PickupRelinquish("DraugrPowerArmsL")
      end
      if ai:PickupIsAcquired("DraugrPowerArmsR") then
        ai:PickupRelinquish("DraugrPowerArmsR")
      end
      InitializeJoints(ai)
      if debugType == 0 then
        activatePowerLimb(ai, "Torsos")
      elseif debugType == 1 then
        activatePowerLimb(ai, "Legs")
      elseif debugType == 2 then
        activatePowerLimb(ai, "RightArms")
      elseif debugType == 3 then
        activatePowerLimb(ai, "LeftArms")
      elseif debugType == 4 then
        activatePowerLimb(ai, "LeftArms")
        activatePowerLimb(ai, "RightArms")
      elseif debugType == 5 then
        activatePowerLimb(ai, "Torsos")
        activatePowerLimb(ai, "Legs")
      elseif debugType == 6 then
        activatePowerLimb(ai, "Torsos")
        activatePowerLimb(ai, "RightArms")
      elseif debugType == 7 then
        activatePowerLimb(ai, "Torsos")
        activatePowerLimb(ai, "LeftArms")
      elseif debugType == 8 then
        activatePowerLimb(ai, "Torsos")
        activatePowerLimb(ai, "Legs")
        activatePowerLimb(ai, "LeftArms")
        activatePowerLimb(ai, "RightArms")
      end
      debugType = debugType + 1
      if debugType == 10 then
        debugType = 0
      end
    end
    if player.Pad.RightDown == true and tempPadDown == false then
      tempPadDown = true
      if ai:PickupIsAcquired("DraugrOneHand") then
        activateWeaponType(ai, "TwoHand")
      elseif ai:PickupIsAcquired("DraugrTwoHand") then
        activateWeaponType(ai, "DualWield")
      elseif ai:PickupIsAcquired("DraugrDualWield") then
        activateWeaponType(ai, "Shield")
      elseif ai:PickupIsAcquired("DraugrShield") then
        activateWeaponType(ai, "Unarmed")
      else
        activateWeaponType(ai, "OneHand")
      end
    end
  end
  if player.Pad.RightDown == false and player.Pad.LeftDown == false and player.Pad.UpDown == false and player.Pad.DownDown == false then
    tempPadDown = false
  end
end
function LuaScriptHook_SendLuaEvent(ai, arg1)
  ai:TriggerMoveEvent(arg1)
end
function InitializeJoints(ai)
  ai:HideJoint(ai:GetJointIndex("decap_Torsos"))
  ai:HideJoint(ai:GetJointIndex("decap_LeftArms"))
  ai:HideJoint(ai:GetJointIndex("decap_RightArms"))
  ai:HideJoint(ai:GetJointIndex("decap_Legs"))
  if activePowerArmL then
    activatePowerLimb(ai, "LeftArms")
  else
    SetLimbNormal(ai, "LeftArms")
  end
  if activePowerArmR then
    activatePowerLimb(ai, "RightArms")
  else
    SetLimbNormal(ai, "RightArms")
  end
  if activePowerBody then
    activatePowerLimb(ai, "Torsos")
  else
    SetLimbNormal(ai, "Torsos")
  end
  if activePowerLegs then
    activatePowerLimb(ai, "Legs")
  else
    SetLimbNormal(ai, "Legs")
  end
end
function SetLimbNormal(ai, limb)
  ai:HideJoint(ai:GetJointIndex("exploded_" .. limb .. ""))
  ai:ShowJoint(ai:GetJointIndex("pristine_" .. limb .. ""))
end
function SetLimbPower(ai, limb)
  ai:ShowJoint(ai:GetJointIndex("exploded_" .. limb .. ""))
  ai:HideJoint(ai:GetJointIndex("pristine_" .. limb .. ""))
end
function SetLimbHidden(ai, limb)
  ai:HideJoint(ai:GetJointIndex("exploded_" .. limb .. ""))
  ai:HideJoint(ai:GetJointIndex("pristine_" .. limb .. ""))
end
function FixTwoHandWeapon(ai)
  for activeWeapon in ai:IterateActiveWeapons() do
    local gameObj = activeWeapon.Weapon
    local gameObjName = gameObj:GetName()
    if gameObjName == "draugrtwohandedaxe00" then
      gameObj:SetCharacterConfig(weaponConfigs[powerLevelInt])
    end
  end
end
function activatePowerLimb(ai, powerLimb)
  if powerLimb == "Torsos" then
    LuaHook_DraugrPowerBodyOn(ai, nil)
  elseif powerLimb == "Legs" then
    LuaHook_DraugrPowerLegsOn(ai, nil)
  elseif powerLimb == "LeftArms" then
    LuaHook_DraugrPowerArmsLOn(ai, nil)
    FixShards(ai)
    if currentCharConfig == "heavy" then
      timer.StartCreatureTimer(0.2, function()
        FixTwoHandWeapon(ai)
      end)
    end
  elseif powerLimb == "RightArms" then
    LuaHook_DraugrPowerArmsROn(ai, nil)
    FixShards(ai)
    if currentCharConfig == "heavy" then
      timer.StartCreatureTimer(0.2, function()
        FixTwoHandWeapon(ai)
      end)
    end
  end
end
function activateBodyType(ai, bodytype)
  if not ai:PickupIsAcquired("DraugrBodyType") then
    ai:PickupAcquire("DraugrBodyType")
  end
  if bodytype == "heavy" then
    ai:PickupSetStage("DraugrBodyType", 1)
    ai:AddMarker("SonAggroResist")
    game.Audio.SetWwiseSwitch(ai, "CHR_Draugr_Type", "Large")
  elseif bodytype == "light" then
    if not ai:PickupIsActive("TurretMode") or ai:PickupIsActive("TurretMode") and global.turretModeBreak then
      ai:PickupSetStage("DraugrBodyType", 2)
    else
      ai:PickupSetStage("DraugrBodyType", 3)
    end
    game.Audio.SetWwiseSwitch(ai, "CHR_Draugr_Type", "Small")
  elseif bodytype == "turret" then
    ai:PickupSetStage("DraugrBodyType", 3)
    game.Audio.SetWwiseSwitch(ai, "CHR_Draugr_Type", "Small")
  else
    ai:PickupSetStage("DraugrBodyType", 0)
    game.Audio.SetWwiseSwitch(ai, "CHR_Draugr_Type", "Medium")
  end
end
function activateWeaponType(ai, weaponType)
  ai:TriggerMoveEvent("kLEDraugrUnarmedFethOff")
  if ai:PickupIsAcquired("DraugrOneHand") then
    ai:PickupRelinquish("DraugrOneHand")
  end
  if ai:PickupIsAcquired("DraugrTwoHand") then
    ai:PickupRelinquish("DraugrTwoHand")
  end
  if ai:PickupIsAcquired("DraugrDualWield") then
    ai:PickupRelinquish("DraugrDualWield")
  end
  if ai:PickupIsAcquired("DraugrShield") then
    ai:PickupRelinquish("DraugrShield")
    SetLimbNormal(ai, "LeftArms")
  end
  if ai:PickupIsActive("TurretMode") and global.turretModeBreak == false then
    currentCharConfig = "light"
  end
  if weaponType == "OneHand" then
    ai:PickupAcquire("DraugrOneHand")
  elseif weaponType == "TwoHand" then
    ai:PickupAcquire("DraugrTwoHand")
    currentCharConfig = "heavy"
  elseif weaponType == "DualWield" then
    ai:PickupAcquire("DraugrDualWield")
    currentCharConfig = "light"
    ai:SetAggressivePriority(2)
    local positioning = Brain_Core:GetPositioning()
  elseif weaponType == "Shield" then
    ai:PickupAcquire("DraugrShield")
    currentCharConfig = "medium"
  else
    ai:ForceMove("BRA_NavIdleUnarmedFeth")
  end
  timer.StartCreatureTimer(0.1, function()
    for activeWeapon in ai:IterateActiveWeapons() do
      local gameObj = activeWeapon.Weapon
      local gameObjName = gameObj:GetName()
      if gameObjName == "draugrsword00" then
        gameObj:SetCharacterConfig(weaponConfigs[powerLevelInt])
      end
      if gameObjName == "draugrtwohandedaxe00" then
        gameObj:SetCharacterConfig(weaponConfigs[powerLevelInt])
      end
      if gameObjName == "draugraxe01" then
        gameObj:SetCharacterConfig(weaponConfigs[powerLevelInt])
      end
    end
  end)
end
function LuaHookDecision_IsSonTargetingSelf(ai, data)
  local son = game.AI.FindSon()
  if son ~= nil and ai == son:GetTargetCreature() and _G.global.targetParams == "FIND_TARGET_PARAMETERS_COMBAT_SON_ONLY" then
    return true
  end
  return false
end
function LuaHookDecision_IsTargetSon(ai, data)
  local currentTarget = ai:GetTargetCreature()
  if currentTarget == game.AI.FindSon() and _G.global.targetParams == "FIND_TARGET_PARAMETERS_COMBAT_SON_ONLY" then
    return true
  end
  return false
end
function LuaHookDecision_IsTargetHero(ai, data)
  local currentTarget = ai:GetTargetCreature()
  if currentTarget == game.Player.FindPlayer() and _G.global.targetParams == "FIND_TARGET_PARAMETERS_COMBAT_KRATOS_ONLY" then
    return true
  end
  return false
end
function LuaHook_JasonTargetSon(ai)
  ai:CallScript("OnForceTempAggro", 6)
end
function LuaHookDecision_IsTargetAccurate(ai, data)
  local currentTarget = ai:GetTargetCreature()
  if currentTarget == game.AI.FindSon() and _G.global.targetParams == "FIND_TARGET_PARAMETERS_COMBAT_SON_ONLY" or currentTarget == game.Player.FindPlayer() and _G.global.targetParams == "FIND_TARGET_PARAMETERS_COMBAT_KRATOS_ONLY" then
    return true
  end
  return false
end
function setupCharacter(ai)
  local moveName = ""
  local spawnContext = ai:GetContext()
  if StartConfig ~= nil then
    if StartConfig.SpawnMove ~= nil then
      moveName = StartConfig.SpawnMove
    end
    if StartConfig.EliteDifficulty ~= nil and StartConfig.EliteDifficulty and not ai:PickupIsAcquired("Draugr00_Elite") then
      ai:PickupAcquire("Draugr00_Elite")
    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 global.turretModeBreakRange > 0 then
          global.turretModeBreak = true
        end
      end
      if global.turretModeBreak == false and ai:PickupIsAcquired("HealthThreshold") then
        ai:PickupRelinquish("HealthThreshold")
      end
    end
    if StartConfig.DispelSource then
      ai:PickupAcquire("DispelObject")
    end
    if StartConfig.DontDropLoot then
      dontDropLoot = StartConfig.DontDropLoot
    end
    currentWeaponType = StartConfig.WeaponType
    if StartConfig.PowerArmL == true then
      activePowerArmL = true
    end
    if StartConfig.PowerArmR == true then
      activePowerArmR = true
    end
    if StartConfig.PowerBody == true then
      activePowerBody = true
    end
    if StartConfig.PowerLegs == true then
      activePowerLegs = true
    end
    if StartConfig.BodyType ~= nil then
      luaSpawnerBodyType = StartConfig.BodyType
    end
  end
  if game.GetNewGamePlus() and global.TurretMode == false and (ai.GroundLevel == nil or ai.GroundLevel ~= nil and string.find(ai.GroundLevel.Name, "Riv975_ChiselArena") == nil and string.find(ai.GroundLevel.Name, "Msp") == nil and string.find(ai.GroundLevel.Name, "Stn430_") == nil) then
    local numLimbsPowered = 0
    if activePowerArmL == true then
      numLimbsPowered = numLimbsPowered + 1
    end
    if activePowerArmR == true then
      numLimbsPowered = numLimbsPowered + 1
    end
    if activePowerBody == true then
      numLimbsPowered = numLimbsPowered + 1
    end
    if activePowerLegs == true then
      numLimbsPowered = numLimbsPowered + 1
    end
    if numLimbsPowered <= 1 then
      local rand = math.random(1, 8)
      if currentWeaponType == "OneHand" then
        if rand <= 2 then
          if not activePowerBody then
            activePowerBody = true
          else
            activePowerLegs = true
          end
        elseif rand <= 5 then
          if not activePowerLegs then
            activePowerLegs = true
          else
            activePowerArmR = true
          end
        elseif rand <= 8 then
          if not activePowerArmR then
            activePowerArmR = true
          else
            activePowerBody = true
          end
        end
      elseif currentWeaponType == "TwoHand" then
        if rand <= 3 then
          if not activePowerBody then
            activePowerBody = true
          else
            activePowerLegs = true
          end
        elseif rand <= 8 then
          if not activePowerArmL then
            activePowerArmL = true
          else
            activePowerLegs = true
          end
        end
      elseif currentWeaponType == "DualWield" then
        if rand <= 3 or activePowerLegs then
          activePowerBody = true
        elseif rand <= 8 or activePowerBody then
          activePowerLegs = true
        end
      elseif currentWeaponType == "Shield" then
        if rand <= 3 or activePowerLegs then
          activePowerBody = true
        elseif rand <= 8 or activePowerBody then
          activePowerLegs = true
        end
      end
    end
  end
  ToggleCharacterConfig(ai, luaSpawnerBodyType, not game.CHECK_FEATURE("PREEMPT_SPAWN_CONFIG"))
  if StartConfig ~= nil and StartConfig.NonCombatState == "Idle" and (ai:IsPlayingMove("MOV_Spawn") or moveName == "BRA_Spawn") then
    if string.upper(StartConfig.AggroState) == "INCOMBAT" then
      moveName = "BRA_SpawnAware"
    else
      moveName = "BRA_SpawnUnawareLoop"
    end
    if moveName ~= "" then
      ai:ForceMove(moveName)
    end
  end
  if ai:AttributeGetValue("Difficulty") == 4 then
    local cineVar = game.Level.GetVariable("CompletedCineNumber")
    if ai:PickupIsAcquired("Draugr00_PowerLevel") and (180 <= cineVar and 1 >= ai:PickupGetStage("Draugr00_PowerLevel") or 250 <= cineVar and 2 >= ai:PickupGetStage("Draugr00_PowerLevel") or 380 <= cineVar and 3 >= ai:PickupGetStage("Draugr00_PowerLevel") and cineVar ~= 425 or 490 <= cineVar and 4 >= ai:PickupGetStage("Draugr00_PowerLevel")) and (ai.GroundLevel == nil or ai.GroundLevel ~= nil and string.find(ai.GroundLevel.Name, "Msp") == nil and string.find(ai.GroundLevel.Name, "Riv975_ChiselArena") == nil and string.find(ai.GroundLevel.Name, "Stn430_") == nil) then
      ai:PickupAcquire("PowerLevelBoost")
    end
  end
  DL.NewGamePlusLevelBoost(ai, "Draugr00_PowerLevel")
end
function OnAIPostSpawn(ai)
  setupCharacter(ai)
  _G.thisLookAtEntry = game.AddGlobalLookAtTarget(ai, engine.Vector.New(0, 1.3, 0), lookAtConsts.TargetType.BadGuy)
  local positioning = Brain_Core:GetPositioning()
  positioning.AddStandardPositioningZone("TwoHand", constants.fightPosDataTwoHand, constants.fightKnowledgeInputs)
  positioning.AddStandardPositioningZone("Ranged", constants.fightPosDataRanged, constants.fightKnowledgeInputs)
  positioning.AddStandardPositioningZone("Shielded", constants.fightPosDataShielded, constants.fightKnowledgeInputs)
  positioning.AddStandardPositioningZone("PowerLegs", constants.fightPosDataPowerLegs, constants.fightKnowledgeInputs)
  if ai.GroundLevel ~= nil and (ai.GroundLevel.Name == "WAD_TB_Denny" or ai.GroundLevel.Name == "WAD_TB_Draugr") then
    global.allowDebug = false
  end
end
function Brain_Core:OnSetPowerlevelOverrideCustom(ai, global, constants, level, isElite, forced)
  powerLevel = level
  ToggleCharacterConfig(ai, currentCharConfig, forced)
end
function OnAIUpdate(ai)
  components.UpdateComponents(ai, attachments)
  traverselink.OnUpdate(ai)
  if global.allowDebug then
    DoDebugStuff(ai)
  end
  if LuaHookDecision_IsTargetSon(ai) then
    engine.DrawFillSphere(ai:GetWorldPosition(), 0.085, 16711680)
  end
end
function _G.OnAICreateLuaState(ai)
  components.StartComponents(ai, attachments)
  _G.OnAICreateLuaState = nil
end
function Brain_Core:OnUpdateCombat(ai, global, constants, dTreeParams)
  local son = game.AI.FindSon()
  if global.target ~= son then
    if ai:PickupIsAcquired("DraugrShield") then
      constants.fightKnowledgeInputs.CurrentZoneSet = "Shielded"
    end
    if ai:PickupIsAcquired("DraugrPowerArmsL") then
      constants.fightKnowledgeInputs.CurrentZoneSet = "Ranged"
    end
    if ai:PickupIsAcquired("DraugrTwoHand") then
      constants.fightKnowledgeInputs.CurrentZoneSet = "TwoHand"
    end
    if ai:PickupIsAcquired("DraugrPowerLegs") then
      constants.fightKnowledgeInputs.CurrentZoneSet = "PowerLegs"
    end
  end
end
function Brain_Core:OnUpdateMotion(ai, global, constants, actuatorData)
end
function Brain_Core:OnHitReaction(event, ai, global, constants)
  if ai:PickupIsAcquired("DraugrDualPowerUp") then
    ai:PickupRelinquish("DraugrDualPowerUp")
  end
end
function LuaHook_BackAttackOpportunity(ai, data)
  if not _G.global.target then
    return
  end
  local relativePos = DL.GetObjectARelativePositionToObjectB(_G.global.target, ai)
  if relativePos == "objBack" then
    ai:TriggerMoveEvent("kLEBackAttackOpportunity")
  else
    return
  end
end
function LuaHook_DraugrPowerHeadOn(ai, data)
  if ai:PickupIsAcquired("DraugrPowerHead") == false then
    ai:PickupAcquire("DraugrPowerHead")
    ai:PickupSetStage("DraugrPowerHead", 4)
  end
end
function LuaHook_DraugrPowerBodyOn(ai, data)
  SetLimbPower(ai, "Torsos")
  if ai:PickupIsAcquired("DraugrPowerBody") == false then
    ai:PickupAcquire("DraugrPowerBody")
    ai:PickupSetStage("DraugrPowerBody", 4)
  end
end
function LuaHook_DraugrPowerLegsOn(ai, data)
  SetLimbPower(ai, "Legs")
  if ai:PickupIsAcquired("DraugrPowerLegs") == false then
    ai:PickupAcquire("DraugrPowerLegs")
    ai:PickupSetStage("DraugrPowerLegs", 4)
  end
end
function LuaHook_DraugrPowerArmsLOn(ai, data)
  SetLimbPower(ai, "LeftArms")
  if ai:PickupIsAcquired("DraugrPowerArmsL") == false then
    ai:PickupAcquire("DraugrPowerArmsL")
    ai:PickupSetStage("DraugrPowerArmsL", 0)
  end
  Brain_Core:SetSonAggro(false)
end
function LuaHook_DraugrPowerArmsROn(ai, data)
  SetLimbPower(ai, "RightArms")
  if ai:PickupIsAcquired("DraugrPowerArmsR") == false then
    ai:PickupAcquire("DraugrPowerArmsR")
    ai:PickupSetStage("DraugrPowerArmsR", 0)
  end
end
function LuaHook_DraugrSetLightVariant(ai, data)
  ToggleCharacterConfig(ai, "light")
end
function LuaHook_DraugrSetMediumVariant(ai, data)
  ToggleCharacterConfig(ai, "medium")
end
function LuaHook_Draugr_PowerArmBlast(ai, data)
  local target = ai:GetTargetCreature()
  if target == nil then
    target = game.Player.FindPlayer()
  end
  local offset = engine.Vector.New(0 + math.random(0.01, 0.03), 2.1, 0 + math.random(0.01, 0.03))
  local powerArmBlastArrowData = {}
  powerArmBlastArrowData.Tweak = "ARR_DRAUGR_PROJECTILE_TWK"
  powerArmBlastArrowData.Creator = ai
  powerArmBlastArrowData.CreatorEmitJoint = "JOLeftWrist1"
  powerArmBlastArrowData.EmitOffset = nil
  if game.Camera.GetViewPenetration(ai:GetWorldPosition(), 0, 0) > 0.2 then
    print("ON SCREEN SHOT")
    powerArmBlastArrowData.Target = target
  elseif global.firstimeshot == false then
    print("OFF SCREEN SHOT - FIRST MISS")
    global.firstimeshot = true
    powerArmBlastArrowData.Target = nil
    powerArmBlastArrowData.TargetLocation = target.WorldPosition + offset
  else
    local randomMiss = math.random(1, 4)
    if randomMiss == 1 then
      print("OFF SCREEN SHOT - RANDOM MISS")
      powerArmBlastArrowData.Target = nil
      powerArmBlastArrowData.TargetLocation = target.WorldPosition + offset
    else
      print("OFF SCREEN SHOT - RANDOM HIT")
      powerArmBlastArrowData.Target = target
    end
  end
  game.Combat.EmitArrow(powerArmBlastArrowData)
end
function LuaHook_Draugr_PowerArmBlast_R(ai, data)
  local player = game.Player.FindPlayer()
  local powerArmBlastArrowData = {}
  powerArmBlastArrowData.Tweak = "ARR_DRAUGR_PROJECTILE_TWK"
  powerArmBlastArrowData.Creator = ai
  powerArmBlastArrowData.CreatorEmitJoint = "JORightWrist1"
  powerArmBlastArrowData.Target = player
  powerArmBlastArrowData.EmitOffset = nil
  game.Combat.EmitArrow(powerArmBlastArrowData)
end
function LuaHook_Draugr_Stn430FireAtSon(ai, data)
  local son = game.AI.FindSon()
  local powerArmBlastArrowData = {}
  powerArmBlastArrowData.Tweak = "ARR_DRAUGR_PROJECTILE_TWK"
  powerArmBlastArrowData.Creator = ai
  powerArmBlastArrowData.CreatorEmitJoint = "JORightWrist1"
  powerArmBlastArrowData.Target = son
  powerArmBlastArrowData.EmitOffset = nil
  game.Combat.EmitArrow(powerArmBlastArrowData)
end
function LuaHook_Draugr_PowerUp(ai, data)
  ai:PickupAcquire("DraugrDualPowerUp")
end
function LuaHook_Draugr_POI_ApplyColdToHotstone(ai, data)
  if _G.global.currentPOI ~= nil then
    _G.global.currentPOI:SendEvent("OnCreatureTriggeredEvent")
  end
end
function LuaHook_MatAnim_BodyShieldOn(ai, data)
  ai:StartMaterialAnim("DraugrEffectTorso_ON")
end
function LuaHook_MatAnim_BodyShieldLoop(ai, data)
  ai:StartMaterialAnim("DraugrEffectTorso_LOOP")
end
function LuaHook_MatAnim_BodyShieldOff(ai, data)
  ai:StartMaterialAnim("DraugrEffectTorso_OFF")
end
picklelib.Install()
function Pickle(GO)
  return {
    global = global
  }
end
function Unpickle(GO, t)
  global = t.global
end
