local DL = require("design.DesignerLibrary")
function LuaHook_CombatPlantTurnBranches(ai, branch)
  local locomotionInfo = ai:GetLocomotionInfo()
  local pathAngle = locomotionInfo.PathAngle
  if pathAngle == nil or not ai:CheckDecision("tweak_Decision_OnCamera") then
    return
  end
  if pathAngle < -60 and -120 < pathAngle then
    return branch:FindOutcomeBranchesEntry("MOV_CombatRunPlantTurn90L")
  end
  if pathAngle < 120 and 60 <= pathAngle then
    return branch:FindOutcomeBranchesEntry("MOV_CombatRunPlantTurn90R")
  end
  if pathAngle <= -120 and -180 <= pathAngle then
    return branch:FindOutcomeBranchesEntry("MOV_CombatRunPlantTurn180L")
  end
  if pathAngle <= 180 and 120 <= pathAngle then
    return branch:FindOutcomeBranchesEntry("MOV_CombatRunPlantTurn180R")
  end
end
function LuaHook_WalkPlantTurnBranches(ai, branch)
  local locomotionInfo = ai:GetLocomotionInfo()
  local pathAngle = locomotionInfo.PathAngle
  local rightFootPhase = locomotionInfo.RightFootPhase
  local leftFootPhase = locomotionInfo.LeftFootPhase
  if pathAngle == nil then
    return
  end
  if pathAngle < -60 and -120 < pathAngle then
    if 0.9 <= rightFootPhase and 0.06875 <= leftFootPhase and leftFootPhase < 0.51 then
      return branch:FindOutcomeBranchesEntry("MOV_WalkPlantTurn90L_RightFoot")
    elseif 0.09 < rightFootPhase and rightFootPhase <= 0.32 and 0.9 < leftFootPhase then
      return branch:FindOutcomeBranchesEntry("MOV_WalkPlantTurn90L_LeftFoot")
    end
  end
  if pathAngle < 120 and 60 <= pathAngle then
    if 0.9 < rightFootPhase and 0.06875 <= leftFootPhase and leftFootPhase < 0.51 then
      return branch:FindOutcomeBranchesEntry("MOV_WalkPlantTurn90R_RightFoot")
    elseif 0.09 < rightFootPhase and rightFootPhase <= 0.32 and 0.9 < leftFootPhase then
      return branch:FindOutcomeBranchesEntry("MOV_WalkPlantTurn90R_LeftFoot")
    end
  end
  if pathAngle <= -120 and -180 <= pathAngle then
    if 0.9 < rightFootPhase and 0.06875 <= leftFootPhase and leftFootPhase < 0.51 then
      return branch:FindOutcomeBranchesEntry("MOV_WalkPlantTurn180L_RightFoot")
    elseif 0.09 < rightFootPhase and rightFootPhase <= 0.32 and 0.9 < leftFootPhase then
      return branch:FindOutcomeBranchesEntry("MOV_WalkPlantTurn180L_LeftFoot")
    end
  end
  if pathAngle <= 180 and 120 <= pathAngle then
    if 0.9 < rightFootPhase and 0.06875 <= leftFootPhase and leftFootPhase < 0.51 then
      return branch:FindOutcomeBranchesEntry("MOV_WalkPlantTurn180R_RightFoot")
    elseif 0.09 < rightFootPhase and rightFootPhase <= 0.32 and 0.9 < leftFootPhase then
      return branch:FindOutcomeBranchesEntry("MOV_WalkPlantTurn180R_LeftFoot")
    end
  end
end
function LuaHook_PlantTurnBranches(ai, branch)
  local locomotionInfo = ai:GetLocomotionInfo()
  local targetSpeed = locomotionInfo.TargetSpeed
  local pathAngle = locomotionInfo.PathAngle
  local velocity = ai:GetVelocity()
  local speed = velocity:Length()
  local runStartSpeed = 1.75
  local runPlantSpeed = 2.8
  local runPlant = runPlantSpeed <= math.min(speed, targetSpeed)
  local runStart = speed < runStartSpeed and targetSpeed >= runPlantSpeed
  if pathAngle == nil then
    return
  end
  if runStart then
    if pathAngle <= -60 then
      return branch:FindOutcomeBranchesEntry("MOV_RunStartTurn120L")
    end
    if 60 <= pathAngle then
      return branch:FindOutcomeBranchesEntry("MOV_RunStartTurn120R")
    end
  end
  if pathAngle <= -60 and -120 < pathAngle then
    if runPlant then
      return branch:FindOutcomeBranchesEntry("MOV_RunPlantTurn90L")
    else
      return branch:FindOutcomeBranchesEntry("MOV_Run_NoAiming")
    end
  end
  if pathAngle < 120 and 60 <= pathAngle then
    if runPlant then
      return branch:FindOutcomeBranchesEntry("MOV_RunPlantTurn90R")
    else
      return branch:FindOutcomeBranchesEntry("MOV_Run_NoAiming")
    end
  end
  if pathAngle <= -120 and -180 <= pathAngle then
    if runPlant then
      return branch:FindOutcomeBranchesEntry("MOV_RunPlantTurn180L")
    else
      return branch:FindOutcomeBranchesEntry("MOV_Run_NoAiming")
    end
  end
  if pathAngle <= 180 and 120 <= pathAngle then
    if runPlant then
      return branch:FindOutcomeBranchesEntry("MOV_RunPlantTurn180R")
    else
      return branch:FindOutcomeBranchesEntry("MOV_Run_NoAiming")
    end
  end
end
function LuaHook_ShouldDoPostUpNav(ai, branch)
  if ai.OwnedPOI and ai:IsContextBehaviorNameEqualTo("POST_UP_BEHAVIOR_CONTEXT_CONFIG") then
    return branch:FindOutcomeBranchesEntry("PostUpNav")
  end
end
function LuaHook_RunOnlyToPlantTurnBranches(ai, branch)
  local locomotionInfo = ai:GetLocomotionInfo()
  local pathAngle = locomotionInfo.PathAngle
  if pathAngle == nil then
    return
  end
  if pathAngle <= -60 and -120 < pathAngle then
    return branch:FindOutcomeBranchesEntry("MOV_RunPlantTurn90L")
  end
  if pathAngle < 120 and 60 <= pathAngle then
    return branch:FindOutcomeBranchesEntry("MOV_RunPlantTurn90R")
  end
  if pathAngle <= -120 and -180 <= pathAngle then
    return branch:FindOutcomeBranchesEntry("MOV_RunPlantTurn180L")
  end
  if pathAngle <= 180 and 120 <= pathAngle then
    return branch:FindOutcomeBranchesEntry("MOV_RunPlantTurn180R")
  end
end
function LuaHook_CheckForEarlyContextActionEnterBranch(ai, branch)
  if not ai.OwnedPOI or ai.OwnedPOI:FindLuaTableAttribute("EarlyStopTransitionPercent") == nil then
    return
  end
  local movePercentage = ai:GetActiveMovePercent()
  local nessecaryPercentage = ai.OwnedPOI:FindLuaTableAttribute("EarlyStopTransitionPercent") * 0.01
  if movePercentage >= nessecaryPercentage then
    ai.OwnedPOI:SendEvent("ContextActionEarlyStopExit")
  end
end
function LuaHook_StartBranches(ai, branch)
  local locomotionInfo = ai:GetLocomotionInfo()
  local targetSpeed = locomotionInfo.TargetSpeed
  local pathAngle = locomotionInfo.PathAngle
  if pathAngle == nil or targetSpeed <= 0.1 then
    return
  end
  local speedType = "Walk"
  if 3.5 <= targetSpeed and locomotionInfo.PathLength > 2 then
    speedType = "Run"
  end
  if speedType == "Walk" and ai.OwnedPOI and ai:IsContextBehaviorNameEqualTo("POST_UP_BEHAVIOR_CONTEXT_CONFIG") then
    return branch:FindOutcomeBranchesEntry("MOV_PostUpWalkStart")
  end
  if -60 < pathAngle and pathAngle < 60 then
    return branch:FindOutcomeBranchesEntry("MOV_" .. speedType .. "StartTurn0")
  end
  if pathAngle <= -60 then
    return branch:FindOutcomeBranchesEntry("MOV_" .. speedType .. "StartTurn120L")
  end
  if 60 <= pathAngle then
    return branch:FindOutcomeBranchesEntry("MOV_" .. speedType .. "StartTurn120R")
  end
end
function LuaHook_ContextBehaviorExitBranches(ai, branch)
  if _G.global.markContextBehaviorForDelete then
    ai:CallScript("DestroyQueuedContextBehavior", ai)
    return branch:FindOutcomeBranchesEntry("MOV_ContextBehaviorExit")
  else
    local locomotionInfo = ai:GetLocomotionInfo()
    local targetSpeed = locomotionInfo.TargetSpeed
    local pathAngle = locomotionInfo.PathAngle
    if pathAngle == nil or targetSpeed <= 0.1 then
      return
    end
    return branch:FindOutcomeBranchesEntry("MOV_ContextBehaviorExit")
  end
end
function LuaHook_WalkStartToStartBranches(ai, branch)
  local locomotionInfo = ai:GetLocomotionInfo()
  local targetSpeed = locomotionInfo.TargetSpeed
  local pathAngle = locomotionInfo.PathAngle
  if pathAngle == nil or targetSpeed < 3 then
    return
  end
  if -60 < pathAngle and pathAngle < 60 then
    return branch:FindOutcomeBranchesEntry("MOV_RunStartTurn0")
  end
  if pathAngle <= -60 then
    return branch:FindOutcomeBranchesEntry("MOV_RunStartTurn120L")
  end
  if 60 <= pathAngle then
    return branch:FindOutcomeBranchesEntry("MOV_RunStartTurn120R")
  end
end
function LuaHook_WalkStartToPlantBranches(ai, branch)
  local locomotionInfo = ai:GetLocomotionInfo()
  local targetSpeed = locomotionInfo.TargetSpeed
  local pathAngle = locomotionInfo.PathAngle
  if pathAngle == nil or 3 <= targetSpeed then
    return
  end
  if pathAngle <= -60 and -120 < pathAngle then
    return branch:FindOutcomeBranchesEntry("MOV_Run_NoAiming")
  end
  if pathAngle < 120 and 60 <= pathAngle then
    return branch:FindOutcomeBranchesEntry("MOV_Run_NoAiming")
  end
  if pathAngle <= -120 and -180 <= pathAngle then
    return branch:FindOutcomeBranchesEntry("MOV_Run_NoAiming")
  end
  if pathAngle <= 180 and 120 <= pathAngle then
    return branch:FindOutcomeBranchesEntry("MOV_Run_NoAiming")
  end
end
function LuaHook_CombatStartBranches(ai, branch)
  local locomotionInfo = ai:GetLocomotionInfo()
  local targetSpeed = locomotionInfo.TargetSpeed
  local pathAngle = locomotionInfo.PathAngle
  if pathAngle == nil then
    return
  end
  if ai.OwnedPOI ~= nil and ai.OwnedPOI.Type == "ContextAction" and locomotionInfo.IsCloseRangeApproach and locomotionInfo.PathLength < 1 and (ai.OwnedPOI:FindLuaTableAttribute("SonAttackType") == "CommandShot" or ai.OwnedPOI:FindLuaTableAttribute("SonAttackType") == "Both") then
    return
  end
  if not ai:CheckDecision("tweak_Decision_OnCamera") and (not ai.OwnedPOI or not ai.OwnedPOI:FindLuaTableAttribute("AvailableDuringCombat")) then
    return branch:FindOutcomeBranchesEntry("MOV_CombatRun")
  end
  if 0.1 <= targetSpeed then
    if -60 < pathAngle and pathAngle < 60 then
      return branch:FindOutcomeBranchesEntry("MOV_CombatRunStartTurn0")
    end
    if pathAngle <= -60 then
      return branch:FindOutcomeBranchesEntry("MOV_CombatRunStartTurn120L")
    end
    if 60 <= pathAngle then
      return branch:FindOutcomeBranchesEntry("MOV_CombatRunStartTurn120R")
    end
  end
end
function LuaHook_NavStop(ai, branch)
  local locomotionInfo = ai:GetLocomotionInfo()
  if locomotionInfo.TargetSpeed > 0 then
    return nil
  end
  local velocity = ai:GetVelocity()
  local speed = velocity:Length()
  local angle
  angle = locomotionInfo.FocusAngle or ai:GetWorldForward()
  local walkStopSpeed = 2
  local runStopSpeed = 4.5
  local rightfoot, returnMove
  local shouldUseWarping = ai.OwnedPOI and not ai.OwnedPOI:FindLuaTableAttribute("IgnoreTranslation") and (not game.AI.IsAIIdleActive or not game.AI.IsAIIdleActive())
  if _G.constants and _G.constants.splineNav then
    shouldUseWarping = false
  end
  if ai.OwnedPOI and ai:IsContextBehaviorNameEqualTo("POST_UP_BEHAVIOR_CONTEXT_CONFIG") then
    return branch:FindOutcomeBranchesEntry("MOV_PostUpWalkStop")
  end
  if speed <= walkStopSpeed then
    local stopnow = false
    if locomotionInfo.RightFootPhase > 0.17 and locomotionInfo.RightFootPhase < 0.3 then
      rightfoot = false
      stopnow = true
    elseif 0.17 < locomotionInfo.LeftFootPhase and 0.3 > locomotionInfo.LeftFootPhase then
      rightfoot = true
      stopnow = true
    elseif ai.OwnedPOI and ai:IsContextBehaviorNameEqualTo("POST_UP_BEHAVIOR_CONTEXT_CONFIG") then
      stopnow = true
    end
    if stopnow then
      if angle < -60 then
        if rightfoot then
          returnMove = "MOV_WalkStopTurn120L_RightFoot"
        else
          returnMove = "MOV_WalkStopTurn120L_LeftFoot"
        end
      elseif 60 < angle then
        if rightfoot then
          returnMove = "MOV_WalkStopTurn120R_RightFoot"
        else
          returnMove = "MOV_WalkStopTurn120R_LeftFoot"
        end
      elseif rightfoot then
        returnMove = "MOV_WalkStopTurn0_RightFoot"
      else
        returnMove = "MOV_WalkStopTurn0_LeftFoot"
      end
    end
  elseif speed <= runStopSpeed or shouldUseWarping then
    if angle < -60 then
      returnMove = "MOV_RunStopTurn120L"
    elseif 60 < angle then
      returnMove = "MOV_RunStopTurn120R"
    else
      returnMove = "MOV_RunStopTurn0"
    end
  else
    returnMove = "MOV_SprintStop"
  end
  if returnMove ~= nil then
    if shouldUseWarping then
      returnMove = returnMove .. "Warp"
    end
    return branch:FindOutcomeBranchesEntry(returnMove)
  end
end
function LuaHook_IdleTurn(ai, branch)
  local locomotionInfo = ai:GetLocomotionInfo()
  local focusAngle = locomotionInfo.FocusAngle
  if locomotionInfo.TargetSpeed == 0 and ai.OwnedPOI ~= nil and locomotionInfo.IsCloseRangeApproach then
    if focusAngle == 0 or -30 < focusAngle and focusAngle < 30 then
      return branch:FindOutcomeBranchesEntry("MOV_IdlePOI")
    end
    if 60 < focusAngle then
      return branch:FindOutcomeBranchesEntry("MOV_IdleTurn120RWarp")
    elseif focusAngle < -60 then
      return branch:FindOutcomeBranchesEntry("MOV_IdleTurn120LWarp")
    elseif -60 <= focusAngle and focusAngle <= 60 then
      return branch:FindOutcomeBranchesEntry("MOV_IdleTurn0Warp")
    end
  end
  if _G.constants.focusDuration ~= nil and 0 < _G.constants.focusDuration and ai.OwnedPOI == nil then
    if focusAngle == 0 or -35 < focusAngle and focusAngle < 35 then
      return
    end
    if 70 < focusAngle then
      return branch:FindOutcomeBranchesEntry("MOV_IdleTurn120R")
    elseif focusAngle < -70 then
      return branch:FindOutcomeBranchesEntry("MOV_IdleTurn120L")
    elseif -70 <= focusAngle and focusAngle <= 70 then
      return branch:FindOutcomeBranchesEntry("MOV_IdleTurn0")
    end
  end
end
function LuaHook_CombatIdleTurn(ai, branch)
  if _G.global.combatTarget ~= nil and (ai.OwnedPOI == nil or ai.OwnedPOI and ai.OwnedPOI:FindLuaTableAttribute("AvailableDuringCombat")) then
    local locomotionInfo = ai:GetLocomotionInfo()
    local focusAngle = locomotionInfo.FocusAngle
    if -90 <= focusAngle and focusAngle <= -40 then
      return branch:FindOutcomeBranchesEntry("MOV_CombatIdleTurn90L")
    elseif 40 < focusAngle and focusAngle <= 90 then
      return branch:FindOutcomeBranchesEntry("MOV_CombatIdleTurn90R")
    elseif focusAngle < -90 and -180 <= focusAngle then
      return branch:FindOutcomeBranchesEntry("MOV_CombatIdleTurn180L")
    elseif focusAngle < 180 and 90 < focusAngle then
      return branch:FindOutcomeBranchesEntry("MOV_CombatIdleTurn180R")
    end
  end
  return branch:FindOutcomeBranchesEntry("MOV_IDLE")
end
function LuaHook_CombatNavStop(ai, branch)
  local locomotionInfo = ai:GetLocomotionInfo()
  if locomotionInfo.TargetSpeed > 0 then
    return nil
  end
  local angle
  local target = ai:GetTargetCreature()
  if ai.OwnedPOI ~= nil then
    angle = DL.GetAngleBetweenVector(ai:GetWorldForward(), DL.ReturnFacing(ai.OwnedPOI))
  elseif target ~= nil then
    angle = DL.FrontAngle(ai, target)
  else
    angle = 0
  end
  if _G.constants.InSurvivalDriver.Value ~= 0 then
    return branch:FindOutcomeBranchesEntry("MOV_CombatSurvivalRepositionStop")
  end
  if angle < -60 then
    return branch:FindOutcomeBranchesEntry("MOV_CombatRunStopTurn120L")
  elseif 60 < angle then
    return branch:FindOutcomeBranchesEntry("MOV_CombatRunStopTurn120R")
  else
    return branch:FindOutcomeBranchesEntry("MOV_CombatRunStopTurn0")
  end
end
function LuaHook_CombatForceStop(ai, branch)
  local locomotionInfo = ai:GetLocomotionInfo()
  if locomotionInfo.TargetSpeed > 0 then
    return nil
  end
  local angle = 0
  local target = ai:GetTargetCreature()
  if target then
    angle = DL.FrontAngle(ai, target)
  end
  if angle < -60 then
    return branch:FindOutcomeBranchesEntry("MOV_CombatRunStopTurn120L")
  elseif 60 < angle then
    return branch:FindOutcomeBranchesEntry("MOV_CombatRunStopTurn120R")
  else
    return branch:FindOutcomeBranchesEntry("MOV_CombatRunStopTurn0")
  end
end
local Install = function()
end
return {Install = Install}
