local K=require("\109\111\115\101\115")local r=require("\115\117\112\112\111\114\116\046\102\097\099\116\111\114\121")local A=require("\105\110\118\111\107\097\116\105\111\110\046\100\111\116\097\050\046\107\118\046\072\101\114\111\075\101\121\086\097\108\117\101\115")local a=require("\105\110\118\111\107\097\116\105\111\110\046\099\111\110\115\116\046\117\110\105\116\115")local W=require("\105\110\118\111\107\097\116\105\111\110\046\099\111\110\115\116\046\104\101\114\111\101\115")r.define("\100\111\116\097\095\104\101\114\111",function(r,a)r=r or{}local Z=W.KEY_VALUES[r.name]or{}r=K.extend({},Z,r)a=a or{}local H=A(r.name,r)local d=CDOTA_BaseNPC_Hero(r,{kv=H})if K.isTable(a.gold)then if K.isNumber(a.gold.reliable)then d:ModifyGold(a.gold.reliable,true,0)end if K.isNumber(a.gold.unreliable)then d:ModifyGold(a.gold.unreliable,false,0)end elseif K.isNumber(a.gold)then d:ModifyGold(a.gold,true,0)end if K.isArray(a.items)then for K,r in ipairs(a.items)do d:AddItemByName(r)end end for K,r in ipairs(H:Abilities())do d:AddAbility(r)end if K.isArray(a.abilities)then for K,r in ipairs(a.abilities)do d:AddAbility(r)end elseif K.isTable(a.abilities)then for K,r in pairs(a.abilities)do local A=d:AddAbility(K)A:SetLevel(r)end end return d end)r.define("\100\111\116\097\095\104\101\114\111\095\105\110\118\111\107\101\114",function(A,W)A=K.extend({},{name=a.INVOKER},A or{})return r.create("\100\111\116\097\095\104\101\114\111",A,W)end)
local m = require("moses")
local Factory = require("support.factory")
local HeroKeyValues = require("invokation.dota2.kv.HeroKeyValues")

local UNITS = require("invokation.const.units")
local HEROES = require("invokation.const.heroes")

Factory.define("dota_hero", function(attributes, options)
  attributes = attributes or {}

  local kvData = HEROES.KEY_VALUES[attributes.name] or {}

  attributes = m.extend({}, kvData, attributes)
  options = options or {}

  local kv = HeroKeyValues(attributes.name, attributes)
  local hero = CDOTA_BaseNPC_Hero(attributes, { kv = kv })

  if m.isTable(options.gold) then
    if m.isNumber(options.gold.reliable) then
      hero:ModifyGold(options.gold.reliable, true, 0)
    end

    if m.isNumber(options.gold.unreliable) then
      hero:ModifyGold(options.gold.unreliable, false, 0)
    end
  elseif m.isNumber(options.gold) then
    hero:ModifyGold(options.gold, true, 0)
  end

  if m.isArray(options.items) then
    for _, name in ipairs(options.items) do
      hero:AddItemByName(name)
    end
  end

  for _, name in ipairs(kv:Abilities()) do
    hero:AddAbility(name)
  end

  if m.isArray(options.abilities) then
    for _, name in ipairs(options.abilities) do
      hero:AddAbility(name)
    end
  elseif m.isTable(options.abilities) then
    for name, level in pairs(options.abilities) do
      local ability = hero:AddAbility(name)
      ability:SetLevel(level)
    end
  end

  return hero
end)

Factory.define("dota_hero_invoker", function(attributes, options)
  attributes = m.extend({}, { name = UNITS.INVOKER }, attributes or {})
  return Factory.create("dota_hero", attributes, options)
end)
