local statemachine = require("ai.statemachine")
local tablex = require("core.tablex")
local picklelib = require("core.pickle")
local DL = require("design.DesignerLibrary")
local uiCalls = require("ui.uicalls")
local globalLuaHooks = require("design.GlobalLuaHooks")
globalLuaHooks.InstallHooks()
local traverselink = require("creature.traverselink")
traverselink.InstallHooks()
print("Jotunn00 main start")
Brain_Core = require("behavior.corebrain")
constants = {}
global = {}
local creatureName
local powerLevel = "1"
local powerLevelInt = 0
local breathEffect
local isPursuingEnemy = false
local swipeCombo = " "
local rageGrabTextShow = false
local chargeSmashComboCount = 0
local chargeSmashCountThreshold = 1
local rockThrowComboCount = 0
local rockThrowCountThreshold = 1
local jotunnEnraged = false
local enrageHealthThreshPercent = 40
local idleTurningEnabled = true
function OnAIPostSpawn(ai)
  setupCharacter(ai)
end
function Brain_Core:OnSetPowerlevelOverrideCustom(ai, global, constants, level, isElite, forced)
  creatureName = ai:GetName()
  powerLevel = level
  ToggleCharacterConfig(ai, forced)
end
function setupCharacter(ai)
  local moveName = ""
  local aggroState = ""
  local spawnContext = ai:GetContext()
  creatureName = ai:GetName()
  ai:PickupAcquire("Jotunn_MFX_Pickup", 0)
  ai:SetDirectAimingModeIsEnabled(true)
  if StartConfig ~= nil and StartConfig.EliteDifficulty ~= nil and StartConfig.EliteDifficulty and not ai:PickupIsAcquired("Jotunn00_Elite") then
    ai:PickupAcquire("Jotunn00_Elite")
  end
  local player = game.Player.FindPlayer()
  if breathEffect == nil then
    breathEffect = game.FX.Spawn("Jotunn_BreathFX", nil, {
      Joint = "JOAttachBreath",
      GameObject = ai,
      DeleteWithCreature = true
    })
    breathEffect:SetAnimFloatChannelDriver(player, "sliderfloatchannels._breathfxintensity")
  end
  if StartConfig ~= nil and StartConfig.SafeSpotOnKill ~= nil and StartConfig.SafeSpotOnKill == true then
    ai:AddMarker("UseSafeSpots")
  end
  if ai:AttributeGetValue("Difficulty") == 4 then
    local cineVar = game.Level.GetVariable("CompletedCineNumber")
    if ai:PickupIsAcquired("Jotunn00_PowerLevel") then
      if (380 <= cineVar and ai:PickupGetStage("Jotunn00_PowerLevel") <= 3 or 490 <= cineVar and 4 >= ai:PickupGetStage("Jotunn00_PowerLevel")) and (ai.GroundLevel == nil or ai.GroundLevel ~= nil and string.find(ai.GroundLevel.Name, "Msp") == nil) then
        ai:PickupAcquire("PowerLevelBoost")
      end
    elseif ai:PickupIsAcquired("Jotunn10_PowerLevel") and (380 <= cineVar and 3 >= ai:PickupGetStage("Jotunn10_PowerLevel") or 490 <= cineVar and 4 >= ai:PickupGetStage("Jotunn10_PowerLevel")) and (ai.GroundLevel == nil or ai.GroundLevel ~= nil and string.find(ai.GroundLevel.Name, "Msp") == nil) then
      ai:PickupAcquire("PowerLevelBoost")
    end
  end
  DL.NewGamePlusLevelBoost(ai, "Jotunn00_PowerLevel")
  DL.NewGamePlusLevelBoost(ai, "Jotunn10_PowerLevel")
end
function ToggleCharacterConfig(ai, override)
  if powerLevel == "1" then
    powerLevelInt = 1
  elseif powerLevel == "2" then
    powerLevelInt = 2
  elseif powerLevel == "3" then
    powerLevelInt = 3
  elseif powerLevel == "4" then
    powerLevelInt = 4
  elseif powerLevel == "5" then
    powerLevelInt = 5
  elseif powerLevel == "6" then
    powerLevelInt = 6
  elseif powerLevel == "7" then
    powerLevelInt = 7
  elseif powerLevel == "8" then
    powerLevelInt = 8
  else
    powerLevelInt = powerLevel
  end
  if creatureName ~= nil then
    if creatureName == "jotunn00" then
      if override ~= nil and override == true then
        if powerLevelInt <= 2 then
          ai:SetCharacterConfig("config0")
        elseif 3 <= powerLevelInt and powerLevelInt <= 4 then
          ai:SetCharacterConfig("config0_hard")
        elseif 5 <= powerLevelInt then
          ai:SetCharacterConfig("config0_veryhard")
        end
      end
    elseif creatureName == "jotunn10" then
      if override ~= nil and override == true then
        if powerLevelInt <= 2 then
          ai:SetCharacterConfig("config1")
        elseif 3 <= powerLevelInt and powerLevelInt <= 4 then
          ai:SetCharacterConfig("config1_hard")
        elseif 5 <= powerLevelInt then
          ai:SetCharacterConfig("config1_veryhard")
        end
      end
    elseif creatureName == "jotunn20" then
      if override ~= nil and override == true then
        ai:SetCharacterConfig("config1")
      end
      ai:SetMaterialSwap("jotunn02")
    else
      print("Jotunn - no texture swap specified for this variant")
      if override ~= nil and override == true then
        ai:SetCharacterConfig("config0")
      end
    end
  end
end
function OnAIUpdate(ai)
  traverselink.OnUpdate(ai)
end
function _G.OnAICreateLuaState(ai)
  _G.OnAICreateLuaState = nil
end
local ThrowEnemyBehavior = function(ai, global, constants)
  local NearbyCreatures = ai:FindFriendlies(8)
  local closestDist = 100
  local closestCreature
  for _, creature in ipairs(NearbyCreatures) do
    if creature ~= ai then
      local creatureName = creature:GetName()
      if creature:GetHitPoints() > 0 and creature:GetTargetCreature() ~= nil and not creature:PickupIsAcquired("TurretMode") and (creatureName == "bandit00" or creatureName == "draugr00" or creatureName == "projection00" or creatureName == "fanatic00" or creatureName == "darkone00") then
        if creatureName == "darkone00" then
          local isSummoner = creature:PickupIsAcquired("DarkOne_Summoner")
          if isSummoner then
            break
          end
        end
        if ai:AttributeGetValue("Difficulty") == 4 then
          if creature.HitPoints > 50 then
            break
          end
          local difficultyPickup = creature:GetName():gsub("%d", "") .. "00_Elite"
          if creature:PickupIsAcquired(difficultyPickup) and creature.HitPoints > 25 then
            break
          end
        end
        local frontAngle = DL.FrontAngle(ai, creature)
        if frontAngle < 90 and -80 <= frontAngle and not creature:IsInAir() then
          local creatureWorldPosition = creature:GetWorldPosition()
          local findPathParams = {}
          findPathParams.StartPosition = ai:GetWorldPosition()
          findPathParams.StartLocation = game.NavMesh.ClosestLocation(findPathParams.StartPosition)
          findPathParams.EndPosition = creatureWorldPosition
          findPathParams.EndLocation = game.NavMesh.ClosestLocation(findPathParams.EndPosition)
          local pathResult = game.NavMesh.FindPath(findPathParams)
          if pathResult ~= nil and pathResult.PathLength < 8.5 then
            closestCreature = creature
            break
          end
        end
      end
    end
  end
  if closestCreature ~= nil then
    isPursuingEnemy = true
    local closestCreatureName = closestCreature:GetName()
    if closestCreatureName == "bandit00" then
      _G.global.targetParams = "FIND_TARGET_PARAMETERS_COMBAT_BANDIT_ONLY"
    elseif closestCreatureName == "draugr00" then
      _G.global.targetParams = "FIND_TARGET_PARAMETERS_COMBAT_DRAUGR_ONLY"
    elseif closestCreatureName == "projection00" then
      _G.global.targetParams = "FIND_TARGET_PARAMETERS_COMBAT_PROJECTION_ONLY"
    elseif closestCreatureName == "fanatic00" then
      _G.global.targetParams = "FIND_TARGET_PARAMETERS_COMBAT_FANATIC_ONLY"
    elseif closestCreatureName == "darkone00" then
      _G.global.targetParams = "FIND_TARGET_PARAMETERS_COMBAT_DARKONE_ONLY"
    end
    _G.global.target = closestCreature
    ai:SetCombatTarget(_G.global.target)
    ai:ForceMove("BRA_PursueThrowableTarget")
  else
    _G.global.targetParams = "FIND_TARGET_PARAMETERS_COMBAT_KRATOS_ONLY"
    isPursuingEnemy = false
    return
  end
end
function LuaHook_AttemptGruntGrab(C, data)
  if C:GetHitPoints() > 0 and not isPursuingEnemy then
    ThrowEnemyBehavior(C)
  end
end
function Brain_Core:OnUpdateCombat(ai, global, constants)
  self.desiredDirectionDelta = ai:GetAnimDriver("AngleToDesiredPosition")
  if ai:HasMarker("TargetFriendly") then
    global.targetParams = "FIND_TARGET_PARAMETERS_COMBAT_FRIENDLY_ONLY"
  end
end
function Brain_Core:OnHitReaction(event, ai, global, constants)
  if not jotunnEnraged and 5 <= powerLevelInt and ai.PercentageOfHealth <= enrageHealthThreshPercent then
    jotunnEnraged = true
    if not ai:PickupIsAcquired("Jotunn00_Elite") then
      ai:PickupAcquire("Jotunn00_Elite")
      local jotunnVariant = ai:GetName()
      if jotunnVariant == "jotunn10" then
        ai:PickupSetStage("Jotunn00_Elite", 1)
      end
    end
  end
  if isPursuingEnemy and not ai:IsDoingSyncMove() and not DL.CheckCreatureContext(event.collisionContext, "ARROW_NORMAL") and not DL.CheckCreatureContext(event.collisionContext, "ARROW_SHOCK") and not DL.CheckCreatureContext(event.collisionContext, "ARROW_CRITICAL") and not DL.CheckCreatureContext(event.collisionContext, "ARROW_GRAZE") and not DL.CheckCreatureContext(event.collisionContext, "ARROW_NORMAL_COMMAND") and not DL.CheckCreatureContext(event.collisionContext, "ARROW_LIGHT") then
    isPursuingEnemy = false
  end
end
function Brain_Core:OnUpdateMotion(ai, global, constants, actuatorData, avoidanceArgs)
  local locInfo = ai:GetLocomotionInfo()
  local locPathAngle = locInfo.PathAngle or 0
  global.angleToDesiredPosition = locPathAngle
  self.desiredDirectionDelta.Value = global.angleToDesiredPosition
end
function Brain_Core:OnDeath(ai, attacker, deathByDespawn)
  if ai:PickupIsAcquired("Jotunn00_Elite") then
    ai:PickupRelinquish("Jotunn00_Elite")
  end
  if breathEffect ~= nil then
    breathEffect:Destroy()
    breathEffect = nil
  end
end
picklelib.Install()
function Pickle(GO)
  return {
    global = global
  }
end
function Unpickle(GO, t)
  global = t.global
end
function LuaHook_RageGrabTextShow(C, data)
  if not rageGrabTextShow then
    rageGrabTextShow = true
    uiCalls.SendSidebarDesignerMessage({
      Text = 40868,
      AdvanceType = uiCalls.msgParam.INFINITE_TIMER
    })
  end
end
function LuaHook_RageGrabTextHide(C, data)
  if rageGrabTextShow then
    uiCalls.UI_Event_TurnOffDesignerMessage()
    rageGrabTextShow = false
  end
end
function LuaHook_DestroyBreathFX(C, data)
  if breathEffect ~= nil then
    breathEffect:Destroy()
    breathEffect = nil
  end
end
function LuaHook_GrantHammerfistPickupOnce(C, data)
  if not C:PickupIsAcquired("Jotunn_FollowupAttackCount") then
    C:PickupAcquire("Jotunn_FollowupAttackCount")
  end
end
local spawnedBanditCarcass
function LuaHook_SpawnEatingBandit_SpawnBandit(ai)
  if spawnedBanditCarcass == nil then
    spawnedBanditCarcass = game.AI.Spawn(ai.Level, ai.WorldPosition, ai:GetWorldForward(), "CRT_Bandit00", "BRA_SpawnJotunnEatingBandit")
  end
end
function LuaHook_SetContextInCombat(C, data)
  global.aggroState = "INCOMBAT"
end
function LuaHook_TargetKratos(C, data)
  isPursuingEnemy = false
  _G.global.targetParams = "FIND_TARGET_PARAMETERS_COMBAT_KRATOS_ONLY"
end
function LuaHook_SetSwipeCombo_SingleDouble(C, data)
  swipeCombo = "singleDouble"
end
function LuaHook_SetSwipeCombo_DoubleSingle(C, data)
  swipeCombo = "doubleSingle"
end
function LuaHook_SetSwipeCombo_SingleSingleLR(C, data)
  swipeCombo = "singleSingleLR"
end
function LuaHook_SetSwipeCombo_SingleSingleRL(C, data)
  swipeCombo = "singleSingleRL"
end
function LuaHook_SetSwipeCombo_DoubleDoubleLR(C, data)
  if creatureName == "jotunn00" and (powerLevelInt <= 2 or 5 <= powerLevelInt) then
    local random = math.random(1, 40)
    local randomThreshold = 10
    if 40 > C.PercentageOfHealth then
      randomThreshold = randomThreshold + 15
    end
    if random <= randomThreshold then
      swipeCombo = "doubleDoubleDoubleLRL"
    else
      swipeCombo = "doubleDoubleLR"
    end
  else
    swipeCombo = "doubleDoubleLR"
  end
end
function LuaHook_SetSwipeCombo_DoubleDoubleRL(C, data)
  if creatureName == "jotunn00" and (powerLevelInt <= 2 or 5 <= powerLevelInt) then
    local random = math.random(1, 40)
    local randomThreshold = 10
    if 40 > C.PercentageOfHealth then
      randomThreshold = randomThreshold + 15
    end
    if random <= randomThreshold then
      swipeCombo = "doubleDoubleDoubleRLR"
    else
      swipeCombo = "doubleDoubleRL"
    end
  else
    swipeCombo = "doubleDoubleRL"
  end
end
function LuaHook_SetSwipeCombo_DoubleDoubleDoubleLRL(C, data)
  swipeCombo = "doubleDoubleDoubleLRL"
end
function LuaHook_SetSwipeCombo_DoubleDoubleDoubleRLR(C, data)
  swipeCombo = "doubleDoubleDoubleRLR"
end
function LuaHook_SetSwipeCombo_SingleDoubleDouble(C, data)
  swipeCombo = "singleDoubleDouble"
end
function LuaHook_GetMeleeCombo(C, data)
  if global.target ~= nil then
    local distToTarget = global.target:GetWorldPosition():Distance(C:GetWorldPosition())
    if swipeCombo == "doubleDoubleLR" and distToTarget <= 6.5 then
      return data:FindOutcomeBranchesEntry("DoubleDoubleLR")
    elseif swipeCombo == "doubleDoubleRL" and distToTarget <= 6.5 then
      return data:FindOutcomeBranchesEntry("DoubleDoubleRL")
    elseif swipeCombo == "singleSingleLR" and distToTarget <= 6 then
      return data:FindOutcomeBranchesEntry("SingleSingleLR")
    elseif swipeCombo == "singleSingleRL" and distToTarget <= 6 then
      return data:FindOutcomeBranchesEntry("SingleSingleRL")
    elseif swipeCombo == "doubleDoubleDoubleLRL" and distToTarget <= 7 then
      return data:FindOutcomeBranchesEntry("DoubleDoubleDoubleLRL")
    elseif swipeCombo == "doubleDoubleDoubleRLR" and distToTarget <= 7 then
      return data:FindOutcomeBranchesEntry("DoubleDoubleDoubleRLR")
    else
      return data:FindOutcomeBranchesEntry("TargetTooFar")
    end
  else
    return
  end
end
function LuaHook_ResetChargeSmashComboCount(C, data)
  chargeSmashComboCount = 0
end
function LuaHook_IncrementChargeSmashComboCount(C, data)
  chargeSmashComboCount = chargeSmashComboCount + 1
end
function LuaHook_CheckChargeSmashFollowup(C, data)
  if creatureName == "jotunn00" and 3 <= powerLevelInt then
    local followupAttack = false
    if chargeSmashComboCount < chargeSmashCountThreshold then
      followupAttack = true
    elseif chargeSmashComboCount == chargeSmashCountThreshold then
      local random = math.random(1, 3)
      if random == 1 then
        followupAttack = true
      end
    end
    if followupAttack then
      local combatTarget = C:GetTargetCreature()
      if combatTarget ~= nil then
        local distanceToTarget = combatTarget:GetWorldPosition():Distance(C:GetWorldPosition())
        local frontAngle = DL.FrontAngle(C, combatTarget)
        if 7 < distanceToTarget then
          if frontAngle < -40 and -180 <= frontAngle then
            return data:FindOutcomeBranchesEntry("Enter120L")
          elseif 40 < frontAngle and frontAngle <= 180 then
            return data:FindOutcomeBranchesEntry("Enter120R")
          else
            return data:FindOutcomeBranchesEntry("Enter0")
          end
        elseif -90 <= frontAngle and frontAngle <= 80 then
          return data:FindOutcomeBranchesEntry("HammerfistSmash")
        else
          return data:FindOutcomeBranchesEntry("DoNothing")
        end
      else
        return data:FindOutcomeBranchesEntry("DoNothing")
      end
    else
      return data:FindOutcomeBranchesEntry("DoNothing")
    end
  end
end
function LuaHook_ResetRockThrowCount(C, data)
  rockThrowComboCount = 0
  print(rockThrowComboCount)
end
function LuaHook_IncrementRockThrowCount(C, data)
  rockThrowComboCount = rockThrowComboCount + 1
  C:SetDirectAimingModeIsEnabled(true)
end
function LuaHook_GetRockThrowComboCount(C, data)
  if rockThrowComboCount < rockThrowCountThreshold or rockThrowComboCount > rockThrowCountThreshold then
    return rockThrowComboCount
  elseif rockThrowComboCount == rockThrowCountThreshold then
    local rand = math.random(1, 3)
    if rand ~= 3 then
      rockThrowComboCount = rockThrowComboCount + 5
    end
    return rockThrowComboCount
  end
end
function LuaHook_CheckChargeAngleToPlayer(C, data)
  local goPlayerCreature = game.Player.FindPlayer()
  if goPlayerCreature ~= nil then
    local distanceToPlayer = goPlayerCreature:GetWorldPosition():Distance(C:GetWorldPosition())
    if 6 < distanceToPlayer then
      local frontAngle = DL.FrontAngle(C, goPlayerCreature)
      if frontAngle < -40 and -180 <= frontAngle then
        return data:FindOutcomeBranchesEntry("Enter120L")
      elseif 40 < frontAngle and frontAngle <= 180 then
        return data:FindOutcomeBranchesEntry("Enter120R")
      else
        return data:FindOutcomeBranchesEntry("Enter0")
      end
    else
      return data:FindOutcomeBranchesEntry("DoNothing")
    end
  else
    return data:FindOutcomeBranchesEntry("DoNothing")
  end
end
function LuaHook_MotionWarpJumpSmash(C, data)
  local creaturePosition = C:GetWorldPosition()
  local distToTarget = 0
  if global.target ~= nil then
    distToTarget = global.target:GetWorldPosition():Distance(creaturePosition)
  end
  local zeroJointFacingFwd = C:GetWorldJointForward(C:GetJointIndex("zeroJoint"))
  local offset = zeroJointFacingFwd:Normalized() * distToTarget
  local offsetZeroJoint = creaturePosition + offset
  C:GetAnimDriver("DirToTarget").ValueVec = zeroJointFacingFwd:Normalized()
  C:GetAnimDriver("PosToTarget").ValueVec = offsetZeroJoint
end
function LuaHook_TraversalAttackCheck(C, data)
  local ai = C:GetAI()
  if global.target == nil then
    return
  end
  local traversalAmt = 0
  if ai:IsPlayingMove("MOV_LongRangeJumpSmashAttempt") then
    traversalAmt = 10
  elseif ai:IsPlayingMove("MOV_ChargeSmashAttempt") then
    traversalAmt = 6
  end
  local zeroJointFacingFwd = ai:GetWorldJointForward(ai:GetJointIndex("zeroJoint"))
  local offsetZeroJoint = ai.WorldPosition + engine.Vector.New(0, 2, 0)
  local toFront = zeroJointFacingFwd * traversalAmt
  local offsetFront = offsetZeroJoint + toFront
  offsetFront.y = offsetZeroJoint.y
  local hitFront = game.World.RaycastCollision(offsetZeroJoint, offsetFront, {
    SourceGameObject = ai,
    EntityType = game.CollisionType.New("kEnvironment", "kInvisibleBarrier")
  })
  if hitFront then
    return data:FindOutcomeBranchesEntry("nothing")
  else
    return data:FindOutcomeBranchesEntry("checkSucceed")
  end
end
function LuaHook_HitStandingF01Death()
  if game.FindLevel("Stn610_POIIntroCombat") then
    game.FindLevel("Stn610_POIIntroCombat"):CallScript("MusicDestroyCJotunnOut")
  elseif game.FindLevel("Cal410_FinaleTowerFight") then
    game.FindLevel("Cal410_FinaleTowerFight"):GetGameObject("encounterControl"):CallScript("rbrMusicWave4JotDeath")
  end
end
function LuaHook_CSJotunnPlayerGrabDeath()
  if game.FindLevel("Stn610_POIIntroCombat") then
    game.FindLevel("Stn610_POIIntroCombat"):CallScript("MusicDestroyCJotunnOut")
  end
end
function LuaHook_CSJotunnRageKillExit()
  if game.FindLevel("Stn610_POIIntroCombat") then
    game.FindLevel("Stn610_POIIntroCombat"):CallScript("MusicDestroyCJotunnOut")
  elseif game.FindLevel("Foot400_Arena") then
    game.FindLevel("Foot400_Arena"):CallScript("foot400CSOgreMusic")
  elseif game.FindLevel("Foot100_Base") and game.Level.GetVariable("CompletedCineNumber") >= 450 then
    game.Audio.StartMusic("SND_MX_FOOT4_ogre_cs_kill")
  elseif game.FindLevel("Peak500_ChimneyTop") and game.Level.GetVariable("CompletedCineNumber") >= 460 then
    game.Audio.StartMusic("SND_MX_PEAK2_upstairs_ogre_cs_kill")
  elseif game.FindLevel("Stn250_BanditCamp") then
    game.Audio.StartMusic("SND_MX_STN_head_camp_fight_ogre_cs_kill")
  elseif game.FindLevel("Xpl100_HTTK") then
    game.Audio.StartMusic("SND_MX_XPL100_ogre_cs_kill")
    game.Audio.SetCheckpointedMusic("SND_MX_XPL100_explore1_in")
  elseif game.FindLevel("Xpl300_Stronghold") then
    game.Audio.StartMusic("SND_MX_XPL300_ogre_cs_kill")
    game.Audio.SetCheckpointedMusic("SND_MX_XPL300_explore2_in")
  elseif game.FindLevel("Cal410_FinaleTowerFight") then
    game.FindLevel("Cal410_FinaleTowerFight"):GetGameObject("encounterControl"):CallScript("rbrMusicWave4CSJotDeath")
  end
end
function LuaHook_AddBlood_Jotunn_Intro_Arm(ai, data)
  local player = game.Player.FindPlayer()
  player:AddBlood(game.GameObject.eRegionId.kHead, 0.05)
  player:AddBlood(game.GameObject.eRegionId.kLeftChest, 0.1)
  player:AddBlood(game.GameObject.eRegionId.kRightChest, 0.1)
  player:AddBlood(game.GameObject.eRegionId.kFrontAbdomen, 0.1)
  player:AddBlood(game.GameObject.eRegionId.kRightFrontUpperArm, 0.2)
  player:AddBlood(game.GameObject.eRegionId.kRightFrontLowerArm, 0.4)
  player:AddBlood(game.GameObject.eRegionId.kLeftBack, 0.1)
  player:AddBlood(game.GameObject.eRegionId.kRightBack, 0.1)
  player:AddBlood(game.GameObject.eRegionId.kRightBackUpperArm, 0.2)
  player:AddBlood(game.GameObject.eRegionId.kRightBackLowerArm, 0.4)
end
function LuaHook_AddBlood_Jotunn_Intro_Axe(ai, data)
  local player = game.Player.FindPlayer()
  player:AddBlood(game.GameObject.eRegionId.kHead, 0.8)
  player:AddBlood(game.GameObject.eRegionId.kLeftChest, 1)
  player:AddBlood(game.GameObject.eRegionId.kRightChest, 1)
  player:AddBlood(game.GameObject.eRegionId.kFrontAbdomen, 1)
  player:AddBlood(game.GameObject.eRegionId.kLeftFrontUpperArm, 0.8)
  player:AddBlood(game.GameObject.eRegionId.kLeftFrontLowerArm, 0.6)
  player:AddBlood(game.GameObject.eRegionId.kRightFrontUpperArm, 0.8)
  player:AddBlood(game.GameObject.eRegionId.kRightFrontLowerArm, 0.6)
  player:AddBlood(game.GameObject.eRegionId.kLeftFrontLeg, 0.6)
  player:AddBlood(game.GameObject.eRegionId.kRightFrontLeg, 0.6)
  player:AddBlood(game.GameObject.eRegionId.kLeftBack, 0.4)
  player:AddBlood(game.GameObject.eRegionId.kRightBack, 0.4)
  player:AddBlood(game.GameObject.eRegionId.kBackAbdomen, 0.6)
  player:AddBlood(game.GameObject.eRegionId.kLeftBackUpperArm, 0.6)
  player:AddBlood(game.GameObject.eRegionId.kLeftBackLowerArm, 0.4)
  player:AddBlood(game.GameObject.eRegionId.kRightBackUpperArm, 0.6)
  player:AddBlood(game.GameObject.eRegionId.kRightBackLowerArm, 0.4)
  player:AddBlood(game.GameObject.eRegionId.kLeftBackLeg, 0.4)
  player:AddBlood(game.GameObject.eRegionId.kRightBackLeg, 0.4)
end
function LuaHook_AddBlood_Jotunn_RageEnter(ai, data)
  local player = game.Player.FindPlayer()
  player:AddBlood(game.GameObject.eRegionId.kHead, 0.4)
  player:AddBlood(game.GameObject.eRegionId.kLeftChest, 0.6)
  player:AddBlood(game.GameObject.eRegionId.kRightChest, 0.6)
  player:AddBlood(game.GameObject.eRegionId.kFrontAbdomen, 0.6)
  player:AddBlood(game.GameObject.eRegionId.kLeftFrontUpperArm, 0.2)
  player:AddBlood(game.GameObject.eRegionId.kLeftFrontLowerArm, 0.4)
  player:AddBlood(game.GameObject.eRegionId.kRightFrontUpperArm, 0.2)
  player:AddBlood(game.GameObject.eRegionId.kRightFrontLowerArm, 0.4)
  player:AddBlood(game.GameObject.eRegionId.kLeftFrontLeg, 0.2)
  player:AddBlood(game.GameObject.eRegionId.kRightFrontLeg, 0.2)
  player:AddBlood(game.GameObject.eRegionId.kLeftBack, 0.2)
  player:AddBlood(game.GameObject.eRegionId.kRightBack, 0.2)
  player:AddBlood(game.GameObject.eRegionId.kBackAbdomen, 0.4)
  player:AddBlood(game.GameObject.eRegionId.kLeftBackUpperArm, 0.2)
  player:AddBlood(game.GameObject.eRegionId.kLeftBackLowerArm, 0.4)
  player:AddBlood(game.GameObject.eRegionId.kRightBackUpperArm, 0.2)
  player:AddBlood(game.GameObject.eRegionId.kRightBackLowerArm, 0.4)
  player:AddBlood(game.GameObject.eRegionId.kLeftBackLeg, 0.2)
  player:AddBlood(game.GameObject.eRegionId.kRightBackLeg, 0.2)
end
function LuaHook_AddBlood_Jotunn_RageBeatDown(ai, data)
  local player = game.Player.FindPlayer()
  player:AddBlood(game.GameObject.eRegionId.kHead, 0.1)
  player:AddBlood(game.GameObject.eRegionId.kLeftChest, 0.4)
  player:AddBlood(game.GameObject.eRegionId.kRightChest, 0.4)
  player:AddBlood(game.GameObject.eRegionId.kFrontAbdomen, 0.4)
  player:AddBlood(game.GameObject.eRegionId.kLeftFrontUpperArm, 0.6)
  player:AddBlood(game.GameObject.eRegionId.kLeftFrontLowerArm, 0.6)
  player:AddBlood(game.GameObject.eRegionId.kRightFrontUpperArm, 0.4)
  player:AddBlood(game.GameObject.eRegionId.kRightFrontLowerArm, 0.4)
  player:AddBlood(game.GameObject.eRegionId.kLeftBackUpperArm, 0.4)
  player:AddBlood(game.GameObject.eRegionId.kLeftBackLowerArm, 0.4)
  player:AddBlood(game.GameObject.eRegionId.kRightBackUpperArm, 0.2)
  player:AddBlood(game.GameObject.eRegionId.kRightBackLowerArm, 0.2)
end
function LuaHook_AddBlood_Jotunn_RageFinisher(ai, data)
  local player = game.Player.FindPlayer()
  player:AddBlood(game.GameObject.eRegionId.kHead, 0.8)
  player:AddBlood(game.GameObject.eRegionId.kLeftChest, 1)
  player:AddBlood(game.GameObject.eRegionId.kRightChest, 1)
  player:AddBlood(game.GameObject.eRegionId.kFrontAbdomen, 1)
  player:AddBlood(game.GameObject.eRegionId.kLeftFrontUpperArm, 0.8)
  player:AddBlood(game.GameObject.eRegionId.kLeftFrontLowerArm, 0.6)
  player:AddBlood(game.GameObject.eRegionId.kRightFrontUpperArm, 0.8)
  player:AddBlood(game.GameObject.eRegionId.kRightFrontLowerArm, 0.6)
  player:AddBlood(game.GameObject.eRegionId.kLeftFrontLeg, 0.6)
  player:AddBlood(game.GameObject.eRegionId.kRightFrontLeg, 0.6)
  player:AddBlood(game.GameObject.eRegionId.kLeftBack, 0.4)
  player:AddBlood(game.GameObject.eRegionId.kRightBack, 0.4)
  player:AddBlood(game.GameObject.eRegionId.kBackAbdomen, 0.6)
  player:AddBlood(game.GameObject.eRegionId.kLeftBackUpperArm, 0.6)
  player:AddBlood(game.GameObject.eRegionId.kLeftBackLowerArm, 0.4)
  player:AddBlood(game.GameObject.eRegionId.kRightBackUpperArm, 0.6)
  player:AddBlood(game.GameObject.eRegionId.kRightBackLowerArm, 0.4)
  player:AddBlood(game.GameObject.eRegionId.kLeftBackLeg, 0.4)
  player:AddBlood(game.GameObject.eRegionId.kRightBackLeg, 0.4)
end
function LuaHook_AddBlood_Jotunn_Slam(ai, data)
  local player = game.Player.FindPlayer()
  player:AddBlood(game.GameObject.eRegionId.kHead, 0.6)
  player:AddBlood(game.GameObject.eRegionId.kLeftChest, 0.8)
  player:AddBlood(game.GameObject.eRegionId.kRightChest, 0.8)
  player:AddBlood(game.GameObject.eRegionId.kFrontAbdomen, 0.8)
  player:AddBlood(game.GameObject.eRegionId.kLeftFrontUpperArm, 0.6)
  player:AddBlood(game.GameObject.eRegionId.kLeftFrontLowerArm, 0.4)
  player:AddBlood(game.GameObject.eRegionId.kRightFrontUpperArm, 0.6)
  player:AddBlood(game.GameObject.eRegionId.kRightFrontLowerArm, 0.4)
  player:AddBlood(game.GameObject.eRegionId.kLeftBack, 0.8)
  player:AddBlood(game.GameObject.eRegionId.kRightBack, 0.8)
  player:AddBlood(game.GameObject.eRegionId.kBackAbdomen, 0.8)
  player:AddBlood(game.GameObject.eRegionId.kLeftBackUpperArm, 0.4)
  player:AddBlood(game.GameObject.eRegionId.kLeftBackLowerArm, 0.2)
  player:AddBlood(game.GameObject.eRegionId.kRightBackUpperArm, 0.4)
  player:AddBlood(game.GameObject.eRegionId.kRightBackLowerArm, 0.2)
end
function LuaHook_AddBlood_Jotunn_SlamDeath(ai, data)
  local player = game.Player.FindPlayer()
  player:AddBlood(game.GameObject.eRegionId.kHead, 0.8)
  player:AddBlood(game.GameObject.eRegionId.kLeftChest, 1)
  player:AddBlood(game.GameObject.eRegionId.kRightChest, 1)
  player:AddBlood(game.GameObject.eRegionId.kFrontAbdomen, 1)
  player:AddBlood(game.GameObject.eRegionId.kLeftFrontUpperArm, 0.8)
  player:AddBlood(game.GameObject.eRegionId.kLeftFrontLowerArm, 0.6)
  player:AddBlood(game.GameObject.eRegionId.kRightFrontUpperArm, 0.8)
  player:AddBlood(game.GameObject.eRegionId.kRightFrontLowerArm, 0.6)
  player:AddBlood(game.GameObject.eRegionId.kLeftFrontLeg, 0.6)
  player:AddBlood(game.GameObject.eRegionId.kRightFrontLeg, 0.6)
  player:AddBlood(game.GameObject.eRegionId.kLeftBack, 1)
  player:AddBlood(game.GameObject.eRegionId.kRightBack, 1)
  player:AddBlood(game.GameObject.eRegionId.kBackAbdomen, 1)
  player:AddBlood(game.GameObject.eRegionId.kLeftBackUpperArm, 0.8)
  player:AddBlood(game.GameObject.eRegionId.kLeftBackLowerArm, 0.6)
  player:AddBlood(game.GameObject.eRegionId.kRightBackUpperArm, 0.8)
  player:AddBlood(game.GameObject.eRegionId.kRightBackLowerArm, 0.6)
  player:AddBlood(game.GameObject.eRegionId.kLeftBackLeg, 0.6)
  player:AddBlood(game.GameObject.eRegionId.kRightBackLeg, 0.6)
end
