Молнии мъеллнира/маелстрома

Danis

Продвинутый
12 Июн 2016
285
0
Проект
Custom Hero Arena
Сделал молнии, вот код может кому пригодится
Код:
require('libraries/timers')
function CDOTA_BaseNPC:CreateLightning( ability, damage, range, jump_count, damage_type, old_target )
 local caster = self
 local counts = 1
 
 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)

 if old_target and old_target:TotalEnemyHeroesInRange(range) <= 1 then 
  if old_target:IsMagicImmune() then
   print("Target is magic immune")
  else
   print("Deal damage")
   old_target:EmitSound("Hero_Leshrac.Lightning_Storm")
   local id1 = ParticleManager:CreateParticle("particles/lightning_custom.vpcf",PATTACH_WORLDORIGIN, old_target)
   ParticleManager:SetParticleControl(id1, 1, Vector(caster:GetAbsOrigin().x,caster:GetAbsOrigin().y,caster:GetAbsOrigin().z+caster:GetBoundingMaxs().z * 2))
   ParticleManager:SetParticleControl(id1, 0, Vector(old_target:GetAbsOrigin().x,old_target:GetAbsOrigin().y,old_target:GetAbsOrigin().z+old_target:GetBoundingMaxs().z * 2))
   ApplyDamage({victim = old_target, attacker = caster, damage = damage, damage_type = damage_type})
  end
  return nil;
 else
  local delay = 0
  for _, target in pairs(units) do
   delay = delay + 0.15
   Timers:CreateTimer(delay, function()
    if counts < jump_count and old_target ~= nil then
     counts = counts + 1
     local new_target = old_target:NearestEnemyHeroInRange(range, true)
     if new_target ~= nil then
      if target:IsMagicImmune() then
       print("Target is magic immune")
      else
       print("Deal damage")
	   old_target:EmitSound("Hero_Leshrac.Lightning_Storm")
       local id1 = ParticleManager:CreateParticle("particles/lightning_custom.vpcf",PATTACH_WORLDORIGIN, new_target)
       ParticleManager:SetParticleControl(id1, 1, Vector(old_target:GetAbsOrigin().x,old_target:GetAbsOrigin().y,old_target:GetAbsOrigin().z+old_target:GetBoundingMaxs().z * 2))
       ParticleManager:SetParticleControl(id1, 0, Vector(new_target:GetAbsOrigin().x,new_target:GetAbsOrigin().y,new_target:GetAbsOrigin().z+new_target:GetBoundingMaxs().z * 2))
       ApplyDamage({victim = new_target, attacker = caster, damage = damage, damage_type = damage_type})
      end
      old_target = new_target
     end
    else
     return nil;
    end
   end)
  end
 end
end

function CDOTA_BaseNPC:TotalEnemyHeroesInRange(range)
 local target = self
 local flags = DOTA_UNIT_TARGET_FLAG_MAGIC_IMMUNE_ENEMIES
 local enemies = FindUnitsInRadius( target:GetTeam(), target:GetAbsOrigin(), nil, range, DOTA_UNIT_TARGET_TEAM_FRIENDLY, DOTA_UNIT_TARGET_ALL, flags, 0, false )
 
 local count = 0
 
 for _,enemy in pairs(enemies) do
  local distanceToEnemy = (target:GetAbsOrigin() - enemy:GetAbsOrigin()):Length()
  if enemy:IsAlive() and distanceToEnemy < range then
   count = count + 1
  end
 end
 print("Count = "..count)
 return count
end

function CDOTA_BaseNPC:NearestEnemyHeroInRange(range , magic_immune)
 local flags = 0
 local entity = self
 if magic_immune then
  flags = DOTA_UNIT_TARGET_FLAG_MAGIC_IMMUNE_ENEMIES
 end
 
 local enemies = FindUnitsInRadius( entity:GetTeam(), entity:GetOrigin(), nil, range, DOTA_UNIT_TARGET_TEAM_FRIENDLY, DOTA_UNIT_TARGET_ALL, flags, 0, false )
 
 local minRange = nil
 local target = nil
 
 for _,enemy in pairs(enemies) do
  local distanceToEnemy = (entity:GetAbsOrigin() - enemy:GetAbsOrigin()):Length2D()
  if enemy:IsAlive() and (minRange == nil or distanceToEnemy > minRange) and distanceToEnemy < range then
   if enemy ~= entity then
    minRange = distanceToEnemy
    target = enemy
    return target;
   end
  end
 end
 return nil
end

Такое должно быть в коде предмета (в случае с луа, с датадрайвен итемом не делал, может тоже пойдет)
Код:
require('libraries/lightning')

function modifier_lesser_lightning_passive:OnAttackLanded( params )
	self.flag_chance = false
	local caster = self:GetCaster()
	local ability = self:GetAbility()
	local chance = ability:GetSpecialValueFor("chance")
	if params.attacker == caster then 
		if RollPercentage(chance) then
			self.flag_chance = true
			if self:IsActiveOrb() then
				print("Start Lightning")
				caster:CreateLightning(ability, 
					ability:GetSpecialValueFor("lightning_damage"), 
					ability:GetSpecialValueFor("lightning_range"), 
					ability:GetSpecialValueFor("jump_count"),
					DAMAGE_TYPE_MAGICAL,
					params.target)
				print("Damage = "..ability:GetSpecialValueFor("lightning_damage").." | Range = "..ability:GetSpecialValueFor("lightning_range").." | Jumps count = "..ability:GetSpecialValueFor("jump_count"))
			end
		else
			self.flag_chance = false
		end
	end
end
Флаги которые я там написал это для того чтобы с орб эффектами работала, если не понадобится сами выпилите)

Вот так выглядит вызов этой функции
Код:
CDOTA_BaseNPC:CreateLightning( ability, damage, range, jump_count, damage_type, old_target )
Разжевываю
CDOTA_BaseNPC - это должен быть кастер
ability - это и есть абилити, та которая будет записыватся при вызове функции, ее указывать обязательно как и все остальное
damage - это урон при попадании
range - максимальный радиус того куда могут попадать молнии
jump_count - это максимальное количество молний которое может быть
damage_type - это тип урона которым оно будет наносить (все типы урона можно посмотреть здесь)
old_target - это цель которая будет браться за начальную цель при старте молнии
Партикль который используется здесь, он кастомный т.е вам нужно поставить свой или взять уже готовый
!!!Звуки здесь используются дотовские, но их как и партикли надо прекешить!!!


Если есть какие-то идеи по улучшению кода - озвучивайте
 
Последнее редактирование модератором:

Danis

Продвинутый
12 Июн 2016
285
0
Проект
Custom Hero Arena
Не большое обновление кода и не значительные изменения
Теперь код молний находится в отдельном файле, lightning.lua
Код:
require('libraries/timers')
function CDOTA_BaseNPC:CreateLightning( ability, damage, range, jump_count, damage_type, old_target, particle )
 local particle_name
 if particle == nil then particle_name = "particles/lightning_custom.vpcf" else particle_name = particle end
 local caster = self
 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)

 if old_target and old_target:TotalEnemyHeroesInRange(range,caster) <= 1 then 
  if old_target:IsMagicImmune() then
   print("Target is magic immune")
  else
   old_target:EmitSound("Hero_Leshrac.Lightning_Storm")
   local id1 = ParticleManager:CreateParticle(particle_name,PATTACH_ABSORIGIN_FOLLOW, old_target)
   local id2 = ParticleManager:CreateParticle("particles/econ/items/dazzle/dazzle_darkclaw/dazzle_darkclaw_talon_explosion_flash.vpcf",PATTACH_ABSORIGIN_FOLLOW, old_target)
   ParticleManager:SetParticleControl(id1, 1, Vector(caster:GetAbsOrigin().x,caster:GetAbsOrigin().y,caster:GetAbsOrigin().z+caster:GetBoundingMaxs().z * 2))
   ParticleManager:SetParticleControl(id1, 0, Vector(old_target:GetAbsOrigin().x,old_target:GetAbsOrigin().y,old_target:GetAbsOrigin().z+old_target:GetBoundingMaxs().z * 2))
   ParticleManager:SetParticleControl(id2, 5, old_target:GetAbsOrigin())
   ApplyDamage({victim = old_target, attacker = caster, damage = damage, damage_type = damage_type})
  end
  return nil;
 else
  local delay = 0
  for _, target in pairs(units) do
   delay = delay + 0.15
   Timers:CreateTimer(delay, function()
    if counts < jump_count and old_target ~= nil then
     counts = counts + 1
     local new_target = old_target:RandomEnemyHeroInRange(range, true,caster)
     if new_target ~= nil then
      if target:IsMagicImmune() then
       print("Target is magic immune")
      else
       old_target:EmitSound("Hero_Leshrac.Lightning_Storm")
       local id1 = ParticleManager:CreateParticle(particle_name,PATTACH_ABSORIGIN_FOLLOW, new_target)
       local id2 = ParticleManager:CreateParticle("particles/econ/items/dazzle/dazzle_darkclaw/dazzle_darkclaw_talon_explosion_flash.vpcf",PATTACH_ABSORIGIN_FOLLOW, new_target)
       ParticleManager:SetParticleControl(id1, 1, Vector(old_target:GetAbsOrigin().x,old_target:GetAbsOrigin().y,old_target:GetAbsOrigin().z+old_target:GetBoundingMaxs().z * 2))
       ParticleManager:SetParticleControl(id1, 0, Vector(new_target:GetAbsOrigin().x,new_target:GetAbsOrigin().y,new_target:GetAbsOrigin().z+new_target:GetBoundingMaxs().z * 2))
       ParticleManager:SetParticleControl(id2, 5, new_target:GetAbsOrigin())
       ApplyDamage({victim = new_target, attacker = caster, damage = damage, damage_type = damage_type})
      end
      old_target = new_target
     end
    else
     return nil;
    end
   end)
  end
 end
end
Код использования молний
Код:
caster:CreateLightning(ability, 
					self.lightning_damage, 
					self.lightning_range, 
					self.jump_count,
					DAMAGE_TYPE_MAGICAL,
					params.target)
Партикль в коде молний надо так же заменить, и в "призыве" функции можно добавить свой партикль по желанию запихав его после params.target через запятую и в кавычках ("").
 
Последнее редактирование модератором:

CryDeS

Друзья CG
14 Июл 2015
1,210
11
А создавать множество таймеров это не лишняя часть?
Можно же вроде обойтись одним, не?
 

Danis

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

Не, как по мне так было легче сделать, я пробовал но у меня не получилось.

Edit: или ты предлагаешь поменять местоположение создания таймера и поиска по целям, и немного переделать задержку?
 
Последнее редактирование модератором:

CryDeS

Друзья CG
14 Июл 2015
1,210
11
Не, как по мне так было легче сделать, я пробовал но у меня не получилось.

Edit: или ты предлагаешь поменять местоположение создания таймера и поиска по целям, и немного переделать задержку?
Предлагаю сделать 1 таймер и через него все прогонять.
 
Последнее редактирование модератором:
Реклама: