local U=require("\109\111\115\101\115")local e=require("\112\108\046\099\108\097\115\115")local Q=require("\115\117\112\112\111\114\116\046\102\097\099\116\111\114\121")local R=require("\105\110\118\111\107\097\116\105\111\110\046\099\111\110\115\116\046\105\110\118\101\110\116\111\114\121")CDOTA_BaseNPC=e(CBaseFlex)local k={hasInventory=false,level=1;maxHealth=0;health=0;maxMana=0;mana=0}function CDOTA_BaseNPC._init(Q,e)local R={abilities={},inventory={}}Q:super(U.extend(R,k,e or{}))end function CDOTA_BaseNPC.GetUnitName(U)return U:GetName()end function CDOTA_BaseNPC.GetPlayerOwner(U)return U.playerOwner end function CDOTA_BaseNPC.ForceKill(e,U)e.alive=U end function CDOTA_BaseNPC.GetLevel(U)return U.level end function CDOTA_BaseNPC.SetLevel(e,U)e.level=U end function CDOTA_BaseNPC.GetMaxHealth(U)return U.maxHealth end function CDOTA_BaseNPC.GetHealth(U)return U.health end function CDOTA_BaseNPC.Heal(Q,U,e)local R=Q.health+U Q.health=R>Q.maxHealth and Q.maxHealth or R end function CDOTA_BaseNPC.GetMaxMana(U)return U.maxMana end function CDOTA_BaseNPC.GetMana(U)return U.mana end function CDOTA_BaseNPC.GiveMana(e,U)local Q=e.mana+U e.mana=Q>e.maxMana and e.maxMana or Q end function CDOTA_BaseNPC.GetAbilityCount(U)return 24 end function CDOTA_BaseNPC.GetAbilityByIndex(e,U)return e.abilities[U]end function CDOTA_BaseNPC.FindAbilityByName(e,U)for Q=1,e:GetAbilityCount(),1 do local R=e.abilities[Q]if R~=nil and R:GetAbilityName()==U then return R end end return nil end function CDOTA_BaseNPC.AddAbility(e,U)local R=e:FindAbilityByName(U)if R~=nil then return R end R=Q.create("\100\111\116\097\095\097\098\105\108\105\116\121",{name=U})table.insert(e.abilities,R)R:SetAbilityIndex(#e.abilities)return R end function CDOTA_BaseNPC.HasInventory(U)return U.hasInventory end function CDOTA_BaseNPC.findInventorySlot(e,U)if not e:HasInventory()then return nil end for Q,R in ipairs(R.SLOTS)do if U(e.inventory[R],R)then return R end end return nil end function CDOTA_BaseNPC.findFreeInventorySlot(U)return U:findInventorySlot(function(U)return U==nil end)end function CDOTA_BaseNPC.findItemSlot(e,U)return e:findInventorySlot(function(e)return e~=nil and e:GetEntityIndex()==U:GetEntityIndex()end)end function CDOTA_BaseNPC.findItemSlotByName(e,U)return e:findInventorySlot(function(e)return e~=nil and e:GetAbilityName()==U end)end function CDOTA_BaseNPC.HasItemInInventory(e,U)return e:findItemSlotByName(U)~=nil end function CDOTA_BaseNPC.GetItemInSlot(e,U)if not e:HasInventory()then return nil end return e.inventory[U]end function CDOTA_BaseNPC.AddItemByName(e,U)if not e:HasInventory()then return nil end local Q=e:findFreeInventorySlot()if Q==nil then return nil end e.inventory[Q]=CDOTA_Item({name=U})return e.inventory[Q]end function CDOTA_BaseNPC.RemoveItem(e,U)if not e:HasInventory()then return end local Q=e:findItemSlot(U)if Q~=nil then e.inventory[Q]=nil end return Q end function CDOTA_BaseNPC.SetIdleAcquire(e,U)e.idleAcquire=U end function CDOTA_BaseNPC.Hold(U) end function CDOTA_BaseNPC.Purge(A,U,e,Q,R,k) end
local m = require("moses")
local class = require("pl.class")
local Factory = require("support.factory")

local INVENTORY = require("invokation.const.inventory")

-- selene: allow(incorrect_standard_library_use)
CDOTA_BaseNPC = class(CBaseFlex)

local DEFAULTS = { hasInventory = false, level = 1, maxHealth = 0, health = 0, maxMana = 0, mana = 0 }

function CDOTA_BaseNPC:_init(attributes)
  local baseAttributes = { abilities = {}, inventory = {} }
  self:super(m.extend(baseAttributes, DEFAULTS, attributes or {}))
end

function CDOTA_BaseNPC:GetUnitName()
  return self:GetName()
end

function CDOTA_BaseNPC:GetPlayerOwner()
  return self.playerOwner
end

function CDOTA_BaseNPC:ForceKill(reincarnate)
  self.alive = reincarnate
end

function CDOTA_BaseNPC:GetLevel()
  return self.level
end

-- not part of Dota2's scripting API
function CDOTA_BaseNPC:SetLevel(level)
  self.level = level
end

function CDOTA_BaseNPC:GetMaxHealth()
  return self.maxHealth
end

function CDOTA_BaseNPC:GetHealth()
  return self.health
end

function CDOTA_BaseNPC:Heal(amount, _source)
  local health = self.health + amount
  self.health = health > self.maxHealth and self.maxHealth or health
end

function CDOTA_BaseNPC:GetMaxMana()
  return self.maxMana
end

function CDOTA_BaseNPC:GetMana()
  return self.mana
end

function CDOTA_BaseNPC:GiveMana(amount)
  local mana = self.mana + amount
  self.mana = mana > self.maxMana and self.maxMana or mana
end

function CDOTA_BaseNPC:GetAbilityCount()
  return 24
end

function CDOTA_BaseNPC:GetAbilityByIndex(i)
  return self.abilities[i]
end

function CDOTA_BaseNPC:FindAbilityByName(name)
  for i = 1, self:GetAbilityCount() do
    local ability = self.abilities[i]
    if ability ~= nil and ability:GetAbilityName() == name then
      return ability
    end
  end

  return nil
end

function CDOTA_BaseNPC:AddAbility(name)
  local ability = self:FindAbilityByName(name)

  if ability ~= nil then
    return ability
  end

  ability = Factory.create("dota_ability", { name = name })

  table.insert(self.abilities, ability)
  ability:SetAbilityIndex(#self.abilities)

  return ability
end

function CDOTA_BaseNPC:HasInventory()
  return self.hasInventory
end

-- not part of Dota2's scripting API
function CDOTA_BaseNPC:findInventorySlot(predicate)
  if not self:HasInventory() then
    return nil
  end

  for _, slot in ipairs(INVENTORY.SLOTS) do
    if predicate(self.inventory[slot], slot) then
      return slot
    end
  end

  return nil
end

-- not part of Dota2's scripting API
function CDOTA_BaseNPC:findFreeInventorySlot()
  return self:findInventorySlot(function(item)
    return item == nil
  end)
end

-- not part of Dota2's scripting API
function CDOTA_BaseNPC:findItemSlot(item)
  return self:findInventorySlot(function(it)
    return it ~= nil and (it:GetEntityIndex() == item:GetEntityIndex())
  end)
end

-- not part of Dota2's scripting API
function CDOTA_BaseNPC:findItemSlotByName(name)
  return self:findInventorySlot(function(it)
    return it ~= nil and (it:GetAbilityName() == name)
  end)
end

function CDOTA_BaseNPC:HasItemInInventory(name)
  return self:findItemSlotByName(name) ~= nil
end

function CDOTA_BaseNPC:GetItemInSlot(slot)
  if not self:HasInventory() then
    return nil
  end

  return self.inventory[slot]
end

function CDOTA_BaseNPC:AddItemByName(name)
  if not self:HasInventory() then
    return nil
  end

  local slot = self:findFreeInventorySlot()

  if slot == nil then
    return nil
  end

  self.inventory[slot] = CDOTA_Item({ name = name })

  return self.inventory[slot]
end

function CDOTA_BaseNPC:RemoveItem(item)
  if not self:HasInventory() then
    return
  end

  local slot = self:findItemSlot(item)

  if slot ~= nil then
    self.inventory[slot] = nil
  end

  return slot
end

function CDOTA_BaseNPC:SetIdleAcquire(value)
  self.idleAcquire = value
end

function CDOTA_BaseNPC:Hold() end
function CDOTA_BaseNPC:Purge(_removeBuffs, _removeDebuffs, _frameOnly, _removeStuns, _removeExceptions) end
