local DL = require("design.DesignerLibrary")
local timer = require("creature.timer")
function LuaHook_EmissivesOn(ai, data)
  ai:SetEmissiveScale(1)
  timer.StartCreatureTimer(0.1, function()
    for activeWeapon in ai:IterateActiveWeapons() do
      local gameObj = activeWeapon.Weapon
      if gameObj ~= nil then
        gameObj:SetEmissiveScale(1)
      end
    end
  end)
end
function LuaHook_EmissivesOff(ai, data)
  ai:SetEmissiveScale(0)
  timer.StartCreatureTimer(0.1, function()
    for activeWeapon in ai:IterateActiveWeapons() do
      local gameObj = activeWeapon.Weapon
      if gameObj ~= nil then
        gameObj:SetEmissiveScale(0)
      end
    end
  end)
end
function LuaHookDecision_IsPlayerTarget(ai, data)
  local player = game.Player.FindPlayer()
  local playerTarget = player:GetTargetCreature()
  if playerTarget == ai then
    return data:FindOutcomeBranchesEntry("True")
  else
    return data:FindOutcomeBranchesEntry("False")
  end
end
local Shared_LedgeCheck = function(ai, data, goingForward)
  local jointIndex = ai:GetJointIndex("zeroJoint")
  local zeroJointFacingFwd = ai:GetWorldJointForward(jointIndex)
  if goingForward == false then
    zeroJointFacingFwd = zeroJointFacingFwd * -1
  end
  local startPos = ai.WorldPosition + engine.Vector.New(0, 0.5, 0)
  local midPos = ai.WorldPosition + zeroJointFacingFwd * -1 + engine.Vector.New(0, 0.5, 0)
  local endPos = ai.WorldPosition + zeroJointFacingFwd * -1 + engine.Vector.New(0, -2, 0)
  local hit = game.World.RaycastCollision(startPos, midPos, {
    SourceGameObject = ai,
    FindAnything = true,
    EntityType = game.CollisionType.New("kEnvironment")
  }, false)
  local hitDown = game.World.RaycastCollision(midPos, endPos, {
    SourceGameObject = ai,
    FindAnything = true,
    EntityType = game.CollisionType.New("kEnvironment")
  }, false)
  if ai:DebugIsSelectedCreature() then
    engine.DrawLine(startPos, midPos, 8388736)
    engine.DrawLine(midPos, endPos, 8388736)
  end
  local ledgeRaycastCount = 0
  if hit == nil and hitDown == nil then
    ledgeRaycastCount = ledgeRaycastCount + 1
  end
  if 0 < ledgeRaycastCount then
    return true
  end
  return false
end
local LuaHook_LedgeCheck = function(ai, data)
  local noFloor = Shared_LedgeCheck(ai, data, true)
  if noFloor then
    return data:FindOutcomeBranchesEntry("no_floor")
  end
end
local LuaHook_LedgeCheckBack = function(ai, data)
  local noFloor = Shared_LedgeCheck(ai, data, false)
  if noFloor then
    return data:FindOutcomeBranchesEntry("no_floor")
  end
end
function LuaHook_SetHealthTo1(ai, data)
  ai:MeterSetValue("Health", 1)
  ai:PickupAcquire("SetHealthTo1")
end
function LuaHook_SuperFlybackWallCheck(ai, data)
  local jointIndex = ai:GetJointIndex("zeroJoint")
  local zeroJointFacingFwd = ai:GetWorldJointForward(jointIndex)
  local zeroJointLeft = ai:GetWorldJointLeft(jointIndex)
  zeroJointFacingFwd = zeroJointFacingFwd * -1
  zeroJointLeft = zeroJointLeft * -1
  local startPos = ai.WorldPosition + engine.Vector.New(0, 1.4, 0)
  local endPos = ai.WorldPosition + zeroJointFacingFwd * 1 + engine.Vector.New(0, 1.4, 0)
  zeroJointLeft = zeroJointLeft * 1
  local hit = game.World.RaycastCollision(startPos, endPos, {SourceGameObject = ai, FindAnything = true})
  local hitLeft = game.World.RaycastCollision(startPos, endPos + zeroJointLeft, {SourceGameObject = ai, FindAnything = true})
  local hitRight = game.World.RaycastCollision(startPos, endPos - zeroJointLeft, {SourceGameObject = ai, FindAnything = true})
  if hit == nil and hitLeft == nil and hitRight == nil then
    return data:FindOutcomeBranchesEntry("Up")
  elseif hitRight == nil and hit == nil then
    return data:FindOutcomeBranchesEntry("Left")
  elseif hitLeft == nil and hit == nil then
    return data:FindOutcomeBranchesEntry("Right")
  else
    return data:FindOutcomeBranchesEntry("Front")
  end
end
function LuaHook_CheckTargetSideAll(ai, data)
  if _G.global.target == nil then
    return data:FindOutcomeBranchesEntry("NoTarget")
  end
  local relativeAngle = DL.GetObjectARelativeAngleToObjectB(_G.global.target, ai)
  if relativeAngle < -135 or 135 < relativeAngle then
    return data:FindOutcomeBranchesEntry("Back")
  elseif -135 < relativeAngle or relativeAngle < -45 then
    return data:FindOutcomeBranchesEntry("Left")
  elseif relativeAngle < 135 or 45 < relativeAngle then
    return data:FindOutcomeBranchesEntry("Right")
  else
    return data:FindOutcomeBranchesEntry("Front")
  end
end
function LuaHook_CheckTargetSideFB(ai, data)
  if _G.global.target == nil then
    return data:FindOutcomeBranchesEntry("NoTarget")
  end
  local relativeAngle = DL.GetObjectARelativeAngleToObjectB(_G.global.target, ai)
  if relativeAngle < -90 or 90 < relativeAngle then
    return data:FindOutcomeBranchesEntry("Back")
  else
    return data:FindOutcomeBranchesEntry("Front")
  end
end
local LuaHookDecision_CheckIfReticleTarget = function(ai, data)
  local retValue = false
  local goPlayerCreature = game.Player.FindPlayer()
  local playerBBoard = goPlayerCreature:GetBlackboard()
  if playerBBoard and ai == playerBBoard:GetObject("ReticleTargetCreature") and playerBBoard:GetBoolean("ReticleTargetCreatureTimeThreshold") and not ai:PickupIsSlotUsed("Frost") and not ai:PickupIsAcquired("TurretMode") then
    retValue = true
  end
  return retValue
end
local LuaHookDecision_CheckIfReticleTargetFast = function(ai, data)
  local retValue = false
  local goPlayerCreature = game.Player.FindPlayer()
  local playerBBoard = goPlayerCreature:GetBlackboard()
  if playerBBoard and ai == playerBBoard:GetObject("ReticleTargetCreature") and playerBBoard:GetBoolean("ReticleTargetCreatureTimeThresholdFast") and not ai:PickupIsSlotUsed("Frost") and not ai:PickupIsAcquired("TurretMode") then
    retValue = true
  end
  return retValue
end
local LuaHookDecision_GetAbsoluteAngleBetweenMyFacingAndTargetFacing = function(creature, data)
  local creatureFacing = creature:GetWorldForward()
  local targetFacing = creature:GetTargetCreature():GetWorldForward()
  local angle = game.AIUtil.AngleBetweenXZ(creatureFacing, targetFacing)
  return angle
end
function LuaHookDecision_CheckEnemiesBeingAttacked(ai, data)
  local retVal = false
  local player = game.Player.FindPlayer()
  if player:GetTargetCreature() ~= nil then
    local playerTarget = player:GetTargetCreature()
    if playerTarget ~= nil and playerTarget:GetTargetCreature() == player and (playerTarget:HasMarker("React") or playerTarget:IsPlayingMove("MOV_DefBlockBreak") or playerTarget:IsPlayingMove("MOV_BlockRecoil") or playerTarget:IsPlayingMove("MOV_BlockRecoil02")) and game.AIUtil.Distance(playerTarget:GetWorldPosition(), player:GetWorldPosition()) < 4 then
      retVal = true
    end
  end
  return retVal
end
local InstallHooks = function()
  _G.LuaHook_LedgeCheck = LuaHook_LedgeCheck
  _G.LuaHook_LedgeCheckBack = LuaHook_LedgeCheckBack
  _G.LuaHookDecision_CheckIfReticleTarget = LuaHookDecision_CheckIfReticleTarget
  _G.LuaHookDecision_CheckIfReticleTargetFast = LuaHookDecision_CheckIfReticleTargetFast
  _G.LuaHookDecision_GetAbsoluteAngleBetweenMyFacingAndTargetFacing = LuaHookDecision_GetAbsoluteAngleBetweenMyFacingAndTargetFacing
end
return {InstallHooks = InstallHooks}
