local LD = require("design.LevelDesignLibrary")
local timer = require("level.timer")
local thisObj, thisLevel, markerZoneObj, objectMarkerName, player
local axeEmbedded = false
local GO_CombatCollision, OnWeaponEmbedCallbacks, OnWeaponUnembedCallbacks, timer_CombatColl
local delayToDamageAppear = 1.25
local delayToDamageFade = 0.5
local poisonOnParticles = {
  cloudLoop = "PoisonCloudOn_Loop",
  cloud = "PoisonCloudOn",
  pole = "ScornPole_root",
  iceFx = "IceFX_On"
}
local poisonOffParticles = {
  cloudLoop = "PoisonCloudOff_Loop",
  cloud = "PoisonCloudOff",
  pole = "ScornPoleOff",
  iceFx = "IceFX_Off"
}
local disableNoGoZone
function OnScriptLoaded(level, obj)
  thisObj = obj
  thisLevel = level
  player = game.Player.FindPlayer()
  poisonOnParticles.pole = thisObj:FindSingleGOByName(poisonOnParticles.pole)
  poisonOnParticles.cloud = thisObj:FindSingleGOByName(poisonOnParticles.cloud)
  poisonOnParticles.cloudLoop = thisObj:FindSingleGOByName(poisonOnParticles.cloudLoop)
  poisonOnParticles.iceFx = thisObj:FindSingleGOByName(poisonOnParticles.iceFx).Child
  poisonOffParticles.cloudLoop = thisObj:FindSingleGOByName(poisonOffParticles.cloudLoop)
  poisonOffParticles.cloud = thisObj:FindSingleGOByName(poisonOffParticles.cloud)
  poisonOffParticles.pole = thisObj:FindSingleGOByName(poisonOffParticles.pole)
  poisonOffParticles.iceFx = thisObj:FindSingleGOByName(poisonOffParticles.iceFx).Child
  GO_CombatCollision = thisObj:FindSingleGOByName("CombatCollision")
  OnWeaponEmbedCallbacks = LD.ExtractCallbacksForEvent(thisLevel, thisObj, thisObj:GetLuaTableAttribute("Event_OnWeaponEmbed"))
  OnWeaponUnembedCallbacks = LD.ExtractCallbacksForEvent(thisLevel, thisObj, thisObj:GetLuaTableAttribute("Event_OnWeaponUnembed"))
  disableNoGoZone = thisObj:GetLuaTableAttribute("Disable_NoGoZones")
  SoundInit()
  local TriggerCollision = thisObj:FindSingleGOByName("TriggerCollision")
  TriggerCollision.LuaObjectScript.RegisterOnWeaponEmbed(Ice)
  TriggerCollision.LuaObjectScript.RegisterOnWeaponUnembed(DeIce)
  objectMarkerName = tostring(thisObj.Parent:GetName()) .. "_Marker"
  markerZoneObj = thisObj:FindSingleGOByName("ScornAreaMarkerZone")
  game.SubObject.SetEntityZoneHandler(thisObj, markerZoneObj)
  game.SubObject.SetEntityZoneHandler(thisObj, thisObj)
  game.SubObject.Sleep(thisObj)
end
function OnSaveCheckpoint(level, obj)
  return {axeEmbedded = axeEmbedded}
end
function OnRestoreCheckpoint(level, obj, savedInfo)
  axeEmbedded = savedInfo.axeEmbedded
end
function OnFirstStart(level, obj)
  DisableEmitters(poisonOffParticles.cloudLoop, true)
  DisableEmitters(poisonOffParticles.cloud, true)
  DisableEmitters(poisonOffParticles.pole, true)
  poisonOnParticles.iceFx:HideModel()
  LD.HideFX(poisonOnParticles.iceFx, {immediate = true})
  poisonOffParticles.iceFx:HideModel()
  LD.HideFX(poisonOffParticles.iceFx, {immediate = true})
  if disableNoGoZone then
    thisObj:HideNavObstacle()
  end
end
function OnStart(level, obj)
  local TriggerCollision = thisObj:FindSingleGOByName("TriggerCollision")
  if axeEmbedded and TriggerCollision:IsAxeEmbedded() == false then
    DeIceFast()
  end
  if player:IsInsideEntityZone(markerZoneObj) then
    OnMarkerEnterZone(level, thisObj, markerZoneObj, player, game.LargeInteger.HashString(3))
  end
  if player:IsInsideEntityZone(thisObj) then
    OnMarkerEnterZone(level, thisObj, thisObj, player, game.LargeInteger.HashString(3))
  end
end
function Ice()
  axeEmbedded = true
  LD.ExecuteCallbacksForEvent(thisLevel, thisObj, OnWeaponEmbedCallbacks, "Event_OnWeaponEmbed")
  if timer_CombatColl ~= nil and timer_CombatColl.fired == false then
    timer_CombatColl:Stop()
  end
  timer_CombatColl = timer.StartLevelTimer(delayToDamageFade, function()
    GO_CombatCollision.LuaObjectScript.Disable()
  end)
  DisableEmitters(thisObj, true)
  DisableEmitters(poisonOnParticles.cloudLoop, true)
  DisableEmitters(poisonOnParticles.cloud)
  DisableEmitters(poisonOnParticles.pole)
  LD.ShowFX(poisonOnParticles.iceFx)
  EnableEmitters(poisonOffParticles.cloudLoop, true)
  EnableEmitters(poisonOffParticles.cloud)
  EnableEmitters(poisonOffParticles.pole)
  thisObj:HideNavObstacle()
  HideEntityZones()
  PlaySoundOnIce()
  StopSoundPoisonOff()
end
function DeIce()
  axeEmbedded = false
  LD.ExecuteCallbacksForEvent(thisLevel, thisObj, OnWeaponUnembedCallbacks, "Event_OnWeaponUnembed")
  EnableEmitters(thisObj, true)
  EnableEmitters(poisonOnParticles.cloudLoop, true)
  EnableEmitters(poisonOnParticles.cloud)
  EnableEmitters(poisonOnParticles.pole)
  poisonOnParticles.iceFx:HideModel()
  LD.HideFX(poisonOnParticles.iceFx, {immediate = true})
  DisableEmitters(poisonOffParticles.cloudLoop, true)
  DisableEmitters(poisonOffParticles.cloud, true)
  DisableEmitters(poisonOffParticles.pole, true)
  LD.ShowFX(poisonOffParticles.iceFx)
  poisonOffParticles.iceFx:OnAnimDone(thisObj, "OnDeIceFinish")
  if not disableNoGoZone then
    thisObj:ShowNavObstacle()
  end
  ShowEntityZones()
  PlaySoundPoisonOn()
  StopSoundIceOff()
  if timer_CombatColl ~= nil and timer_CombatColl.fired == false then
    timer_CombatColl:Stop()
  end
  timer_CombatColl = timer.StartLevelTimer(delayToDamageAppear, function()
    GO_CombatCollision.LuaObjectScript.Enable()
  end)
end
function DeIceFast()
  axeEmbedded = false
  LD.ExecuteCallbacksForEvent(thisLevel, thisObj, OnWeaponUnembedCallbacks, "Event_OnWeaponUnembed")
  EnableEmitters(thisObj, true)
  EnableEmitters(poisonOnParticles.cloudLoop, true)
  EnableEmitters(poisonOnParticles.cloud)
  EnableEmitters(poisonOnParticles.pole)
  poisonOnParticles.iceFx:HideModel()
  LD.HideFX(poisonOnParticles.iceFx, {immediate = true})
  DisableEmitters(poisonOffParticles.cloudLoop, true)
  DisableEmitters(poisonOffParticles.cloud, true)
  DisableEmitters(poisonOffParticles.pole, true)
  LD.ShowFX(poisonOffParticles.iceFx)
  poisonOffParticles.iceFx:OnAnimDone(thisObj, "OnDeIceFinish")
  if not disableNoGoZone then
    thisObj:ShowNavObstacle()
  end
  ShowEntityZones()
  PlaySoundPoisonOn()
  if timer_CombatColl ~= nil and timer_CombatColl.fired == false then
    timer_CombatColl:Stop()
  end
  GO_CombatCollision.LuaObjectScript.Enable()
end
function OnDeIceFinish()
  LD.HideFX(poisonOffParticles.iceFx, {immediate = true})
  poisonOffParticles.iceFx:HideModel()
end
function EnableEmitters(obj, loopAnim)
  if obj ~= nil then
    obj:ShowModel()
    obj:ShowParticleEmitter()
    obj:ShowLights()
    obj:JumpAnimToFrame(0)
    if loopAnim then
      obj:PlayAnimCycle()
    else
      obj:PlayAnimToEnd()
    end
  end
end
function DisableEmitters(obj, hideModel)
  if obj ~= nil then
    obj:PauseAnim()
    obj:HideParticleEmitter()
    obj:HideLights()
    if hideModel then
      obj:HideModel()
    end
  end
end
function Enable()
  EnableEmitters(thisObj, true)
  EnableEmitters(poisonOnParticles.pole)
  EnableEmitters(poisonOnParticles.cloudLoop, true)
  EnableEmitters(poisonOnParticles.cloud)
  DisableEmitters(poisonOffParticles.cloudLoop, true)
  DisableEmitters(poisonOffParticles.cloud, true)
  DisableEmitters(poisonOffParticles.pole, true)
  if not disableNoGoZone then
    thisObj:ShowNavObstacle()
  end
  ShowEntityZones()
  local TriggerCollision = thisObj:FindSingleGOByName("TriggerCollision")
  TriggerCollision:Show()
  PlaySoundPoisonOn()
  timer_CombatColl = timer.StartLevelTimer(1, function()
    GO_CombatCollision.LuaObjectScript.Enable()
  end)
end
function CustomDisable_Cal250()
  axeEmbedded = false
  poisonOnParticles.iceFx:HideModel()
  LD.HideFX(poisonOnParticles.iceFx, {immediate = true})
  Disable()
end
function Disable()
  if timer_CombatColl ~= nil and timer_CombatColl.fired == false then
    timer_CombatColl:Finish()
  end
  timer_CombatColl = nil
  GO_CombatCollision.LuaObjectScript.Disable()
  local TriggerCollision = thisObj:FindSingleGOByName("TriggerCollision")
  TriggerCollision:Hide()
  DisableEmitters(thisObj, true)
  DisableEmitters(poisonOnParticles.pole)
  DisableEmitters(poisonOffParticles.cloudLoop, true)
  DisableEmitters(poisonOffParticles.cloud)
  local tempVFXs = thisObj:FindSingleGOByName("Scorn_Pole_Turnoff")
  EnableEmitters(tempVFXs)
  thisObj:HideNavObstacle()
  HideEntityZones()
  StopSoundPoisonOff()
end
function HideEntityZones()
  thisObj:HideEntityVolume()
  markerZoneObj:HideEntityVolume()
end
function ShowEntityZones()
  thisObj:ShowEntityVolume()
  markerZoneObj:ShowEntityVolume()
end
local markerObjInEntityZone = false
function OnMarkerEnterZone(level, scriptObj, volumeGameObject, markerGameObject, markerId)
  if game.LargeInteger.HashString(objectMarkerName) == markerId and volumeGameObject == markerZoneObj then
    player:CallScript("LuaHook_DisableRevive", true)
    markerObjInEntityZone = true
  end
  if game.LargeInteger.HashString(3) == markerId or game.LargeInteger.HashString(3) == game.LargeInteger.HashString(tostring(markerId)) then
    if volumeGameObject == markerZoneObj and not player:HasMarker(objectMarkerName) then
      player:AddMarkerPointTest(objectMarkerName, player:GetJointIndex("defense02_shoulders"))
    elseif volumeGameObject == thisObj then
      player:CallScript("LuaHook_DisableRevive", true)
    end
  end
end
function OnMarkerExitZone(level, scriptObj, volumeGameObject, markerGameObject, markerId)
  if game.LargeInteger.HashString(objectMarkerName) == markerId and player:IsDead() == false and player:IsDying() == false and volumeGameObject == markerZoneObj then
    player:CallScript("LuaHook_DisableRevive", false)
    markerObjInEntityZone = false
  end
  if game.LargeInteger.HashString(3) == markerId or game.LargeInteger.HashString(3) == game.LargeInteger.HashString(tostring(markerId)) then
    if volumeGameObject == markerZoneObj and player:HasMarker(objectMarkerName) then
      player:RemoveMarker(objectMarkerName)
    elseif volumeGameObject == thisObj and not markerObjInEntityZone then
      player:CallScript("LuaHook_DisableRevive", false)
    end
  end
end
local soundEmitterCloud, soundEmitterFire
local soundPosionDisable = false
local soundEvents = {
  isLooping = true,
  OnIce = "SND_WPN_Axe_Hit_Freeze_Object_LP",
  PoisonOn = "SND_TRAP_Scorn_Pole_Cloud_LP",
  FireOn = "SND_TRAP_Scorn_Pole_Fire_LP"
}
function SoundInit()
  soundEmitterCloud = GO_CombatCollision:FindSingleSoundEmitterByName("SNDPoisonCloudColl")
  soundEmitterFire = thisObj.Child.Child:FindSingleSoundEmitterByName("SNDPoisonCloudFire")
  LD.CallFunctionAfterDelay(function()
    if not soundPosionDisable then
      PlaySoundPoisonOn()
    end
  end, 0.3)
end
function SoundSetup(sounds)
  if sounds ~= nil then
    if sounds.SoundEmitterCloud ~= nil then
      soundEmitterCloud = thisObj:FindSingleSoundEmitterByName(sounds.SoundEmitterCloud)
    end
    if sounds.SoundEmitterFire ~= nil then
      soundEmitterFire = thisObj.Child.Child:FindSingleSoundEmitterByName(sounds.SoundEmitterFire)
    end
    for key, value in pairs(soundEvents) do
      for newKey, newValue in pairs(sounds) do
        if newKey == key and newValue ~= nil and newValue ~= "" then
          soundEvents[key] = newValue
        end
      end
      LD.SoundDebug(tostring(key) .. ": " .. tostring(value))
    end
  end
end
function PlaySoundPoisonOn()
  LD.PlayRestartableSoundLoop(soundEmitterCloud, soundEvents.PoisonOn)
  LD.PlayRestartableSoundLoop(soundEmitterFire, soundEvents.FireOn)
end
function StopSoundPoisonOff()
  LD.StopRestartableSoundLoop(soundEmitterCloud, soundEvents.PoisonOn)
  LD.StopRestartableSoundLoop(soundEmitterFire, soundEvents.FireOn)
end
function PlaySoundOnIce()
  LD.PlaySound(soundEmitterFire, soundEvents.OnIce)
end
function StopSoundIceOff()
  LD.StopSound(soundEmitterFire, soundEvents.OnIce)
end
function StopSoundPoisonDisable_Remote()
  soundPosionDisable = true
  StopSoundPoisonOff()
end
