local statemachine = require("ai.statemachine")
local tablex = require("core.tablex")
local picklelib = require("core.pickle")
local DL = require("design.DesignerLibrary")
local color = require("core.color")
Brain_Core = require("behavior.corebrain")
constants = {}
global = {}
player = nil
son = nil
phase = 1
local hpStunAmountTotal = 0
local hpStunThreshold = 0
function GetMagni(ai)
  local magni
  local creaturesAroundPlayer = player:FindEnemies(30)
  for _, thisCreature in ipairs(creaturesAroundPlayer) do
    if thisCreature ~= ai then
      magni = thisCreature
    end
  end
  return magni
end
function LuaHook_ShieldStrikeSnowBlind()
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 LuaHookDecision_IsBehindPlayer(ai, data)
  local toTarget = (ai:GetWorldPosition() - player:GetWorldPosition()):Normalized()
  local isBehind = false
  if toTarget:Dot(player:GetWorldForward()) < 0.25 then
    isBehind = true
  end
  return isBehind
end
function LuaHookDecision_IsSonStunned(ai, data)
  local retVal = false
  if son:HasMarker("Stunned") == true or son:HasMarker("Son_KnockedDown") == true then
    retVal = true
  end
  return retVal
end
function LuaHookDecision_ModiRevive(ai, data)
  if ai:MeterGetValue("MamoRevive") <= 4 then
    return data:FindOutcomeBranchesEntry("True")
  end
  return data:FindOutcomeBranchesEntry("False")
end
function LuaHook_AxeReject(ai)
  local concussionParams = {}
  concussionParams = {
    Tweak = "CNC_AXE_REJECT",
    WorldLocation = ai:GetWorldPosition(),
    GameObject = ai,
    EnemyId = ai:GetID()
  }
  game.Combat.PlayConcussion(concussionParams)
end
function OnAIPostSpawn(ai)
  player = game.Player.FindPlayer()
  son = game.AI.FindSon()
  global.navData.navSpeedWalk = ai:LookupFloatConstant("NAV_SPEED_WALK")
  global.navData.navSpeedJog = ai:LookupFloatConstant("NAV_SPEED_JOG")
  ai:PickupAcquire("Modi_MFX_Pickup", 0)
  DL.NewGamePlusLevelBoostFlat(ai, 3)
end
function PlayWeaponMaterial(ai, wepName, matAnimName)
  for gameObj in ai:IterateActiveWeapons() do
    if gameObj ~= nil and gameObj.Weapon ~= nil then
      local objWepName = gameObj.Weapon:GetName()
      if objWepName == wepName then
        gameObj.Weapon:StartMaterialAnim(matAnimName)
      end
    end
  end
end
function LuaHook_ClearArrow(ai, data)
  game.Combat.RemoveArrows(ai)
end
function LuaHook_MaceON(ai)
  ai:StartMaterialAnim("rightarmON")
  PlayWeaponMaterial(ai, "modihammer00", "electricityON")
end
function LuaHook_MaceOFF(ai)
  ai:StartMaterialAnim("rightarmOFF")
  PlayWeaponMaterial(ai, "modihammer00", "electricityOFF")
end
function LuaHook_ShieldON(ai)
  ai:StartMaterialAnim("leftarmON")
  PlayWeaponMaterial(ai, "modishield00", "electricityON")
end
function LuaHook_ShieldOFF(ai)
  ai:StartMaterialAnim("leftarmOFF")
  PlayWeaponMaterial(ai, "modishield00", "electricityOFF")
end
function LuaHook_TargetSon()
  if global.targetParams ~= "FIND_TARGET_PARAMETERS_COMBAT_SON_ONLY" then
    global.targetParams = "FIND_TARGET_PARAMETERS_COMBAT_SON_ONLY"
  end
end
function LuaHook_TargetKratos()
  if global.targetParams ~= "FIND_TARGET_PARAMETERS_COMBAT_KRATOS_ONLY" then
    global.targetParams = "FIND_TARGET_PARAMETERS_COMBAT_KRATOS_ONLY"
  end
end
function LuaHook_TargetBro()
  if global.targetParams ~= "FIND_TARGET_PARAMETERS_COMBAT_BRO_ONLY" then
    global.targetParams = "FIND_TARGET_PARAMETERS_COMBAT_BRO_ONLY"
  end
end
function LuaHook_ForceBroRun(ai)
  local magni = GetMagni(ai)
  if son:HasMarker("Stunned") == false or magni ~= nil and magni:HasMarker("StageTransition") then
    ai:TriggerMoveEvent("LE_BroRun")
  end
end
function LuaHook_ForceTagTeam(ai)
  local magni = GetMagni(ai)
  if son:HasMarker("Stunned") == false or magni ~= nil and magni:HasMarker("StageTransition") then
    ai:TriggerMoveEvent("LE_TagTeam")
  end
end
local wat = false
local breathEffect
function OnAIUpdate(ai)
  if breathEffect == nil then
    breathEffect = game.FX.Spawn("FX_kratos_Breath", nil, {
      Joint = "JOJaw1",
      GameObject = ai,
      DeleteWithCreature = true
    })
    breathEffect:SetAnimFloatChannelDriver(player, "sliderfloatchannels._breathfxintensity")
  end
  if ai:PickupIsAcquired("MagniSnowBlind") or ai:PickupIsAcquired("ModiSnowBlind") then
    LuaHook_TargetKratos()
  else
    if son:HasMarker("CommandShot") and player:IsPlayingMove("MOV_CSMagniGrabLoop") == false and player:IsPlayingMove("MOV_CSMagniGrabEnter") == false and ai:MeterGetValue("SonGrab") < 100 and ai:IsPlayingMove("MOV_SonCommandArrowResponse") == false then
      ai:TriggerMoveEvent("LE_SonCommandArrowResponse")
    end
    if ai:IsPlayingMove("MOV_csShieldRush") or ai:IsPlayingMove("MOV_csShieldJump") or ai:IsPlayingMove("MOV_csShieldJumpL") then
      LuaHook_TargetKratos()
    end
    if ai:HasMarker("TargetBro") then
      LuaHook_TargetBro()
    end
  end
end
function Brain_Core:OnHitReaction(event, ai, global, constants)
  local diff = ai:MeterGetValue("Health") - hpStunThreshold
  if diff < 0 then
    diff = 0
  end
  local progressToStun = diff / hpStunAmountTotal
  local stunVal = 100 - progressToStun * 100
  if 98 < stunVal then
    stunVal = 98
  end
  if stunVal > ai:MeterGetValue("MamoRevive") then
    ai:MeterSetValue("MamoRevive", stunVal)
  end
end
function _G.OnAICreateLuaState(ai)
  local positioning = Brain_Core:GetPositioning()
  positioning.AddStandardPositioningZone("Far", constants.fightPosDataFar, constants.fightKnowledgeInputs)
  positioning.AddStandardPositioningZone("SonTarget", constants.fightPosDataSonTarget, constants.fightKnowledgeInputs)
  _G.OnAICreateLuaState = nil
end
function LuaHook_JasonTargetSon(ai)
  ai:CallScript("OnForceTempAggro", 6)
end
function LuaHookDecision_GrabSon(ai, data)
  local retVal = false
  local magni = GetMagni(ai)
  if ai:MeterGetValue("SonGrab") >= 100 and player:HasMarker("MagniGrab") == false and phase >= 2 and magni ~= nil and magni:HasMarker("MagniGrab") == false and magni:HasMarker("StageTransition") == false then
    retVal = true
  end
  return retVal
end
function LuaHook_ReviveSelf(ai)
  ai:MeterSetValue("MamoRevive", 0)
  local difficulty = ai:AttributeGetValue("Difficulty")
  if difficulty == 1 then
    HealSelf(ai, 30)
  elseif difficulty == 2 then
    HealSelf(ai, 50)
  elseif difficulty == 3 then
    HealSelf(ai, 100)
  elseif difficulty == 4 then
    HealSelf(ai, 150)
  end
end
function HealSelf(ai, healAmount)
  hpStunAmountTotal = ai:MeterGetValue("Health") + healAmount - hpStunThreshold
  ai:MeterSetValue("Health", ai:MeterGetValue("Health") + healAmount)
end
function LuaHook_SetHpStunThreshold(ai)
  hpStunAmountTotal = ai:MeterGetValue("Health") - hpStunThreshold
end
function SetPhase(ai, phaseNum, newThreshold)
  phase = phaseNum
  hpStunThreshold = newThreshold
  LuaHook_SetHpStunThreshold(ai)
  if phase == 1 then
    if ai:HasMarker("PhaseOne") == false then
      ai:AddMarker("PhaseOne")
    end
    if ai:HasMarker("PhaseTwo") == true then
      ai:RemoveMarker("PhaseTwo")
    end
    if ai:HasMarker("PhaseThree") == true then
      ai:RemoveMarker("PhaseThree")
    end
  elseif phase == 2 then
    if ai:HasMarker("PhaseTwo") == false then
      ai:AddMarker("PhaseTwo")
    end
    if ai:HasMarker("PhaseOne") == true then
      ai:RemoveMarker("PhaseOne")
    end
    if ai:HasMarker("PhaseThree") == true then
      ai:RemoveMarker("PhaseThree")
    end
  elseif phase == 3 then
    if ai:HasMarker("PhaseThree") == false then
      ai:AddMarker("PhaseThree")
    end
    if ai:HasMarker("PhaseOne") == true then
      ai:RemoveMarker("PhaseOne")
    end
    if ai:HasMarker("PhaseTwo") == true then
      ai:RemoveMarker("PhaseTwo")
    end
  end
end
function SetSnowblindMode(ai, snowblindMode)
  if snowblindMode then
    global.aggroState = "INCOMBAT"
    global.target = player
    if ai:PickupIsAcquired("ModiSnowBlind") == false then
      ai:PickupAcquire("ModiSnowBlind")
    end
  else
    global.aggroState = "INCOMBAT"
    global.target = nil
    if ai:PickupIsAcquired("ModiSnowBlind") then
      ai:PickupRelinquish("ModiSnowBlind")
    end
  end
end
function LuaHook_WarpClosest(ai, data)
  local currentLevel = ai.Level
  currentLevel:CallScript("WarpBossClosest", ai)
end
function LuaHook_CheckCanReact(ai)
  if ai:MeterGetValue("CD_ComboBreaker") >= 99 then
    return false
  else
    return true
  end
end
function Brain_Core:OnUpdateCombat(ai, global, constants, dTreeParams)
  if LuaHookDecision_IsSonStunned(ai, nil) then
    if ai:PickupIsAcquired("MamoNoRetarget") and ai:PickupGetStage("MamoNoRetarget") == 0 then
      ai:PickupRelinquish("MamoNoRetarget")
    end
    if ai:PickupIsAcquired("MamoNoRetarget") == false and ai:GetTargetCreature() == game.Player.FindPlayer() then
      ai:PickupAcquire("MamoNoRetarget")
      ai:PickupSetStage("MamoNoRetarget", 1)
    end
  end
  local currentTarget = ai:GetTargetCreature()
  if currentTarget == game.Player.FindPlayer() and _G.global.targetParams == "FIND_TARGET_PARAMETERS_COMBAT_KRATOS_ONLY" then
    if ai:PickupIsAcquired("ModiNavigateFar") then
      constants.fightKnowledgeInputs.CurrentZoneSet = "Far"
    else
      constants.fightKnowledgeInputs.CurrentZoneSet = "Default"
    end
  else
    constants.fightKnowledgeInputs.CurrentZoneSet = "SonTarget"
  end
end
picklelib.Install()
function Pickle(GO)
  return {
    global = global
  }
end
function Unpickle(GO, t)
  global = t.global
end
