Исходник пассивного предмета, где что-нибудь зависит от зарядов

  • Автор темы Автор темы Se7eN
  • Дата начала Дата начала

Se7eN

Друзья CG
22 Ноя 2014
334
18
Скиньте что-нибудь типо собираешь заряды, если их 5 то дается 5 ловкости и что-то подобное
 
Я делал так: сделал стакаемый предмет активным и когда пользователь на него нажимал, осуществлял проверку на наличие необходимого количества этой вещи. И если было достаточно, создавал новую.

Код:
 	"item_scroll_of_archangel"
  {
		"ID"							"1237" 
		"BaseClass"						"item_datadriven" 	
		"AbilityTextureName"			"scroll_of_archangel" 
		"AbilityBehavior"     		"DOTA_ABILITY_BEHAVIOR_NO_TARGET" 		
		"ItemCost"            "1" 
		"ItemAliases"					"item_scroll_of_archangel"
		"ItemDroppable"					"1" 
		"ItemPurchasable"				"0" 
		"ItemSellable"					"1" 
		"ItemKillable"					"1" 
		"ItemShareability"				"ITEM_FULLY_SHAREABLE" 
		"ItemDeclarations"				"DECLARE_PURCHASES_TO_TEAMMATES | DECLARE_PURCHASES_TO_SPECTATORS | DECLARE_PURCHASES_IN_SPEECH"
		"ItemInitialCharges" "1" 
		"ItemDisplayCharges" "1"
		"ItemStackable" "1"
		"ItemPermanent" "0"	
	
		"OnSpellStart"
		{
			"RunScript"
			{
				"ScriptFile"		"ai.lua"
				"Function"			"ChekTicket"				
				"PartName"			"item_scroll_of_archangel"
				"TicketName"		"item_cloak_of_invisibility"
				"item_name"			"item_scroll_of_archangel"				
			}			
		}
			
	}		
		
  }

Код:
function ChekTicket(data)

local caster = data.caster
local part_name = data.PartName
--print("chek")

if caster:HasItemInInventory(part_name) then
	local item = nil
	local charges = 0
	local first = 0
	for i = 0, 5 do
		item = caster:GetItemInSlot(i)
		if item ~= nil then
			if item:GetAbilityName() == part_name and first == 0 then
				if item:GetCurrentCharges() > 4 then
					charges = item:GetCurrentCharges()
					if charges == 5 then
						caster:RemoveItem(item)
						caster:AddItemByName(data.TicketName)
					else
						item:SetCurrentCharges(charges-5)
						if caster:HasAnyAvailableInventorySpace() then
							caster:AddItemByName(data.TicketName)
						else
							CreateDrop(data.TicketName, caster:GetAbsOrigin())
						end
					end
				end
			first = 1
			end
		end
	end
end
	
end
 
Последнее редактирование модератором:
Думаю, разберешься как под себя переделать.

Может и варианты попроще есть. Не помню, почему я вручную реализовывал.
 
Скиньте что-нибудь типо собираешь заряды, если их 5 то дается 5 ловкости и что-то подобное
Вот хороший пример
Код:
LinkLuaModifier ("modifier_item_frostmourne", "items/item_frostmourne.lua", LUA_MODIFIER_MOTION_NONE)
LinkLuaModifier ("modifier_item_frostmourne_slowing", "items/item_frostmourne.lua", LUA_MODIFIER_MOTION_NONE)
LinkLuaModifier ("modifier_item_frostmourne_soul_stole", "items/item_frostmourne.lua", LUA_MODIFIER_MOTION_NONE)

if item_frostmourne == nil then
  item_frostmourne = class ( {})
end

function item_frostmourne:GetIntrinsicModifierName ()
  return "modifier_item_frostmourne"
end

function item_frostmourne:OnHeroDiedNearby (hVictim, hKiller, kv)
  if hVictim == nil or hKiller == nil then
    return
  end

  if hVictim:GetTeamNumber () ~= self:GetCaster ():GetTeamNumber () and self:GetCaster ():IsAlive () then
    self.range = self:GetSpecialValueFor ("soul_stole_range")
    local vToCaster = self:GetCaster ():GetOrigin () - hVictim:GetOrigin ()
    local flDistance = vToCaster:Length2D ()
    if hKiller == self:GetCaster () or self.range >= flDistance then
      if self.nKills == nil then
        self.nKills = 0
      end

      self.nKills = self.nKills + 1
      self:GetCaster():CalculateStatBonus ()
      local nFXIndex = ParticleManager:CreateParticle ("particles/units/heroes/hero_pudge/pudge_fleshheap_count.vpcf", PATTACH_OVERHEAD_FOLLOW, self:GetCaster () )
      ParticleManager:SetParticleControl (nFXIndex, 1, Vector (1, 0, 0) )
      ParticleManager:ReleaseParticleIndex (nFXIndex)
    end
  end
end

--------------------------------------------------------------------------------

function item_frostmourne:GetFrostmourneStacks ()
  if self.nKills == nil then
    self.nKills = 1
  end
  local damage = self:GetSpecialValueFor ("soul_stole_stack_damage")
  local stacks = self.nKills * damage
  return stacks
end

--------------------------------------------------------------------------------
if modifier_item_frostmourne == nil then
  modifier_item_frostmourne = class ( {})
end

function modifier_item_frostmourne:IsHidden ()
  return true
end

function modifier_item_frostmourne:OnCreated (kv)
  if IsServer () then
    local hAbility = self:GetAbility ()
    self:SetStackCount (hAbility:GetFrostmourneStacks())
    self:GetParent ():CalculateStatBonus ()
    if not self:GetParent():HasModifier("modifier_item_frostmourne_soul_stole")  then
     self:GetParent ():AddNewModifier (self:GetCaster (), self:GetAbility (), "modifier_item_frostmourne_soul_stole", nil)
    end
  end
end

function modifier_item_frostmourne:OnDestroy(kv)
  if IsServer () then
    local hAbility = self:GetAbility ()
    self:SetStackCount (hAbility:GetFrostmourneStacks ())
    self:GetParent ():CalculateStatBonus ()
    self:GetParent ():RemoveModifierByName ("modifier_item_frostmourne_soul_stole")
  end
end

function modifier_item_frostmourne:DeclareFunctions ()
  local funcs = {
    MODIFIER_PROPERTY_HEALTH_BONUS,
    MODIFIER_PROPERTY_MANA_BONUS,
    MODIFIER_PROPERTY_STATS_AGILITY_BONUS,
    MODIFIER_PROPERTY_STATS_INTELLECT_BONUS,
    MODIFIER_PROPERTY_STATS_STRENGTH_BONUS,
    MODIFIER_PROPERTY_PREATTACK_BONUS_DAMAGE,
    MODIFIER_EVENT_ON_ATTACK_LANDED,
    MODIFIER_PROPERTY_REINCARNATION
  }

  return funcs
end

function modifier_item_frostmourne:OnRefresh (kv)
  if IsServer () then
    self:GetParent ():CalculateStatBonus ()
  end
end

function modifier_item_frostmourne:GetModifierPreAttack_BonusDamage (params)
  local hAbility = self:GetAbility ()
  return hAbility:GetSpecialValueFor ("bonus_damage")
end
function modifier_item_frostmourne:GetModifierBonusStats_Strength (params)
  local hAbility = self:GetAbility ()
  return hAbility:GetSpecialValueFor ("bonus_all_stats")
end
function modifier_item_frostmourne:GetModifierBonusStats_Intellect (params)
  local hAbility = self:GetAbility ()
  return hAbility:GetSpecialValueFor ("bonus_all_stats")
end
function modifier_item_frostmourne:GetModifierBonusStats_Agility (params)
  local hAbility = self:GetAbility ()
  return hAbility:GetSpecialValueFor ("bonus_all_stats")
end
function modifier_item_frostmourne:GetModifierHealthBonus (params)
  local hAbility = self:GetAbility ()
  return hAbility:GetSpecialValueFor ("bonus_health")
end
function modifier_item_frostmourne:GetModifierManaBonus (params)
  local hAbility = self:GetAbility ()
  return hAbility:GetSpecialValueFor ("bonus_mana")
end

function modifier_item_frostmourne:OnAttackLanded (params)
  if IsServer () then
    if params.attacker == self:GetParent () then
      local hAbility = self:GetAbility ()
      params.target:AddNewModifier (self:GetCaster (), self:GetAbility (), "modifier_item_frostmourne_slowing", { duration = 5 })
      local cold_attack_damage = hAbility:GetSpecialValueFor ("cold_attack_damage")
      EmitSoundOn ("Hero_Ancient_Apparition.Attack", params.target)
      ApplyDamage ( { attacker = hAbility:GetCaster (), victim = params.target, ability = hAbility, damage = cold_attack_damage, damage_type = DAMAGE_TYPE_PURE })
    end
  end
  return 0
end

function modifier_item_frostmourne:ReincarnateTime (params)
  if IsServer () then
    local parent = self:GetParent ()
    if self:GetAbility ():IsCooldownReady () then
      self:GetAbility ():StartCooldown (self:GetAbility ():GetCooldown (self:GetAbility ():GetLevel ()))

      local respawnPosition = parent:GetAbsOrigin ()

      local particleName = "particles/units/heroes/hero_skeletonking/wraith_king_reincarnate.vpcf"
      self.ReincarnateParticle = ParticleManager:CreateParticle (particleName, PATTACH_ABSORIGIN_FOLLOW, parent)
      ParticleManager:SetParticleControl (self.ReincarnateParticle, 0, respawnPosition)
      ParticleManager:SetParticleControl (self.ReincarnateParticle, 1, Vector (500, 0, 0))
      ParticleManager:SetParticleControl (self.ReincarnateParticle, 1, Vector (500, 500, 0))
      parent:EmitSound ("Hero_SkeletonKing.Reincarnate")
      parent:EmitSound ("Hero_SkeletonKing.Death")

      Timers:CreateTimer (3,
      function ()
        ParticleManager:DestroyParticle (self.ReincarnateParticle, false)
        parent:EmitSound ("Hero_SkeletonKing.Reincarnate.Stinger")

        if not self:GetParent ():IsAlive () then
          self:GetParent ():RespawnHero (false, false, false)
          self:GetParent ():SetAbsOrigin (respawnPosition)
        end
      end
      )
      return 3
    end
    return
  end
end

if modifier_item_frostmourne_slowing == nil then
  modifier_item_frostmourne_slowing = class ( {})
end

function modifier_item_frostmourne_slowing:IsBuff ()
  return false
end

function modifier_item_frostmourne_slowing:GetTexture ()
  return "item_frostmourne"
end

function modifier_item_frostmourne_slowing:DeclareFunctions ()
  local funcs = {
    MODIFIER_PROPERTY_ATTACKSPEED_BONUS_CONSTANT,
    MODIFIER_PROPERTY_MOVESPEED_BONUS_CONSTANT
  }

  return funcs
end

function modifier_item_frostmourne_slowing:GetStatusEffectName ()
  return "particles/status_fx/status_effect_frost.vpcf"
end

--------------------------------------------------------------------------------

function modifier_item_frostmourne_slowing:StatusEffectPriority ()
  return 1000
end

function modifier_item_frostmourne_slowing:GetModifierAttackSpeedBonus_Constant (params)
  local hAbility = self:GetAbility ()
  return hAbility:GetSpecialValueFor ("cold_attack_speed")
end

function modifier_item_frostmourne_slowing:GetModifierMoveSpeedBonus_Constant (params)
  local hAbility = self:GetAbility ()
  return hAbility:GetSpecialValueFor ("cold_movement_speed")
end

if modifier_item_frostmourne_soul_stole == nil then
  modifier_item_frostmourne_soul_stole = class ( {})
end

function modifier_item_frostmourne_soul_stole:IsHidden ()
  return true
end

function modifier_item_frostmourne_soul_stole:OnCreated (kv)
  if IsServer () then
    local hAbility = self:GetAbility ()
    self:SetStackCount (hAbility:GetFrostmourneStacks())
    self:GetParent ():CalculateStatBonus ()
    Timers:CreateTimer(0.1, function()
      if self:GetParent ():HasModifier ("modifier_item_frostmourne_soul_stole") then
        self:ForceRefresh ()
        return 0.1
      else
        return nil
      end
    end)
  end
end

function modifier_item_frostmourne_soul_stole:OnDestroy (kv)
  if IsServer () then
    self:GetParent ():CalculateStatBonus ()
  end
end

function modifier_item_frostmourne_soul_stole:DeclareFunctions ()
  local funcs = {
    MODIFIER_PROPERTY_PREATTACK_BONUS_DAMAGE
  }

  return funcs
end

function modifier_item_frostmourne_soul_stole:OnRefresh (kv)
  if IsServer () then
    local hAbility = self:GetAbility ()
    self:SetStackCount (hAbility:GetFrostmourneStacks ())
    self:GetParent ():CalculateStatBonus ()
  end
end

function modifier_item_frostmourne_soul_stole:GetModifierPreAttack_BonusDamage (params)
  local hAbility = self:GetAbility ()
  return self:GetStackCount () * 2
end
 
Последнее редактирование модератором:
Не, первое совсем не то.

А фростморн то, но кода слишком много.
Поищу чего-нибудь попроще)
 
Скиньте что-нибудь типо собираешь заряды, если их 5 то дается 5 ловкости и что-то подобное

Смотря как заряды собираются. Если через убийства кого-либо, то в датадривене можно в пару строчек.
Вот например, стаки на модификаторе при получении урона (OnTakeDamage):
Код:
local modifier = caster:FindModifierByName("modifier_shields_blow_passive")
		local stacks = modifier:GetStackCount()
		if stacks ~= max_stacks then
			modifier:SetStackCount(modifier:GetStackCount() + 1)
		end
Просто добавляешь еще 1 условие, если стаки равны твоему значению, делать какие-то действия.

Если нужно что-то посложнее , типа 1 стак = 1 агилити, и тому подобное , то можно либу от Noya посмотреть, что-то про Custom Stats. Там реализовано через датадривен модификаторы, с обновление(правильно отоброжение информации на интерфейсе).

Вот пример с зарядами для предмета:
Код:
function ItemStackCheck(keys)
	local ability = keys.ability
	local caster = keys.caster
	local stacks = ability:GetCurrentCharges()
	local max_stacks = 25
	if stacks ~= max_stacks then
		ability:SetCurrentCharges(stacks + 1)
		if stacks == 10 or stacks == 20 then
			ability:ApplyDataDrivenModifier(caster, caster, "modifier_agility_five_bonus", {duration=-1}) -- Дополнительная бонусная прибавка за 10 стаков
			ability:ApplyDataDrivenModifier(caster, caster, "modifier_agility_one", {duration=-1})
		else
			ability:ApplyDataDrivenModifier(caster, caster, "modifier_agility_one", {duration=-1}) -- Обычная бонусная прибавка за каждый стак.
		end
	end
end
Создаешь предмет , прописываешь ему какое либо событие, и RunScript на ItemStackCheck.
2 датадривен модификатора - для 1 агилити и для 5-ти (это уже от себя добавил :))
 
Последнее редактирование модератором:
Бро, бро. Такое запилить мне на 2 минуты.

Просто в описании я оговорился.

Мне нужен исходник предмета полностью на луа. Прям от точки до точки.

Чтобы не item_datadriven, а item_lua

А такие орешки на kv я делаю на раз два, просто мне нужно создать очень динамически меняющийся предмет. Недавно вот разбирал некоторые исходники и в принципе уже много чему научился.
У предметов на луа очень большое преимущество, они могут быть динамичными, менять свои параметры.
 
Реклама: