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 mpicon = require("ui.mpicon")
local globalLuaHooks = require("design.GlobalLuaHooks")
globalLuaHooks.InstallHooks()
local traverselink = require("creature.traverselink")
traverselink.InstallHooks()
Brain_Core = require("behavior.corebrain")
constants = {}
global = {}
local goPlayerCreature, powerLevel
local pLevelInt = 1
local variant
local darkEliteNavEvadeUsed = false
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("kLEDarkOneEliteWeaponApproach")
  end
end
function LuaHook_DarkEliteNavEvade(ai, data)
  darkEliteNavEvadeUsed = true
end
function LuaHook_ReactionBreakerReset(ai, data)
  DL.ComboBreakerDecay(ai, 9999)
  if ai:HasMarker("ReactionBreakerReady") then
    ai:RemoveMarker("ReactionBreakerReady")
  end
end
function LuaHook_ReactionBreakerReduce(ai, data)
  DL.ComboBreakerDecayAbsolute(ai, 30)
  if ai:HasMarker("ReactionBreakerReady") then
    ai:RemoveMarker("ReactionBreakerReady")
  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")
  elseif not hitFront then
    return data:FindOutcomeBranchesEntry("RecoverForward")
  else
    return data:FindOutcomeBranchesEntry("RecoverFailed")
  end
end
function LuaHook_AttTripleShot(ai)
  LuaHook_AttTripleShot_Left(ai)
  LuaHook_AttTripleShot_Center(ai)
  LuaHook_AttTripleShot_Right(ai)
end
function LuaHook_AttTripleShot_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.5
  local distanceLeftOfTarget = 3
  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
  end
  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
    targetLeft = targetLeft * -1
  else
    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_STICKYMINE_ELITE_SHOT"
  arrowData.Creator = ai
  arrowData.CreatorEmitJoint = "JOMeleeWeapon1"
  arrowData.TargetLocation = targetLocation
  arrowData.EmitOffset = engine.Vector.New(0, 0, -1.1)
  game.Combat.EmitArrow(arrowData)
  print("LEFT SHOT FIRE AT ")
  print(arrowData.TargetLocation)
  print(angleFwd)
  print(angleLeft)
  print("------------------")
end
function LuaHook_AttTripleShot_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.25
  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
  else
    targetForward = targetForward * distanceFrontOfTarget
    targetLeft = targetLeft * distanceLeftOfTarget
  end
  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
  targetLocation = targetPosition + targetForward + targetLeft
  local arrowData = {}
  engine.DrawFillSphere(targetPosition, 0.25, 65280, 3)
  engine.DrawFillSphere(targetLocation, 0.25, 16711680, 3)
  arrowData.Tweak = "ARR_STICKYMINE_ELITE_SHOT"
  arrowData.Creator = ai
  arrowData.CreatorEmitJoint = "JOMeleeWeapon1"
  arrowData.TargetLocation = targetLocation
  arrowData.EmitOffset = engine.Vector.New(0, 0, -1.1)
  game.Combat.EmitArrow(arrowData)
  print("CENTER SHOT FIRE AT ")
  print(arrowData.TargetLocation)
  print(angleFwd)
  print(angleLeft)
  print("------------------")
end
function LuaHook_AttTripleShot_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.5
  local distanceLeftOfTarget = 3
  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
  end
  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
  targetLocation = targetPosition + targetForward + targetLeft
  local arrowData = {}
  engine.DrawFillSphere(targetPosition, 0.25, 65280, 3)
  engine.DrawFillSphere(targetLocation, 0.25, 16711680, 3)
  arrowData.Tweak = "ARR_STICKYMINE_ELITE_SHOT"
  arrowData.Creator = ai
  arrowData.CreatorEmitJoint = "JOMeleeWeapon1"
  arrowData.TargetLocation = targetLocation
  arrowData.EmitOffset = engine.Vector.New(0, 0, -1.1)
  game.Combat.EmitArrow(arrowData)
  print("RIGHT SHOT FIRE AT ")
  print(arrowData.TargetLocation)
  print(angleFwd)
  print(angleLeft)
  print("------------------")
end
function LuaHook_MotionWarp_AttAirDive(ai, data)
  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 = 0
  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
  engine.DrawFillSphere(targetPosition, 0.25, 65280, 3)
  engine.DrawFillSphere(targetLocation, 0.25, 16711680, 3)
  local warpRot = ai:GetAnimDriver("AttAirDiveRot")
  warpRot.ValueVec = ai:GetWorldForward()
  local warpLoc = ai:GetAnimDriver("AttAirDivePos")
  warpLoc.ValueVec = targetLocation
  if ai:IsPlayingMove("MOV_AttAirDive_Warped") then
    ai:TriggerMoveEvent("kLEDarkOne_AirDiveWarped")
  elseif ai:IsPlayingMove("MOV_AttAirDive_Warped_Combo_01") then
    ai:TriggerMoveEvent("kLEDarkOne_AirDiveWarped_01")
  elseif ai:IsPlayingMove("MOV_AttAirDive_Warped_Combo_02") then
    ai:TriggerMoveEvent("kLEDarkOne_AirDiveWarped_02")
  end
end
local bossHealthBarOn = false
function ShowHealthBar(ai)
  if bossHealthBarOn == false then
    ai:ForceHideHealthBar()
    mpicon.level.Create(ai:GetGameObject(), "BOSS_HEALTH_BAR_DARKONE_KING")
    mpicon.level.SetTextObjectText(ai, "BOSS_HEALTH_BAR_DARKONE_KING", "bossName", "[MSG:" .. 40136 .. "]")
    mpicon.level.SetTextObjectText(ai, "BOSS_HEALTH_BAR_DARKONE_KING", "icon", "\198\155")
    bossHealthBarOn = true
  end
end
function HideHealthBar(ai)
  if bossHealthBarOn == true then
    mpicon.level.Off(ai:GetGameObject(), "BOSS_HEALTH_BAR_DARKONE_KING")
    bossHealthBarOn = false
  end
end
function HideDefaultHealthBar(ai)
  ai:ForceHideHealthBar()
end
function OnAIPostSpawn(ai)
  goPlayerCreature = game.Player.FindPlayer()
  if StartConfig ~= nil and StartConfig.Variant ~= nil then
    variant = StartConfig.Variant
  end
  setupCharacter(ai, not game.CHECK_FEATURE("PREEMPT_SPAWN_CONFIG"))
  detectAggroStateFromSpawnMove(ai)
  if ai.GroundLevel ~= nil and ai.GroundLevel.Name == "WAD_TB_DarkOne_Variants" and variant == "Boss" then
    ShowHealthBar(ai)
  end
end
function Brain_Core:OnSetPowerlevelOverrideCustom(ai, global, constants, level, isElite, forced)
  powerLevel = level
  setupCharacter(ai, forced)
end
function setupCharacter(ai, override)
  ai:PickupAcquire("Barefoot_MFX_Pickup", 0)
  if variant ~= nil and powerLevel ~= nil then
    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 not ai:PickupIsAcquired("DarkOneElite00") then
      ai:PickupAcquire("DarkOneElite00")
    end
    if not ai:PickupIsAcquired("DarkOne_Elite_ComboCounter") then
      ai:PickupAcquire("DarkOne_Elite_ComboCounter")
    end
    if not ai:PickupIsAcquired("DarkOne_EliteSpear") then
      ai:PickupAcquire("DarkOne_EliteSpear")
    end
    ai:HideJoint(ai:GetJointIndex("CNfrontSkirtPatch1"))
    ai:HideJoint(ai:GetJointIndex("CNrearSkirtPatch1"))
    ai:HideJoint(ai:GetJointIndex("CNHeadClothPatches1"))
    ai:HideJoint(ai:GetJointIndex("CNHeadJewelryClothPatches1"))
    ai:HideJoint(ai:GetJointIndex("CNleftHeadJewelryBPatch1"))
    if variant == "Normal" then
      if 4 < pLevelInt then
        if override ~= nil and override == true then
          ai:SetCharacterConfig("veryhardVariant")
        end
        ai:ShowJoint(ai:GetJointIndex("CNfrontSkirtPatch1"))
        ai:ShowJoint(ai:GetJointIndex("CNrearSkirtPatch1"))
        ai:ShowJoint(ai:GetJointIndex("CNHeadClothPatches1"))
        ai:ShowJoint(ai:GetJointIndex("CNHeadJewelryClothPatches1"))
        ai:ShowJoint(ai:GetJointIndex("CNleftHeadJewelryBPatch1"))
      else
        if override ~= nil and override == true then
          ai:SetCharacterConfig("normalVariant")
        end
        ai:ShowJoint(ai:GetJointIndex("CNfrontSkirtPatch1"))
        ai:ShowJoint(ai:GetJointIndex("CNrearSkirtPatch1"))
        ai:ShowJoint(ai:GetJointIndex("CNHeadClothPatches1"))
        ai:ShowJoint(ai:GetJointIndex("CNHeadJewelryClothPatches1"))
        ai:ShowJoint(ai:GetJointIndex("CNleftHeadJewelryBPatch1"))
      end
    else
      if override ~= nil and override == true then
        ai:SetCharacterConfig("hardVariant")
      end
      ai:ShowJoint(ai:GetJointIndex("CNfrontSkirtPatch1"))
      ai:ShowJoint(ai:GetJointIndex("CNrearSkirtPatch1"))
      ai:ShowJoint(ai:GetJointIndex("CNHeadClothPatches1"))
    end
    timer.StartCreatureTimer(0.05, function()
      for activeWeapon in ai:IterateActiveWeapons() do
        local gameObj = activeWeapon.Weapon
        local difficulty = ai:AttributeGetValue("Difficulty")
        if gameObj:GetName() == "darkoneelitespear00" then
          if variant == "Boss" then
            gameObj:SetCharacterConfig("eliteBoss")
            if ai:PickupIsAcquired("DarkOneElite00_PowerLevel") then
              ai:PickupRelinquish("DarkOneElite00_PowerLevel")
            end
            if ai:PickupIsAcquired("DarkOneElite00") then
              ai:PickupRelinquish("DarkOneElite00")
              ai:PickupAcquire("DarkOneElite00_King")
            end
            if ai:PickupIsAcquired("HealthThreshold") then
              ai:PickupRelinquish("HealthThreshold")
            end
            if difficulty == 1 then
              DL.NewGamePlusLevelBoostFlat(ai, 3)
            else
              DL.NewGamePlusLevelBoostFlat(ai, 4)
            end
          else
            gameObj:SetCharacterConfig("eliteHeavy")
          end
        end
      end
    end)
  end
  if game.GetNewGamePlus() then
    if ai.GroundLevel == nil or ai.GroundLevel ~= nil and string.find(ai.GroundLevel.Name, "Cal410_") == nil then
      DL.NewGamePlusLevelBoost(ai, "DarkOneElite00_PowerLevel")
    else
      local difficulty = ai:AttributeGetValue("Difficulty")
      if difficulty == 4 then
        DL.NewGamePlusLevelBoostFlat(ai, 2)
      elseif 2 <= difficulty then
        DL.NewGamePlusLevelBoostFlat(ai, 1)
      end
    end
  end
end
function OnAIUpdate(ai)
  traverselink.OnUpdate(ai)
  if Brain_Core:GetDebugTable(ai) then
    local debugTable = {}
    table.insert(debugTable, {
      "Reaction Breaker Meter: ",
      DL.ComboBreakerGetDebugString()
    })
    Brain_Core:AddCustomDebugTable(debugTable)
  end
  if darkEliteNavEvadeUsed then
    if ai:IsPlayingMove("MOV_DefEvadeNav") then
      constants.fightKnowledgeInputs.Zones.Default.Aggressive[1].Constraints[1].Min = 15
      constants.fightKnowledgeInputs.Zones.Default.Aggressive[1].Constraints[1].Max = 20
      constants.fightKnowledgeInputs.Zones.Default.Aggressive[1].Constraints[2].Min = -180
      constants.fightKnowledgeInputs.Zones.Default.Aggressive[1].Constraints[2].Max = 180
    else
      darkEliteNavEvadeUsed = false
      constants.fightKnowledgeInputs.Zones.Default.Aggressive[1].Constraints[1].Min = 6
      constants.fightKnowledgeInputs.Zones.Default.Aggressive[1].Constraints[1].Max = 10
      constants.fightKnowledgeInputs.Zones.Default.Aggressive[1].Constraints[2].Min = -60
      constants.fightKnowledgeInputs.Zones.Default.Aggressive[1].Constraints[2].Max = 60
    end
  end
end
function _G.OnAICreateLuaState(ai)
  _G.OnAICreateLuaState = nil
  local positioning = Brain_Core:GetPositioning()
  positioning.AddStandardPositioningZone("Flight", constants.fightPosDataFlight, constants.fightKnowledgeInputs)
end
function Brain_Core:OnUpdateCombat(ai, global, constants, dTreeParams)
  if ai:PickupIsAcquired("DarkOne_FlightState") then
    constants.fightKnowledgeInputs.CurrentZoneSet = "Flight"
    global.navData.startDistance = 3
  else
    constants.fightKnowledgeInputs.CurrentZoneSet = "Default"
    global.navData.startDistance = 1
  end
end
function Brain_Core:OnHitReaction(event, ai, global, constants)
  if ai:IsAxeEmbedded() then
    timer.StartCreatureTimer(0.25, function()
      if ai:HasMarker("REACT_FROZEN") == false then
        game.Player.FindPlayer():DropThrowable("ATT_Axe")
      end
    end)
  end
  if event.enemyId == DL.HashCreatureID(ai, "HERO") then
    local comboBreakerDamageThreshold = 60
    local damage = event.damage
    if damage < 8 then
      damage = 8
    end
    local breakThisFrame = DL.ComboBreakerCheck(ai, damage, comboBreakerDamageThreshold, 1, nil)
    if breakThisFrame and ai:HasMarker("DarkOneKingStun") == false and ai:HasMarker("ReactionBreakerReady") == false then
      ai:AddMarker("ReactionBreakerReady")
    end
  end
end
picklelib.Install()
function Pickle(GO)
  return {
    global = global
  }
end
function Unpickle(GO, t)
  global = t.global
end
