local statemachine = require("ai.statemachine")
local DL = require("design.DesignerLibrary")
LD = require("design.LevelDesignLibrary")
local timer = require("creature.timer")
local picklelib = require("core.pickle")
local globalLuaHooks = require("design.GlobalLuaHooks")
local color = require("core.color")
globalLuaHooks.InstallHooks()
attachments = {}
constants = {}
global = {}
global.currentPOI = {}
global.aggroState = ""
local isHeadDamageFocusOn = false
local IsMarkTurnOffDTREE = false
local Peak550, dragonGurglingDelay, dragonMouthEmitter
function pickSpawnMove(ai)
  local spawnContext = ai:GetContext()
  if DL.CheckCreatureContext(spawnContext, "INCOMBAT") then
    global.aggroState = "INCOMBAT"
  elseif DL.CheckCreatureContext(spawnContext, "PREAGGRO") then
    global.aggroState = "PREAGGRO"
  elseif DL.CheckCreatureContext(spawnContext, "UNAWARE") then
    global.aggroState = "UNAWARE"
  end
end
function DrawTriangleFromCreature(thisCreature, angle, length, color, debugOffsetVector)
  if not engine.IsDebug() then
    return
  end
  local x1, z1, x2, z2
  local thisCreatureDir = thisCreature:GetWorldForward()
  local hyp = length
  if debugOffsetVector == nil then
    debugOffsetVector = engine.Vector.New(0, 0.1, 0)
  end
  x1 = thisCreatureDir.x * math.cos(math.rad(angle)) - thisCreatureDir.z * math.sin(math.rad(angle))
  z1 = thisCreatureDir.x * math.sin(math.rad(angle)) + thisCreatureDir.z * math.cos(math.rad(angle))
  x2 = thisCreatureDir.x * math.cos(math.rad(-angle)) - thisCreatureDir.z * math.sin(math.rad(-angle))
  z2 = thisCreatureDir.x * math.sin(math.rad(-angle)) + thisCreatureDir.z * math.cos(math.rad(-angle))
  local vec1 = engine.Vector.New(x1, 0, z1):Normalized() * hyp + debugOffsetVector
  local vec2 = engine.Vector.New(x2, 0, z2):Normalized() * hyp + debugOffsetVector
  local vec3 = thisCreatureDir:Normalized() * hyp + debugOffsetVector
  engine.DrawLine(thisCreature.WorldPosition + debugOffsetVector, thisCreature.WorldPosition + vec1, color)
  engine.DrawLine(thisCreature.WorldPosition + debugOffsetVector, thisCreature.WorldPosition + vec2, color)
  engine.DrawLine(thisCreature.WorldPosition + vec3, thisCreature.WorldPosition + vec2, color)
  engine.DrawLine(thisCreature.WorldPosition + vec3, thisCreature.WorldPosition + vec1, color)
end
function IsTargetInRangeCheck(thisCreature, maxAngle, minDistance, maxDistance, color)
  local l_target = thisCreature:GetTargetCreature()
  if l_target == nil then
    return false
  end
  local l_angleToTarget = GetAngleToTarget(thisCreature, l_target)
  local vecToTarget = l_target:GetWorldPosition() - thisCreature:GetWorldPosition()
  local distToTarget = vecToTarget:Length()
  local debugOffsetVector = engine.Vector.New(0, 1.5, 0)
  if minDistance <= distToTarget and maxDistance >= distToTarget and maxAngle >= l_angleToTarget then
    return true
  end
  return false
end
function GetDirectionToTarget(ai)
  local ai_pos = ai:GetWorldPosition()
  local l_target = ai:GetTargetCreature()
  local target_pos = l_target:GetWorldPosition()
  local dir = target_pos - ai_pos
  return dir:Normalized()
end
function GetAngleToTarget(ai, target)
  local l_target = target
  local forward_vector = ai:GetWorldForward()
  local dot = forward_vector:Dot(GetDirectionToTarget(ai))
  local degree = math.acos(dot)
  degree = math.deg(degree)
  return degree
end
function IsTargetOnLeft(ai)
  local left_vector = ai:GetWorldLeft()
  local dot = left_vector:Dot(GetDirectionToTarget(ai))
  if 0 < dot then
    return true
  end
  return false
end
function OnAIPostSpawn(ai, global)
  ai:HideJoint(ai:GetJointIndex("JORakeCollision"))
  ai:StartMaterialAnim("energyIdle")
  local hasPickup = ai:PickupIsAcquired("EarthDragon_AttributeStats")
  if hasPickup ~= nil then
    if hasPickup == false then
      ai:PickupAcquire("EarthDragon_AttributeStats")
    end
    ai:PickupSetStage("EarthDragon_AttributeStats", 1)
  end
  InitializeAudioEmitters(ai)
  DL.NewGamePlusLevelBoostFlat(ai, 3)
end
earthdragon_states = {
  require("EarthDragon00.brain")
}
function OnAIUpdate(ai)
  statemachine.UpdateAll(earthdragon_states, ai, global, constants)
end
function _G.OnAICreateLuaState(ai)
  statemachine.StartAll(ai, earthdragon_states, ai, global, constants)
  _G.OnAICreateLuaState = nil
end
function LuaHook_DragonFireMode_GroundPlume_Center(ai)
  local l_player = game.Player.FindPlayer()
  local targetPosition = l_player:GetWorldPosition()
  local targetForward = l_player:GetWorldForward()
  local targetLeft = l_player:GetWorldLeft()
  local distanceFrontOfTarget = 2
  local distanceLeftOfTarget = 0
  local targetLocation = targetPosition + targetForward * distanceFrontOfTarget
  local arrowData = {}
  engine.DrawFillSphere(targetPosition, 0.25, 65280, 3)
  engine.DrawFillSphere(targetLocation, 0.25, 16711680, 3)
  local concussionParams = {
    Tweak = "CNC_EARTHDRAGON_FIREMODE_GROUND_TELL",
    WorldLocation = targetLocation,
    GameObject = ai,
    EnemyId = ai:GetID()
  }
  game.Combat.PlayConcussion(concussionParams)
end
function LuaHook_Peak550_MortarLob_PatternLABTEST(ai)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_Peak550_MortarLob_PatternLABTEST")
end
function LuaHook_Peak550_MortarLob_GroupA(ai)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_Peak550_MortarLob_GroupA")
end
function LuaHook_Peak550_MortarLob_GroupB(ai)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_Peak550_MortarLob_GroupB")
end
function LuaHook_Peak550_MortarLob_GroupC(ai)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_Peak550_MortarLob_GroupC")
end
function LuaHook_Peak550_MortarLob_GroupAll(ai)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_Peak550_MortarLob_GroupAll")
end
function LuaHook_Peak550_MortarLob_PatternPos01_Wave(ai)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_Peak550_MortarLob_PatternPos01_Wave")
end
function LuaHook_Peak550_MortarLob_PatternPos02_Wave(ai)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_Peak550_MortarLob_PatternPos02_Wave")
end
function LuaHook_Peak550_MortarLob_PatternPos03_Wave(ai)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_Peak550_MortarLob_PatternPos03_Wave")
end
function LuaHook_Peak550_MortarLob_PatternPos01_Gaps(ai)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_Peak550_MortarLob_PatternPos01_Gaps")
end
function LuaHook_Peak550_MortarLob_PatternPos02_Gaps(ai)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_Peak550_MortarLob_PatternPos02_Gaps")
end
function LuaHook_Peak550_MortarLob_PatternPos03_Gaps(ai)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_Peak550_MortarLob_PatternPos03_Gaps")
end
function LuaHook_Peak550_MortarLob_PatternPos01_OutterRim(ai)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_Peak550_MortarLob_PatternPos01_OutterRim")
end
function LuaHook_Peak550_MortarLob_PatternPos02_OutterRim(ai)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_Peak550_MortarLob_PatternPos02_OutterRim")
end
function LuaHook_Peak550_MortarLob_PatternPos03_OutterRim(ai)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_Peak550_MortarLob_PatternPos03_OutterRim")
end
function LuaHook_Peak550_MortarLob_PatternPos01_MiddleLine(ai)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_Peak550_MortarLob_PatternPos01_MiddleLine")
end
function LuaHook_Peak550_MortarLob_PatternPos02_MiddleLine(ai)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_Peak550_MortarLob_PatternPos02_MiddleLine")
end
function LuaHook_Peak550_MortarLob_PatternPos03_MiddleLine(ai)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_Peak550_MortarLob_PatternPos03_MiddleLine")
end
function LuaHook_Peak550_MortarLob_PatternPos01_Stripes(ai)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_Peak550_MortarLob_PatternPos01_Stripes")
end
function LuaHook_Peak550_MortarLob_PatternPos02_Stripes(ai)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_Peak550_MortarLob_PatternPos02_Stripes")
end
function LuaHook_Peak550_MortarLob_PatternPos03_Stripes(ai)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_Peak550_MortarLob_PatternPos03_Stripes")
end
function LuaHook_Peak550_MortarLob_PatternPos01_YSplit(ai)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_Peak550_MortarLob_PatternPos01_YSplit")
end
function LuaHook_Peak550_MortarLob_PatternPos02_YSplit(ai)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_Peak550_MortarLob_PatternPos02_YSplit")
end
function LuaHook_Peak550_MortarLob_PatternPos03_YSplit(ai)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_Peak550_MortarLob_PatternPos03_YSplit")
end
function LuaHook_Peak550_MortarLob_PatternPos01_SquareZones(ai)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_Peak550_MortarLob_PatternPos01_SquareZones")
end
function LuaHook_Peak550_MortarLob_PatternPos02_SquareZones(ai)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_Peak550_MortarLob_PatternPos02_SquareZones")
end
function LuaHook_Peak550_MortarLob_PatternPos03_SquareZones(ai)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_Peak550_MortarLob_PatternPos03_SquareZones")
end
function LuaHook_ForceStunBossState()
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_ForceStunBossState")
end
function LuaHook_Peak380_ElevatorBreakSupport_ClawHit(ai, data)
  local level = game.FindLevel("Peak380_BigElevator")
  level:CallScript("DragonElevatorBreakPillar_ClawHit")
end
function LuaHook_Peak380_Stg1_ElectricBreath(ai, data)
  local level = game.FindLevel("Peak380_BigElevator")
  level:CallScript("LuaHook_Stg1_ElectricBreath")
end
function LuaHook_Peak380_ElevatorBreakSupport_TailHit(ai, data)
  local level = game.FindLevel("Peak380_BigElevator")
  level:CallScript("DragonElevatorBreakPillar_TailHit")
end
function LuaHook_Dragon_BombFaceTransistion(ai, data)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_BossForwardState")
  return data:FindOutcomeBranchesEntry("True")
end
function LuaHook_BossForwardState(ai, data)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_BossForwardState")
end
function LuaHook_BossBackwardState(ai, data)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_BossBackwardState")
end
function LuaHook_WarpToDragonArena(ai, data)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_WarpToDragonArena")
end
function LuaHook_Peak550_AxeMeleeTutorial(ai, data)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_AxeMeleeTutorial")
end
function LuaHook_Peak550_TurnOffDesignerMsgs(ai, data)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_TurnOffDesignerMsgs")
end
function LuaHook_DragonSpitKratosToStg3(ai, data)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_DragonSpitKratosToStg3")
end
function LuaHook_Peak500_ElevatorBreakSupport(ai, data)
  local level = game.FindLevel("Peak380_BigElevator")
  level:CallScript("LuaHook_Peak500_ElevatorBreakSupport")
end
function LuaHook_ForwardBossState_FromPeak500(ai, data)
  local level = game.FindLevel("Peak380_BigElevator")
  level:CallScript("LuaHook_ForwardBossState")
end
function LuaHook_Peak550_SetActiveState_TugWar_Pos00(ai, data)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_Peak550_SetActiveState_TugWar_Pos00")
end
function LuaHook_Peak550_HideAllCrystalSpawners(ai, data)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_Peak550_HideAllCrystalSpawners")
end
function LuaHook_Peak550_ShowAllCrystalSpawners(ai, data)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_Peak550_ShowAllCrystalSpawners")
end
function LuaHook_Peak550_ElectricMode_FullScreenEffect_Activate(ai, data)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_Peak550_ElectricMode_FullScreenEffect_Activate")
end
function LuaHook_Peak550_ElectricMode_FullScreenEffect_Deactivate(ai, data)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_Peak550_ElectricMode_FullScreenEffect_Deactivate")
end
function LuaHook_Peak380_Trigger_DragonIntro(ai, data)
  local level = game.FindLevel("Peak380_BigElevator")
  level:CallScript("LuaHook_Trigger_DragonIntro")
end
function LuaHook_Peak500_Trigger_PlatformRockFall(ai, data)
  local level = game.FindLevel("Peak500_ChimneyTop")
  level:CallScript("LuaHook_Trigger_PlatformRockFall")
end
function LuaHook_Peak380_Trigger_DragonElevatorPlatformBite(ai, data)
  local level = game.FindLevel("Peak380_BigElevator")
  level:CallScript("LuaHook_DragonElevatorPlatformBite")
end
function LuaHook_Peak550_BreakPlatform(ai, data)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_BreakPlatform")
end
function LuaHook_ElevatorStoppedMelee(ai, data)
  local level = game.FindLevel("Peak380_BigElevator")
  level:CallScript("LuaHook_ElevatorStoppedMelee")
end
function LuaHook_ElevatorStoppedElectricBreath(ai, data)
  local level = game.FindLevel("Peak380_BigElevator")
  level:CallScript("LuaHook_ElevatorStoppedElectricBreath")
end
function LuaHook_SetVulnerabilityMarker(ai, data)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_SetVulnerabilityMarker")
end
function LuaHook_AcquirePickup_CrystalVul(ai, data)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_AcquirePickup_CrystalVul")
end
function LuaHook_HitBombFaceDecision(ai, data)
  local hasPickup = ai:PickupIsAcquired("EarthDragon_HitBombFaceCounter")
  local pickupStage = ai:PickupGetStage("EarthDragon_HitBombFaceCounter")
  if hasPickup then
    ai:PickupIncrementStage("EarthDragon_HitBombFaceCounter")
    if 1 <= pickupStage then
      LuaHook_BossForwardState(ai, data)
      if ai:HasMarker("BossStage_Pos1_Breath") then
        return data:FindOutcomeBranchesEntry("Pos01ReactionToStun")
      elseif ai:HasMarker("BossStage_Pos3_Breath") then
        return data:FindOutcomeBranchesEntry("Pos03ReactionToStun")
      elseif ai:HasMarker("BossStage_Pos2_Breath") then
        return data:FindOutcomeBranchesEntry("Pos02ReactionToStun")
      elseif ai:HasMarker("BossStage_TugWar_Pos02_Breath") then
        return data:FindOutcomeBranchesEntry("TugReactionToStun")
      end
    elseif ai:HasMarker("BossStage_Pos1_Breath") then
      return data:FindOutcomeBranchesEntry("Pos01ReactionToIdle")
    elseif ai:HasMarker("BossStage_Pos3_Breath") then
      return data:FindOutcomeBranchesEntry("Pos03ReactionToIdle")
    elseif ai:HasMarker("BossStage_Pos2_Breath") then
      return data:FindOutcomeBranchesEntry("Pos02ReactionToIdle")
    elseif ai:HasMarker("BossStage_TugWar_Pos02_Breath") then
      return data:FindOutcomeBranchesEntry("TugReactionToIdle")
    end
  else
    return false
  end
end
function LuaHookDecision_POS03_isClearOutRange(ai, data)
  if IsMarkTurnOffDTREE == true then
    return false
  end
  local l_player = game.Player.FindPlayer()
  local l_distToPlayer = (l_player:GetWorldPosition() - ai:GetWorldPosition()):Length()
  local l_angleToTarget = GetAngleToTarget(ai, l_player)
  local l_IsTargetOnLeft = IsTargetOnLeft(ai)
  if IsTargetInRangeCheck(ai, 10, 0, 12, color.red) and not l_IsTargetOnLeft then
    return true
  elseif IsTargetInRangeCheck(ai, 40, 0, 12, color.red) and l_IsTargetOnLeft then
    return true
  elseif IsTargetInRangeCheck(ai, 40, 0, 10, color.red) then
    return true
  end
  return false
end
function LuaHookDecision_POS03_isCloseRange(ai, data)
  if IsMarkTurnOffDTREE == true then
    return false
  end
  local l_player = game.Player.FindPlayer()
  local l_distToPlayer = (l_player:GetWorldPosition() - ai:GetWorldPosition()):Length()
  local l_angleToTarget = GetAngleToTarget(ai, l_player)
  local l_IsTargetOnLeft = IsTargetOnLeft(ai)
  if IsTargetInRangeCheck(ai, 65, 10, 17, color.orange) and not l_IsTargetOnLeft then
    return true
  elseif IsTargetInRangeCheck(ai, 32, 10, 17, color.orange) and not l_IsTargetOnLeft then
    return true
  elseif IsTargetInRangeCheck(ai, 30, 10, 17, color.orange) and l_IsTargetOnLeft then
    return true
  end
  return false
end
function LuaHookDecision_POS03_isCloseMidRange(ai, data)
  if IsMarkTurnOffDTREE == true then
    return false
  end
  local l_player = game.Player.FindPlayer()
  local l_distToPlayer = (l_player:GetWorldPosition() - ai:GetWorldPosition()):Length()
  local l_angleToTarget = GetAngleToTarget(ai, l_player)
  local l_IsTargetOnLeft = IsTargetOnLeft(ai)
  if IsTargetInRangeCheck(ai, 40, 19.5, 24, color.yellow) and not l_IsTargetOnLeft then
    return true
  elseif IsTargetInRangeCheck(ai, 40, 15, 23, color.yellow) and l_IsTargetOnLeft then
    return true
  elseif IsTargetInRangeCheck(ai, 15, 17, 19, color.yellow) and l_IsTargetOnLeft then
    return true
  end
  return false
end
function LuaHookDecision_POS03_isMidRange(ai, data)
  if IsMarkTurnOffDTREE == true then
    return false
  end
  local l_player = game.Player.FindPlayer()
  local l_distToPlayer = (l_player:GetWorldPosition() - ai:GetWorldPosition()):Length()
  local l_angleToTarget = GetAngleToTarget(ai, l_player)
  local l_IsTargetOnLeft = IsTargetOnLeft(ai)
  if IsTargetInRangeCheck(ai, 16, 24, 28, color.lime) then
    return true
  elseif IsTargetInRangeCheck(ai, 34, 24, 29, color.lime) and not l_IsTargetOnLeft then
    return true
  elseif IsTargetInRangeCheck(ai, 60, 24, 28, color.lime) and l_IsTargetOnLeft then
    return true
  end
  return false
end
function LuaHookDecision_POS03_isMidAltRange(ai, data)
  if IsMarkTurnOffDTREE == true then
    return false
  end
  local l_player = game.Player.FindPlayer()
  local l_distToPlayer = (l_player:GetWorldPosition() - ai:GetWorldPosition()):Length()
  local l_angleToTarget = GetAngleToTarget(ai, l_player)
  local l_IsTargetOnLeft = IsTargetOnLeft(ai)
  if IsTargetInRangeCheck(ai, 34, 16, 29, color.lime) then
    return true
  end
  return false
end
function LuaHookDecision_POS03_isFar(ai, data)
  if IsMarkTurnOffDTREE == true then
    return false
  end
  if IsTargetInRangeCheck(ai, 60, 30, 60, color.purple) then
    return true
  end
end
function LuaHookDecision_hasMarker_BossStage_Pos2_Melee(ai, data)
  if IsMarkTurnOffDTREE == true then
    return false
  end
  if ai:HasMarker("BossStage_Pos2_Melee") then
    return true
  else
    return false
  end
end
function LuaHookDecision_hasMarker_BossStage_Pos3_Melee(ai, data)
  if IsMarkTurnOffDTREE == true then
    return false
  end
  if ai:HasMarker("BossStage_Pos3_Melee") then
    return true
  else
    return false
  end
end
function LuaHookDecision_hasMarker_BossStage_TugWar_Pos02_Melee(ai, data)
  if IsMarkTurnOffDTREE == true then
    return false
  end
  if ai:HasMarker("BossStage_TugWar_Pos02_Melee") then
    return true
  else
    return false
  end
end
function LuaHookDecision_hasMarker_ELECTRICBREATH_MODE(ai, data)
  if IsMarkTurnOffDTREE == true then
    return false
  end
  if ai:HasMarker("ELECTRICBREATH_MODE") then
    return true
  else
    return false
  end
end
function LuaHookDecision_POS03_isFarAlt(ai, data)
  if IsMarkTurnOffDTREE == true then
    return false
  end
  local l_player = game.Player.FindPlayer()
  local l_distToPlayer = (l_player:GetWorldPosition() - ai:GetWorldPosition()):Length()
  local l_angleToTarget = GetAngleToTarget(ai, l_player)
  local l_IsTargetOnLeft = IsTargetOnLeft(ai)
  if IsTargetInRangeCheck(ai, 60, 27, 60, color.purple) then
    return true
  end
end
function LuaHook_DragonPos03AttackDecision(ai, data)
  if IsMarkTurnOffDTREE == true then
    return false
  end
  local l_player = game.Player.FindPlayer()
  local l_distToPlayer = (l_player:GetWorldPosition() - ai:GetWorldPosition()):Length()
  local l_angleToTarget = GetAngleToTarget(ai, l_player)
  local l_IsTargetOnLeft = IsTargetOnLeft(ai)
  if IsTargetInRangeCheck(ai, 40, 0, 15, color.red) then
    if math.random(1, 2) == 1 then
      return data:FindOutcomeBranchesEntry("Taunt")
    end
  elseif IsTargetInRangeCheck(ai, 60, 0, 30, color.yellow) then
    if math.random(1, 5) == 1 then
      return data:FindOutcomeBranchesEntry("Taunt")
    end
  elseif IsTargetInRangeCheck(ai, 60, 0, 60, color.purple) and math.random(1, 10) == 1 then
    return data:FindOutcomeBranchesEntry("Taunt")
  end
  if IsTargetInRangeCheck(ai, 10, 0, 12, color.red) and not l_IsTargetOnLeft then
    if math.random(1, 2) == 1 then
      return data:FindOutcomeBranchesEntry("ClearOut")
    else
      return data:FindOutcomeBranchesEntry("ClearOutAlt")
    end
  elseif IsTargetInRangeCheck(ai, 11, 0, 12, color.red) and l_IsTargetOnLeft then
    if math.random(1, 2) == 1 then
      return data:FindOutcomeBranchesEntry("ClearOut")
    else
      return data:FindOutcomeBranchesEntry("ClearOutAlt")
    end
  elseif IsTargetInRangeCheck(ai, 40, 0, 10, color.red) then
    if math.random(1, 2) == 1 then
      return data:FindOutcomeBranchesEntry("ClearOut")
    else
      return data:FindOutcomeBranchesEntry("ClearOutAlt")
    end
  elseif IsTargetInRangeCheck(ai, 65, 0, 17, color.orange) and not l_IsTargetOnLeft then
    return data:FindOutcomeBranchesEntry("TargetClose")
  elseif IsTargetInRangeCheck(ai, 32, 0, 17, color.orange) and not l_IsTargetOnLeft then
    return data:FindOutcomeBranchesEntry("TargetClose")
  elseif IsTargetInRangeCheck(ai, 30, 0, 17, color.orange) and l_IsTargetOnLeft then
    return data:FindOutcomeBranchesEntry("TargetClose")
  elseif IsTargetInRangeCheck(ai, 40, 19.5, 24, color.yellow) and not l_IsTargetOnLeft then
    return data:FindOutcomeBranchesEntry("TargetMid")
  elseif IsTargetInRangeCheck(ai, 40, 10, 19, color.yellow) and l_IsTargetOnLeft then
    return data:FindOutcomeBranchesEntry("TargetMid")
  elseif IsTargetInRangeCheck(ai, 15, 17, 19, color.yellow) and l_IsTargetOnLeft then
    return data:FindOutcomeBranchesEntry("TargetMid")
  elseif IsTargetInRangeCheck(ai, 16, 25, 28, color.lime) then
    return data:FindOutcomeBranchesEntry("TargetMidFar")
  elseif IsTargetInRangeCheck(ai, 34, 16, 29, color.lime) and not l_IsTargetOnLeft then
    if math.random(1, 2) == 1 then
      return data:FindOutcomeBranchesEntry("TargetMidFar")
    else
      return data:FindOutcomeBranchesEntry("TargetMidFarAlt")
    end
  elseif IsTargetInRangeCheck(ai, 60, 16, 28, color.lime) and l_IsTargetOnLeft then
    return data:FindOutcomeBranchesEntry("TargetMidFar")
  elseif IsTargetInRangeCheck(ai, 60, 27, 60, color.purple) then
    if 1 < math.random(1, 3) then
      return data:FindOutcomeBranchesEntry("TargetFar")
    else
      return data:FindOutcomeBranchesEntry("TargetFarAlt")
    end
  else
    return data:FindOutcomeBranchesEntry("False")
  end
end
function LuaHook_DragonPos03RakeFollowUpDecision(ai, data)
  if IsMarkTurnOffDTREE == true then
    return false
  end
  if ai:HasMarker("BossStage_Pos2_Melee") ~= true then
    return false
  end
  local l_IsTargetOnLeft = IsTargetOnLeft(ai)
  local l_IsTargetLeftOfJoint = IsTargetLeftOfJoint(ai, data, "JOLeftToe1Tip")
  if IsTargetInRangeCheck(ai, 45, 0, 21, color.red) then
    return data:FindOutcomeBranchesEntry("TargetMidClose")
  elseif IsTargetInRangeCheck(ai, 10, 0, 31, color.lime) then
    if l_IsTargetLeftOfJoint then
      return data:FindOutcomeBranchesEntry("LeftSide")
    else
      return data:FindOutcomeBranchesEntry("RightSide")
    end
  elseif IsTargetInRangeCheck(ai, 40, 0, 31, color.lime) and l_IsTargetOnLeft then
    if l_IsTargetLeftOfJoint then
      return data:FindOutcomeBranchesEntry("LeftSide")
    else
      return data:FindOutcomeBranchesEntry("RightSide")
    end
  elseif IsTargetInRangeCheck(ai, 40, 0, 31, color.lime) and not l_IsTargetOnLeft then
    if l_IsTargetLeftOfJoint then
      return data:FindOutcomeBranchesEntry("LeftSide")
    else
      return data:FindOutcomeBranchesEntry("RightSide")
    end
  elseif IsTargetInRangeCheck(ai, 40, 0, 31, color.lime) and l_IsTargetOnLeft then
    if l_IsTargetLeftOfJoint then
      if math.random(1, 2) == 1 then
        return data:FindOutcomeBranchesEntry("TargetMidFar")
      else
        return data:FindOutcomeBranchesEntry("TargetMidFarAlt")
      end
    else
      return data:FindOutcomeBranchesEntry("RightSide")
    end
  elseif IsTargetInRangeCheck(ai, 40, 0, 31, color.lime) and not l_IsTargetOnLeft then
    if l_IsTargetLeftOfJoint then
      return data:FindOutcomeBranchesEntry("LeftSide")
    elseif math.random(1, 2) == 1 then
      return data:FindOutcomeBranchesEntry("TargetMidFar")
    else
      return data:FindOutcomeBranchesEntry("TargetMidFarAlt")
    end
  elseif IsTargetInRangeCheck(ai, 45, 0, 35, color.purple) then
    if math.random(1, 2) == 1 then
      return data:FindOutcomeBranchesEntry("TargetMidFar")
    else
      return data:FindOutcomeBranchesEntry("TargetMidFarAlt")
    end
  elseif IsTargetInRangeCheck(ai, 45, 0, 60, color.purple) then
    return data:FindOutcomeBranchesEntry("TargetFar")
  end
end
function IsTargetLeftOfJoint(ai, data, jointName)
  local l_jointName = jointName
  local l_target = ai:GetTargetCreature()
  local l_target_pos = l_target:GetWorldPosition()
  local l_lhand_pos = ai:GetWorldJointPosition(ai:GetJointIndex(l_jointName))
  local l_distToTarget = (l_target:GetWorldPosition() - l_lhand_pos):Length()
  local left_vector = ai:GetWorldJointLeft(ai:GetJointIndex(l_jointName))
  local l_dirToTarget = (l_target_pos - l_lhand_pos):Normalized()
  local dot = left_vector:Dot(l_dirToTarget)
  if 0 < dot then
    return true
  else
    return false
  end
end
function LuaHook_DragonPos03BreathAttackDecision(ai, data)
  if IsMarkTurnOffDTREE == true then
    return false
  end
  local l_player = game.Player.FindPlayer()
  local l_distToPlayer = (l_player:GetWorldPosition() - ai:GetWorldPosition()):Length()
  local l_angleToTarget = GetAngleToTarget(ai, l_player)
  local l_IsTargetOnLeft = IsTargetOnLeft(ai)
  if IsTargetInRangeCheck(ai, 40, 24, 30, color.orange) then
    return data:FindOutcomeBranchesEntry("TargetClose")
  elseif IsTargetInRangeCheck(ai, 40, 31, 40, color.blue) then
    return data:FindOutcomeBranchesEntry("TargetMid")
  elseif IsTargetInRangeCheck(ai, 45, 0, 60, color.purple) then
    return data:FindOutcomeBranchesEntry("TargetFar")
  else
    return data:FindOutcomeBranchesEntry("False")
  end
end
function LuaHook_DragonTugAttackDecision(ai, data)
  if IsMarkTurnOffDTREE == true then
    return false
  end
  local l_player = game.Player.FindPlayer()
  local l_distToPlayer = (l_player:GetWorldPosition() - ai:GetWorldPosition()):Length()
  local l_angleToTarget = GetAngleToTarget(ai, l_player)
  local l_IsTargetOnLeft = IsTargetOnLeft(ai)
  if IsTargetInRangeCheck(ai, 60, 0, 20, color.red) and l_IsTargetOnLeft then
    return data:FindOutcomeBranchesEntry("TargetLeftClose")
  elseif IsTargetInRangeCheck(ai, 60, 0, 20, color.red) and not l_IsTargetOnLeft then
    return data:FindOutcomeBranchesEntry("TargetRightClose")
  elseif IsTargetInRangeCheck(ai, 60, 0, 60, color.purple) then
    return data:FindOutcomeBranchesEntry("TargetFar")
  else
    return data:FindOutcomeBranchesEntry("False")
  end
end
function PeakDragon_PlayConcussion(ai, cncName, leftOffset, forwardOffset)
  local player = game.Player.FindPlayer()
  local l_level = game.FindLevel("Peak380_BigElevator")
  local l_obj = l_level:GetGameObject("dragonelevator00")
  local l_jointIndex = l_obj:GetJointIndex("JOPelvis1")
  local elevatorPosition = l_obj:GetWorldJointPosition(l_jointIndex)
  local elevatorLeft = l_obj:GetWorldJointLeft(l_jointIndex)
  local elevatorForward = l_obj:GetWorldJointForward(l_jointIndex)
  local concussionParams = {
    Tweak = cncName,
    WorldLocation = elevatorPosition + elevatorLeft * leftOffset - elevatorForward * forwardOffset,
    GameObject = ai,
    EnemyId = player:GetID()
  }
  game.Combat.PlayConcussion(concussionParams)
  local fxParams = {
    Tweak = "PFX_PEAKDRAGON_PLACEHOLDER_ATTACK",
    WorldLocation = elevatorPosition + elevatorLeft * leftOffset * 0.25 - elevatorForward * forwardOffset * 1.2,
    GameObject = ai,
    EnemyId = player:GetID()
  }
  game.Combat.PlayConcussion(fxParams)
end
function LuaHook_PeakDragon_LeftBite(ai, data)
  PeakDragon_PlayConcussion(ai, "CNC_PEAKDRAGON_BITE", -15, 5)
end
function LuaHook_PeakDragon_RightClaw(ai, data)
  PeakDragon_PlayConcussion(ai, "CNC_PEAKDRAGON_CLAW", 15, 5)
end
function LuaHook_AnimateChargeAttack(ai, data)
  ai:StartMaterialAnim("chargeAttack")
end
function LuaHook_AnimateChargeAttack_Short(ai, data)
  ai:StartMaterialAnim("short_attack")
end
function LuaHook_AnimateHandDamageHit(ai, data)
  ai:StartMaterialAnim("arms_damage_hit")
end
function LuaHook_AnimateHandDamageHitRight(ai, data)
  ai:StartMaterialAnim("arms_right_damage_hit")
end
function LuaHook_AnimateLegDamageHit(ai, data)
  ai:StartMaterialAnim("legs_left_damage_hit")
end
function LuaHook_AnimateLegDamageHitRight(ai, data)
  ai:StartMaterialAnim("legs_right_damage_hit")
end
function LuaHook_AnimateHeadDamageHit(ai, data)
  ai:StartMaterialAnim("damage_hit")
  if isHeadDamageFocusOn then
    ai:StartMaterialAnim("head_damage_focus_off")
  end
end
function LuaHook_AnimateHeadDamageFocus_Off(ai, data)
  if isHeadDamageFocusOn then
    ai:StartMaterialAnim("head_damage_focus_off")
  end
end
function LuaHook_AnimateHeadDamageFocus_On(ai, data)
  isHeadDamageFocusOn = true
  ai:StartMaterialAnim("head_damage_focus_on")
end
function IsPlayerOnElevatorLeft(ai)
  local l_player = game.Player.FindPlayer()
  local l_level = game.FindLevel("Peak380_BigElevator")
  local l_obj = l_level:GetGameObject("dragonelevator00")
  local l_jointIndex = l_obj:GetJointIndex("JOPelvis1")
  local elevatorPosition = l_obj:GetWorldJointPosition(l_jointIndex)
  local elevatorLeft = l_obj:GetWorldJointLeft(l_jointIndex)
  local elevatorForward = l_obj:GetWorldJointForward(l_jointIndex)
  local l_distToPlayer = (l_player:GetWorldPosition() - ai:GetWorldPosition()):Length()
  local dir = (l_player:GetWorldPosition() - elevatorPosition):Normalized()
  local dot = elevatorLeft:Dot(dir)
  engine.DrawFillSphere(elevatorPosition, 1, 16711680)
  engine.DrawFillSphere(elevatorPosition + elevatorForward * 3, 1, 16711680)
  if -0.48 < dot then
    engine.DrawFillSphere(l_player:GetWorldPosition() + l_player:GetWorldLeft() * 2, 0.5, 16711680)
    return true
  else
    engine.DrawFillSphere(l_player:GetWorldPosition() - l_player:GetWorldLeft() * 2, 0.5, 16711680)
    return false
  end
end
function LuaHookDecision_DragonAttackElevator(ai, data)
  if IsMarkTurnOffDTREE == true then
    return false
  end
  if IsPlayerOnElevatorLeft(ai) == false then
    return data:FindOutcomeBranchesEntry("TargetLeft")
  else
    return data:FindOutcomeBranchesEntry("TargetRight")
  end
end
function LuaHook_Peak550_ToggleMeterOn(ai, data)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_ToggleMeterOn")
end
function LuaHook_Peak550_ToggleMeterOff(ai, data)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_ToggleMeterOff")
end
function LuaHook_ShieldsUp(ai, data)
  ai:MeterSetValue("DragonBossShield", ai:MeterGetValue("DragonBossHealth"))
end
function LuaHook_RegenBombFaceDamage_FromPos01Stun(ai, data)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_RegenBombFaceDamage_FromPos01Stun")
end
function LuaHook_InitMetersForStartOfPos01Stun(ai, data)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_InitMetersForStartOfPos01Stun")
end
function LuaHook_InitMetersForStartOfPos03Melee(ai, data)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_InitMetersForStartOfPos03Melee")
end
function LuaHook_InitMetersForStartOfPos03Stun(ai, data)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_InitMetersForStartOfPos03Stun")
end
function LuaHook_RegenBombFaceDamage_FromPos03Stun(ai, data)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_RegenBombFaceDamage_FromPos03Stun")
end
function LuaHook_InitMetersForStartOfPos02Melee(ai, data)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_InitMetersForStartOfPos02Melee")
end
function LuaHook_RegenBombFaceDamage_FromPos02Stun(ai, data)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_RegenBombFaceDamage_FromPos02Stun")
end
function LuaHook_InitMetersForStartOfPos02Stun(ai, data)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_InitMetersForStartOfPos02Stun")
end
function LuaHook_InitMetersForStartOfTugOfWar(ai, data)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_InitMetersForStartOfTugOfWar")
end
function LuaHook_InitMetersForStartOfTugOfWarStun(ai, data)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_InitMetersForStartOfTugOfWarStun")
end
function LuaHook_BombFaceDamage(ai, data)
  local l_curMeter = ai:MeterGetValue("DragonBossHealth")
  ai:MeterSetValue("DragonBossHealth", math.abs(l_curMeter - 100))
  ai:MeterSetValue("DragonBossHealth_Hidden", math.abs(l_curMeter - 100))
  DamageHealthBar()
end
function LuaHook_HealthTickDown(ai, data)
  local currentHealth = ai:MeterGetValue("DragonBossHealth")
  local currentHealth_Hidden = ai:MeterGetValue("DragonBossHealth_Hidden")
  ai:MeterSetValue("DragonBossHealth", currentHealth_Hidden)
  DamageHealthBar()
end
function LuaHook_InMouthDamage_HealthTickDown_Light(ai, data)
  local l_player = game.Player.FindPlayer()
  l_player:SetBlood(game.GameObject.eRegionId.kRightBackLeg, 0.5)
  l_player:SetBlood(game.GameObject.eRegionId.kLeftBackLeg, 0.5)
  l_player:SetBlood(game.GameObject.eRegionId.kLeftFrontLeg, 0.8)
  l_player:SetBlood(game.GameObject.eRegionId.kRightFrontLeg, 0.8)
  l_player:SetBlood(game.GameObject.eRegionId.kLeftChest, 0.3)
  l_player:SetBlood(game.GameObject.eRegionId.kRightChest, 0.4)
  l_player:SetBlood(game.GameObject.eRegionId.kFrontAbdomen, 0.8)
  l_player:SetBlood(game.GameObject.eRegionId.kBackAbdomen, 0.6)
  l_player:SetBlood(game.GameObject.eRegionId.kMud, 1)
  local currentHealth = ai:MeterGetValue("DragonBossHealth")
  local currentHealth_Hidden = ai:MeterGetValue("DragonBossHealth_Hidden")
  local newHealth = math.max(currentHealth - 3, 0)
  local newHealth_Hidden = math.max(currentHealth_Hidden - 3, 0)
  ai:MeterSetValue("DragonBossHealth", newHealth)
  ai:MeterSetValue("DragonBossHealth_Hidden", newHealth_Hidden)
  DamageHealthBar()
end
function LuaHook_InMouthDamage_HealthTickDown_Heavy(ai, data)
  local l_player = game.Player.FindPlayer()
  l_player:SetBlood(game.GameObject.eRegionId.kHead, 0.5)
  l_player:SetBlood(game.GameObject.eRegionId.kRightBackUpperArm, 0.4)
  l_player:SetBlood(game.GameObject.eRegionId.kRightBackLowerArm, 0.4)
  l_player:SetBlood(game.GameObject.eRegionId.kLeftChest, 0.2)
  l_player:SetBlood(game.GameObject.eRegionId.kRightChest, 0.3)
  l_player:SetBlood(game.GameObject.eRegionId.kRightFrontUpperArm, 0.4)
  l_player:SetBlood(game.GameObject.eRegionId.kRightFrontLowerArm, 0.4)
  l_player:SetBlood(game.GameObject.eRegionId.kSnowfall, 0.7)
  local currentHealth = ai:MeterGetValue("DragonBossHealth")
  local currentHealth_Hidden = ai:MeterGetValue("DragonBossHealth_Hidden")
  local newHealth = math.max(currentHealth - 6, 0)
  local newHealth_Hidden = math.max(currentHealth_Hidden - 6, 0)
  ai:MeterSetValue("DragonBossHealth", newHealth)
  ai:MeterSetValue("DragonBossHealth_Hidden", newHealth_Hidden)
  DamageHealthBar()
end
function DamageHealthBar(ai, data)
  local l_level
  l_level = game.FindLevel("Peak550_DragonArena")
  if l_level ~= nil then
    l_level:CallScript("LuaHook_DamageHealthBar")
  else
    l_level = game.FindLevel("Peak380_BigElevator")
    if l_level ~= nil then
      l_level:CallScript("LuaHook_DamageHealthBar")
    end
  end
end
function LuaHook__Finale_ClampImpactHealth(ai, data)
  ai:MeterSetValue("DragonBossHealth", 20)
end
function LuaHook__Finale_ImpaleImpactHealth(ai, data)
  ai:MeterSetValue("DragonBossHealth", 15)
end
function LuaHook__Finale_ExplosionHealth(ai, data)
  ai:MeterSetValue("DragonBossHealth", 0.01)
end
function LuaHook_Peak550_TriggerFinaleDamageState(ai, data)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_Peak550_TriggerFinaleDamageState")
end
function LuaHook_Peak550_Finale_SpawnHealthOnDragonStun(ai, data)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("SpawnHealthOnDragonStun")
end
function LuaHook_Peak550_ToggleMeterOff(ai, data)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_ToggleMeterOff")
end
function LuaHook_EnableFinaleCollision(ai, data)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_EnableFinaleCollision")
end
function LuaHook_Dragon_StunBombFace_Breakables(ai, data)
  local level = game.FindLevel("Peak550_DragonArena")
  level:CallScript("LuaHook_Dragon_StunBombFace_Breakables")
end
function LuaHook_ForceCineRageModeExit(ai, data)
  local l_player = game.Player.FindPlayer()
  l_player:CallScript("LuaHook_ForceCineRageModeExit")
end
local currentDifficulty
local difficultyTable = {
  EasyDifficulty = 0,
  NormalDifficulty = 1,
  HardDifficulty = 2,
  ImpossibleDifficulty = 3
}
function LuaHook_SetDifficulty_Easy(ai, data)
  ai:AddMarker("EasyDifficulty")
  ai:RemoveMarker("NormalDifficulty")
  ai:RemoveMarker("HardDifficulty")
  ai:RemoveMarker("ImpossibleDifficulty")
  currentDifficulty = difficultyTable.EasyDifficulty
  print("Difficulty Check: ", currentDifficulty)
end
function LuaHook_SetDifficulty_Normal(ai, data)
  ai:AddMarker("NormalDifficulty")
  ai:RemoveMarker("EasyDifficulty")
  ai:RemoveMarker("HardDifficulty")
  ai:RemoveMarker("ImpossibleDifficulty")
  currentDifficulty = difficultyTable.NormalDifficulty
  print("Difficulty Check: ", currentDifficulty)
end
function LuaHook_SetDifficulty_Hard(ai, data)
  ai:AddMarker("HardDifficulty")
  ai:RemoveMarker("EasyDifficulty")
  ai:RemoveMarker("NormalDifficulty")
  ai:RemoveMarker("ImpossibleDifficulty")
  currentDifficulty = difficultyTable.HardDifficulty
  print("Difficulty Check: ", currentDifficulty)
end
function LuaHook_SetDifficulty_Impossible(ai, data)
  ai:AddMarker("ImpossibleDifficulty")
  ai:RemoveMarker("EasyDifficulty")
  ai:RemoveMarker("NormalDifficulty")
  ai:RemoveMarker("HardDifficulty")
  currentDifficulty = difficultyTable.ImpossibleDifficulty
  print("Difficulty Check: ", currentDifficulty)
end
function LuaHook_isDifficultyEasy(ai, data)
  if currentDifficulty == difficultyTable.EasyDifficulty then
    return true
  else
    return false
  end
end
function LuaHook_isDifficultyNormal(ai, data)
  if currentDifficulty == difficultyTable.NormalDifficulty then
    return true
  else
    return false
  end
end
function LuaHook_isDifficultyHard(ai, data)
  if currentDifficulty == difficultyTable.HardDifficulty then
    return true
  else
    return false
  end
end
function LuaHook_isDifficultyImpossible(ai, data)
  if currentDifficulty == difficultyTable.ImpossibleDifficulty then
    return true
  else
    return false
  end
end
function LuaHook_PlayDragonSlamSound()
  if Peak550 == nil then
    Peak550 = game.FindLevel("Peak550_DragonArena")
  end
  if Peak550 ~= nil then
    Peak550:CallScript("LuaHook_PlayDragonSlamSound")
  end
end
function InitializeAudioEmitters(ai)
  dragonMouthEmitter = ai:FindSingleSoundEmitterByName("SNDMouth")
end
function LuaHook_ActivateDragonMouthRTPC()
  game.Audio.SetBusLevelRTPCValue("EVNT_Inside_EarthDragon", 100)
  dragonGurglingDelay = timer.StartCreatureTimer(3.5, TimerElapsed)
  dragonGurglingDelay:Finish()
end
function LuaHook_DeactivateDragonMouthRTPC()
  dragonGurglingDelay:Stop()
  game.Audio.SetBusLevelRTPCValue("EVNT_Inside_EarthDragon", 0)
  LuaHook_StopInsideDragonMouth()
  if dragonMouthEmitter:IsPlaying("SND_CHR_EarthDragon_Breath_Mouth_Inside_Pain_Short") then
    LD.StopSound(dragonMouthEmitter, "SND_CHR_EarthDragon_Breath_Mouth_Inside_Pain_Short")
  end
end
function LuaHook_StopInsideDragonMouth()
  LD.StopSound(dragonMouthEmitter, "SND_CHR_EarthDragon_Vox_Gurgling_InMouth_LP")
end
function TimerElapsed()
  LD.PlaySound(dragonMouthEmitter, "SND_CHR_EarthDragon_Vox_Gurgling_InMouth_LP")
end
function LuaHook_InsideDragonMouthPain()
  if not dragonMouthEmitter:IsPlaying("SND_CHR_EarthDragon_Breath_Mouth_Inside_Pain_Short") then
    LuaHook_StopInsideDragonMouth()
    LD.PlaySound(dragonMouthEmitter, "SND_CHR_EarthDragon_Breath_Mouth_Inside_Pain_Short")
    if dragonGurglingDelay ~= nil then
      dragonGurglingDelay:Restart()
    end
  end
end
function AddDragonDebugTable(ai, debugTable)
  local l_player = game.Player.FindPlayer()
  local l_distToPlayer = (l_player:GetWorldPosition() - ai:GetWorldPosition()):Length()
  local l_target = ai:GetTargetCreature()
  local l_angleToTarget = GetAngleToTarget(ai, l_player)
  local l_IsTargetOnLeft = IsTargetOnLeft(ai)
  local l_healthmeter = ai:MeterGetValue("DragonBossHealth")
  table.insert(debugTable, {"--", "--"})
  table.insert(debugTable, {"Target:", l_target})
  table.insert(debugTable, {
    "Distance TO Player:",
    l_distToPlayer
  })
  table.insert(debugTable, {
    "Angle TO Target:",
    l_angleToTarget
  })
  table.insert(debugTable, {
    "Target on Left:",
    tostring(l_IsTargetOnLeft)
  })
  table.insert(debugTable, {"--", "--"})
  table.insert(debugTable, {
    "Health Meter:",
    tostring(l_healthmeter)
  })
end
picklelib.Install()
function Pickle(GO)
  return {
    global = global
  }
end
function Unpickle(GO, t)
  global = t.global
end
