Создание молний как у Мъеллнира

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

Danis

Продвинутый
12 Июн 2016
285
0
Проект
Custom Hero Arena
Есть кто шарит в этой теме? поможете показать где как надо делать? вот то что у меня получилось адаптировать из EBF кода но он для кв итема, а мне для луа нужно.

Код:
function CDOTA_BaseNPC:LightningJump( ability,target,particle ) 
 LinkLuaModifier("modifier_arc_lightning_hammer","lua_item/modifier_arc_lightning_hammer.lua",LUA_MODIFIER_MOTION_NONE)
 require('libraries/timers')
 local caster = self
 local radius = ability:GetSpecialValueFor("lightning_range")
 local damage = ability:GetSpecialValueFor("lightning_damage")
 local damage_type = ability:GetAbilityDamageType()
 local delay = ability:GetSpecialValueFor("lightning_delay")
 if not delay then delay = 0.25 end
 print("Lightning delay is "..delay)
 if not radius then radius = 600 end
 print("Lightning radius is "..radius)
 if caster:IsRealHero() then
  if not target:IsMagicImmune() then
   ApplyDamage({victim = target, attacker = caster, damage = damage, damage_type = damage_type})
  else
   print("Target is magic immune")
  end
  target:RemoveModifierByName("modifier_arc_lightning_hammer")
  print("Remove modifier")

  local timer = Timers:CreateTimer(delay,
   function()
   print("Start Lightning Timer")
   local current

   for i=0,ability.instance do 
    if ability.target[i] ~= nil then
     if ability.target[i] == target then
      current = i
     end
    end
   end

   if target.hit == nil then
    target.hit = {}
   end

   target.hit[current] = true
   print(ability.jump_count[current].." Jumps")
   ability.jump_count[current] = ability.jump_count[current] - 1
   print(ability.jump_count[current].." Jumps remaining")
   if ability.jump_count[current] > 0 then
    local units = FindUnitsInRadius(caster:GetTeamNumber(), 
	target:GetAbsOrigin(), 
	nil, 
	radius, 
	DOTA_UNIT_TARGET_TEAM_ENEMY, DOTA_UNIT_TARGET_ALL, 
	DOTA_UNIT_TARGET_FLAG_NONE, 
	FIND_ANY_ORDER, false)
    local closest = radius
    local new_target
    for _,unit in pairs(units) do
     if unit == target then return end
     local unit_location = unit:GetAbsOrigin()
     local vector_distance = target:GetAbsOrigin() - unit_location
     local distance = (vector_distance):Length2D()
     if distance < closest then
      if unit.hit == nil then
       new_target = unit
       closest = distance
      elseif unit.hit[current] == nil then
       new_target = unit
       closest = distance
      end
     end
    end

    if new_target then
     local ID0 = ParticleManager:CreateParticle(particle, PATTACH_WORLDORIGIN, target)
     ParticleManager:SetParticleControl(ID0,0,target:GetAbsOrigin() + target:GetBoundingMaxs().z)
     ParticleManager:SetParticleControl(ID0,1,new_target:GetAbsOrigin() + new_target:GetBoundingMaxs().z)
     ability.target[current] = new_target
     print("New target name "..new_target:GetName()) 
     print("Add new modifier")
     new_target:AddNewModifier(caster,ability, "modifier_arc_lightning_hammer", {})
    else
     print("Ability target Nil 1")
     ability.target[current] = nil
    end
   else
    print("Ability target Nil 2")
    ability.target[current] = nil
   end
  end)
 end
end

function CDOTA_BaseNPC:NewInstance( ability,target,particle )
 local caster = self
 if caster:IsRealHero() then 

  if ability.instance == nil then
   print("Create instance")
   ability.instance = 0
   ability.jump_count = {}
   ability.target = {}
  else
   print("Instance + 1")
   ability.instance = ability.instance + 1
   print("Instance = "..ability.instance)
  end
  print("Set target and jump count")
  ability.jump_count[ability.instance] = ability:GetSpecialValueFor("jump_count")
  print(ability.jump_count[ability.instance].." Jumps count")
  ability.target[ability.instance] = target

  local ID0 = ParticleManager:CreateParticle(particle, PATTACH_WORLDORIGIN, caster)
  ParticleManager:SetParticleControl(ID0,0,caster:GetAbsOrigin() + caster:GetBoundingMaxs().z)
  ParticleManager:SetParticleControl(ID0,1,target:GetAbsOrigin() + target:GetBoundingMaxs().z)
 end
end

Код:
if modifier_arc_lightning_hammer == nil then modifier_arc_lightning_hammer = class({}) end

function modifier_arc_lightning_hammer:IsHidden( )
	return true
end

function modifier_arc_lightning_hammer:OnCreated( )
	print("Lightning created")
	local ability = self:GetAbility()
	print(ability:GetName().." Ability name")
	local caster = self:GetCaster()

	if not self:GetParent():IsMagicImmune() then
		ApplyDamage({victim = self:GetParent(),attacker = caster,damage = ability:GetSpecialValueFor("lightning_damage"),damage_type = DAMAGE_TYPE_MAGICAL})
	else
		print("Target is magic immune")
	end

	caster:LightningJump(self:GetAbility(),self:GetParent(),"particles/lightning_custom.vpcf")
end

Код:
if item_lesser_lightning == nil then item_lesser_lightning = class({}) end

LinkLuaModifier("modifier_lesser_lightning_passive","items/item_lesser_lightning.lua",LUA_MODIFIER_MOTION_NONE)
LinkLuaModifier("modifier_arc_lightning_hammer","lua_item/modifier_arc_lightning_hammer.lua",LUA_MODIFIER_MOTION_NONE)

function item_lesser_lightning:GetIntrinsicModifierName( )
	return "modifier_lesser_lightning_passive"
end

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

function modifier_lesser_lightning_passive:IsHidden( )
	return true
end

function modifier_lesser_lightning_passive:IsPurgable( )
	return false
end

function modifier_lesser_lightning_passive:DeclareFunctions( )
	return {MODIFIER_EVENT_ON_ATTACK_LANDED,MODIFIER_PROPERTY_ATTACKSPEED_BONUS_CONSTANT,MODIFIER_PROPERTY_PREATTACK_BONUS_DAMAGE}
end

function modifier_lesser_lightning_passive:GetModifierPreAttack_BonusDamage( )
	return self:GetAbility():GetSpecialValueFor("dmg")
end

function modifier_lesser_lightning_passive:GetModifierAttackSpeedBonus_Constant( )
	return self:GetAbility():GetSpecialValueFor("atk")
end

function modifier_lesser_lightning_passive:GetModifierOrbPriority( )
	return DOTA_ORB_PRIORITY_ITEM_UNIQUE
end

function modifier_lesser_lightning_passive:OnAttackLanded( params )
	local caster = self:GetCaster()
	local ability = self:GetAbility()
	local chance = ability:GetSpecialValueFor("chance")
	if params.attacker == caster then 
		if RollPercentage(100) then
			if self:IsActiveOrb() then
				print("Start Lightning")
				params.target:AddNewModifier(caster,ability,"modifier_arc_lightning_hammer",{})
				caster:NewInstance(ability,params.target,"particles/lightning_custom.vpcf")
			end
		end
	end
end
Просто уже 3й день маюсь этой штукой и ничего почти не выходит, работает сейчас так: при ударе дает молнию, но только 1 по основной цели, по остальным бьет если для основной цели удар был смертельным и то пускает дальше только 1 молнию.
 
Последнее редактирование модератором:
Сколько не смотрю, все делают по своему.

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

Просто по массиву юнитов из области удара с определенной задержкой (скачки молний) отрисовываешь партиклю и наносишь урон.
 
Вот вроде написал, но оно сразу всех бьет) вот код, может кому понадобится
Код:
function CDOTA_BaseNPC:CreateLightning( ability, damage, range, jump_count, damage_type )
 local caster = self
 local old_target = ability.old_target

   if old_target:IsMagicImmune() then
    print("Target is magic immune")
   else
    print("Deal damage")
    local id0 = ParticleManager:CreateParticle("particles/lightning_custom.vpcf",PATTACH_ABSORIGIN_FOLLOW, old_target)
    ParticleManager:SetParticleControlEnt(id0, 1, caster, PATTACH_ABSORIGIN_FOLLOW, "attach_hitloc", caster:GetAbsOrigin()+Vector(0,0,caster:GetBoundingMaxs().z), false)
    ParticleManager:SetParticleControlEnt(id0, 0, old_target, PATTACH_ABSORIGIN_FOLLOW, "attach_hitloc", old_target:GetAbsOrigin()+Vector(0,0,old_target:GetBoundingMaxs().z), false)
    ApplyDamage({victim = old_target, attacker = caster, damage = damage, damage_type = damage_type})
   end

 local target
 local counts = 0
 
 local units = FindUnitsInRadius(
  caster:GetTeamNumber(),
  old_target:GetAbsOrigin(),
  nil,
  range,
  DOTA_UNIT_TARGET_TEAM_ENEMY,
  DOTA_UNIT_TARGET_ALL,
  DOTA_UNIT_TARGET_FLAG_NONE,
  FIND_ANY_ORDER,
  false)

 for i = 1, jump_count do
  for _, target in pairs(units) do
   if old_target == target then return end
   if counts < jump_count - 1 then
    counts = counts + 1
    if target:IsMagicImmune() then
     print("Target is magic immune")
    else
     print("Deal damage")
     local id0 = ParticleManager:CreateParticle("particles/lightning_custom.vpcf",PATTACH_ABSORIGIN_FOLLOW, target)
     ParticleManager:SetParticleControlEnt(id0, 1, caster, PATTACH_ABSORIGIN_FOLLOW, "attach_hitloc", caster:GetAbsOrigin()+Vector(0,0,caster:GetBoundingMaxs().z), false)
     ParticleManager:SetParticleControlEnt(id0, 0, target, PATTACH_ABSORIGIN_FOLLOW, "attach_hitloc", target:GetAbsOrigin()+Vector(0,0,target:GetBoundingMaxs().z), false)
     ApplyDamage({victim = target, attacker = caster, damage = damage, damage_type = damage_type})
    end
    old_target = target
   end
  end
 end
end
 
Последнее редактирование модератором:
Добавишь таймер для задержки и будет не моментально бить.
 
Ну вон, во вторую часть, где скачки у тебя идут. Создаешь блок таймера, который повторяешь (через return) через определенное время до тех пор, пока последний элемент не поступит на обработку (тут через return вернешь nil). В самом блоке отрисовывай партиклю между двумя юнитами и наноси урон последнему, как ты там делаешь.
 
Реклама: