local h=require("\105\110\118\111\107\097\116\105\111\110\046\100\111\116\097\050\046\073\110\118\111\107\101\114")local Y=require("\105\110\118\111\107\097\116\105\111\110\046\100\111\116\097\050\046\080\108\097\121\101\114")local q=require("\105\110\118\111\107\097\116\105\111\110\046\100\111\116\097\050\046\085\110\105\116")local t=require("\105\110\118\111\107\097\116\105\111\110\046\099\111\110\115\116\046\108\105\109\105\116\115")local I=require("\105\110\118\111\107\097\116\105\111\110\046\099\111\110\115\116\046\115\111\117\110\100\095\101\118\101\110\116\115")local x=require("\105\110\118\111\107\097\116\105\111\110\046\099\111\110\115\116\046\117\110\105\116\115")local m={}function m.setup(h,t)h=Y(h)local I=q(h.hero)I:HeroLevelUpTo(t.heroLevel)I:AddItemsByName(t.items or{},{onlyMissing=true})if t.gold~=nil then I:GiveGold(t.gold)end I:Hold()end function m.teardown(t,m)m=m or{}t=Y(t)local b=q(t.hero)b:StopSound(I.SNDEVT_INVOKER_METEOR_LOOP)b:EndItemCooldowns()b:EndAbilityCooldowns()b:RemoveDroppedItems()for h,Y in pairs(x.INVOKER_SPAWNED)do t:RemoveOwnedUnitsByName(Y)end if m.hardReset then local Y=h(t.hero)b:RemoveItems()Y:ResetAbilities()b:SetAbilityPoints(1)t:ReplaceHero(t.hero:GetUnitName())else b:Purge()b:GiveMaxHealth()b:GiveMaxMana()end end function m.refundPurchase(h,t)h=Y(h)local I=q(h.hero)I:GiveGold(t.cost)end function m.levelUp(I,x)x=x or{}I=Y(I)local m=q(I.hero)local b if x.level~=nil then b=x.level elseif x.maxLevel then b=t.MAX_HERO_LEVEL else b=m:GetLevel()+1 end m:HeroLevelUpTo(b,{playEffects=true})if b==t.MAX_HERO_LEVEL then local Y=h(I.hero)Y:LevelUpAbilities({maxLevel=true})end end return m
--- Internal combos hero helpers.
-- @module invokation.combos.hero
local Invoker = require("invokation.dota2.Invoker")
local Player = require("invokation.dota2.Player")
local Unit = require("invokation.dota2.Unit")

local LIMITS = require("invokation.const.limits")
local SOUND_EVENTS = require("invokation.const.sound_events")
local UNITS = require("invokation.const.units")

local M = {}

--- Runs the setup phase of a combo.
-- @tparam CDOTAPlayer player Player playing the combo
-- @tparam Combo combo Combo
function M.setup(player, combo)
  player = Player(player)

  local unit = Unit(player.hero)

  unit:HeroLevelUpTo(combo.heroLevel)
  unit:AddItemsByName(combo.items or {}, { onlyMissing = true })

  if combo.gold ~= nil then
    unit:GiveGold(combo.gold)
  end

  unit:Hold()
end

--- Runs the teardown phase of a combo.
-- @tparam CDOTAPlayer player Player playing the combo
-- @tparam table options Options table
-- @tparam bool options.hardReset Perform a full reset
function M.teardown(player, options)
  options = options or {}
  player = Player(player)

  local unit = Unit(player.hero)

  unit:StopSound(SOUND_EVENTS.SNDEVT_INVOKER_METEOR_LOOP)
  unit:EndItemCooldowns()
  unit:EndAbilityCooldowns()
  unit:RemoveDroppedItems()

  for _, unitName in pairs(UNITS.INVOKER_SPAWNED) do
    player:RemoveOwnedUnitsByName(unitName)
  end

  if options.hardReset then
    local invoker = Invoker(player.hero)

    unit:RemoveItems()
    -- Orbs reset must come before hero replacement
    invoker:ResetAbilities()
    unit:SetAbilityPoints(1)
    player:ReplaceHero(player.hero:GetUnitName())
  else
    unit:Purge()
    unit:GiveMaxHealth()
    unit:GiveMaxMana()
  end
end

--- Refunds a purchase made by a player's hero.
-- @tparam CDOTAPlayer player Player that made the purchase
-- @tparam Combos.Purchase purchase Purchase information
function M.refundPurchase(player, purchase)
  player = Player(player)

  local unit = Unit(player.hero)

  unit:GiveGold(purchase.cost)
end

--- Levels a player's hero up.
-- @tparam CDOTAPlayer player Player
-- @tparam Combos.LevelUpOptions options
function M.levelUp(player, options)
  options = options or {}
  player = Player(player)

  local unit = Unit(player.hero)
  local targetLevel

  if options.level ~= nil then
    targetLevel = options.level
  elseif options.maxLevel then
    targetLevel = LIMITS.MAX_HERO_LEVEL
  else
    targetLevel = unit:GetLevel() + 1
  end

  unit:HeroLevelUpTo(targetLevel, { playEffects = true })

  if targetLevel == LIMITS.MAX_HERO_LEVEL then
    local invoker = Invoker(player.hero)
    invoker:LevelUpAbilities({ maxLevel = true })
  end
end

return M
