Как сделать предмет по типу мьельнира?

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

Danis

Продвинутый
12 Июн 2016
285
0
Проект
Custom Hero Arena
Я вот захотел сделать предмет по типу мьельнира чтобы при рандоме и суццессе вылетала молния и херачила несколько целей.
Прошу объясните как работает модифир bounce если он вообще есть.
 
Danis, вот тебе модификатор крита скелета вроде. По типу этого и делай. При шансе луа вызывай, делай эффект и эпплидемедж.
Код:
"modifier_gnev"
  {
    "Passive"  "0"
    "IsHidden" "0"
    "Duration" "25"
    "EffectName"  "particles/heroes/ghoul/invoker_forge_spirit_ambient_esl_embers2.vpcf"
    "OnCreated"
    {
     "RunScript"
     {
      "ScriptFile"  "abilities/ghoul/ghoul.lua"
      "Function"   "gnev_effect"
     }
    }
    "OnAttackStart"
    {
      "RemoveModifier"
      {
        "ModifierName" "modifier_critical_strike_crit"
        "Target"  "CASTER"
      }
      "Random"
      {
        "Chance" "%crit_chance"
        "OnSuccess"
        {
         "FireSound"
         {
          "EffectName" "Hero_SkeletonKing.CriticalStrike"
          "Target"  "CASTER"
         }
         "FireEffect"
         {
          "EffectName"  "particles/units/heroes/hero_juggernaut/jugg_attack_blur.vpcf"
          "EffectAttachType" "attach_sword"
          "Target"    "CASTER"
         }
         "ApplyModifier"
         {
          "ModifierName" "modifier_critical_strike_crit"
          "Target"   "CASTER"  
         }    
        }
      }
    }
  }
 
Последнее редактирование модератором:
[quote author=Slavko link=topic=969.msg4948#msg4948 date=1466030258]
Danis, вот тебе модификатор крита скелета вроде. По типу этого и делай. При шансе луа вызывай, делай эффект и эпплидемедж.
Код:
"modifier_gnev"
  {
    "Passive"  "0"
    "IsHidden" "0"
    "Duration" "25"
    "EffectName"  "particles/heroes/ghoul/invoker_forge_spirit_ambient_esl_embers2.vpcf"
    "OnCreated"
    {
     "RunScript"
     {
      "ScriptFile"  "abilities/ghoul/ghoul.lua"
      "Function"   "gnev_effect"
     }
    }
    "OnAttackStart"
    {
      "RemoveModifier"
      {
        "ModifierName" "modifier_critical_strike_crit"
        "Target"  "CASTER"
      }
      "Random"
      {
        "Chance" "%crit_chance"
        "OnSuccess"
        {
         "FireSound"
         {
          "EffectName" "Hero_SkeletonKing.CriticalStrike"
          "Target"  "CASTER"
         }
         "FireEffect"
         {
          "EffectName"  "particles/units/heroes/hero_juggernaut/jugg_attack_blur.vpcf"
          "EffectAttachType" "attach_sword"
          "Target"    "CASTER"
         }
         "ApplyModifier"
         {
          "ModifierName" "modifier_critical_strike_crit"
          "Target"   "CASTER"  
         }    
        }
      }
    }
  }
[/quote]

Бред же) Кроме рандома, тут нет ничего от мъелнира.
Не совсем уверен, но молния, реализована через TrackingProjectile с почти моментальной скоростью, от одной цели к другой, от другой к третьей и так далее.
 
Последнее редактирование модератором:
RecoveryIt, я лишь подскажу, что через луа эффект делается управлением поинтами партикля. :D Прожектайла молнии нет вроде.
 
[quote author=Slavko link=topic=969.msg4950#msg4950 date=1466030547]
RecoveryIt, я лишь подскажу, что через луа эффект делается управлением поинтами партикля. :D Прожектайла молнии нет вроде.
[/quote]
Причем тут вообще управление партиклями, если урон наносится с задержками. Ты их тоже партиклями сделаешь?
Ты сам подумай, если сделать как ты говоришь, то урон нанесется моментально всем целям при проке, а это уже какойто сплеш))) Нужны задержки после каждой цели, и самый оптимальный вариант это TrackingProjectile. Есть конечно вариант заюзать таймеры, но как по мне - наркомания.
 
RecoveryIt, хорошо, как ты сделаешь задержки между прожектайлами от цели к цели, если говоришь, мол, прожектайл моментальный нужен ?
 
В чем проблема сделать молнию к первой цели и дамаг, а от этой цели к следующей - через Timers:CreateTimer(0.5, function()
 
[quote author=Slavko link=topic=969.msg4952#msg4952 date=1466031486]
RecoveryIt, хорошо, как ты сделаешь задержки между прожектайлами от цели к цели, если говоришь, мол, прожектайл моментальный нужен ?
[/quote]

ПОЧТИ моментальный. А вообще вот вариант с таймерами, с гитхаба.
Считаю что через TrakingProjectile кода могло быть меньше.

Код:
--[[Author: YOLOSPAGHETTI
	Date: March 24, 2016
	Finds the next unit to jump to and deals the damage]]
function LightningJump(keys)
	local caster = keys.caster
	local target = keys.target
	local ability = keys.ability
	local jump_delay = ability:GetLevelSpecialValueFor("jump_delay", (ability:GetLevel() -1))
	local radius = ability:GetLevelSpecialValueFor("radius", (ability:GetLevel() -1))
	
	-- Applies damage to the current target
	ApplyDamage({victim = target, attacker = caster, damage = ability:GetAbilityDamage(), damage_type = ability:GetAbilityDamageType()})
	-- Removes the hidden modifier
	target:RemoveModifierByName("modifier_arc_lightning_datadriven")
	
	-- Waits on the jump delay
	Timers:CreateTimer(jump_delay,
  function()
		-- Finds the current instance of the ability by ensuring both current targets are the same
		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
	
		-- Adds a global array to the target, so we can check later if it has already been hit in this instance
		if target.hit == nil then
			target.hit = {}
		end
		-- Sets it to true for this instance
		target.hit[current] = true
	
		-- Decrements our jump count for this instance
		ability.jump_count[current] = ability.jump_count[current] - 1
	
		-- Checks if there are jumps left
		if ability.jump_count[current] > 0 then
			-- Finds units in the radius to jump to
			local units = FindUnitsInRadius(caster:GetTeamNumber(), target:GetAbsOrigin(), nil, radius, ability:GetAbilityTargetTeam(), ability:GetAbilityTargetType(), ability:GetAbilityTargetFlags(), 0, false)
			local closest = radius
			local new_target
			for i,unit in ipairs(units) do
				-- Positioning and distance variables
				local unit_location = unit:GetAbsOrigin()
				local vector_distance = target:GetAbsOrigin() - unit_location
				local distance = (vector_distance):Length2D()
				-- Checks if the unit is closer than the closest checked so far
				if distance < closest then
					-- If the unit has not been hit yet, we set its distance as the new closest distance and it as the new target
					if unit.hit == nil then
						new_target = unit
						closest = distance
					elseif unit.hit[current] == nil then
						new_target = unit
						closest = distance
					end
				end
			end
			-- Checks if there is a new target
			if new_target ~= nil then
				-- Creates the particle between the new target and the last target
				local lightningBolt = ParticleManager:CreateParticle(keys.particle, PATTACH_WORLDORIGIN, target)
				ParticleManager:SetParticleControl(lightningBolt,0,Vector(target:GetAbsOrigin().x,target:GetAbsOrigin().y,target:GetAbsOrigin().z + target:GetBoundingMaxs().z ))  
				ParticleManager:SetParticleControl(lightningBolt,1,Vector(new_target:GetAbsOrigin().x,new_target:GetAbsOrigin().y,new_target:GetAbsOrigin().z + new_target:GetBoundingMaxs().z ))
				-- Sets the new target as the current target for this instance
				ability.target[current] = new_target
				-- Applies the modifer to the new target, which runs this function on it
				ability:ApplyDataDrivenModifier(caster, new_target, "modifier_arc_lightning_datadriven", {})
			else
				-- If there are no new targets, we set the current target to nil to indicate this instance is over
				ability.target[current] = nil
			end
		else
			-- If there are no more jumps, we set the current target to nil to indicate this instance is over
			ability.target[current] = nil
		end
	end)
end

--[[Author: YOLOSPAGHETTI
	Date: March 24, 2016
	Keeps track of all instances of the spell (since more than one can be active at once)]]
function NewInstance(keys)
	local caster = keys.caster
	local ability = keys.ability
	local target = keys.target
	
	-- Keeps track of the total number of instances of the ability (increments on cast)
	if ability.instance == nil then
		ability.instance = 0
		ability.jump_count = {}
		ability.target = {}
	else
		ability.instance = ability.instance + 1
	end
	
	-- Sets the total number of jumps for this instance (to be decremented later)
	ability.jump_count[ability.instance] = ability:GetLevelSpecialValueFor("jump_count", (ability:GetLevel() -1))
	-- Sets the first target as the current target for this instance
	ability.target[ability.instance] = target
	
	-- Creates the particle between the caster and the first target
	local lightningBolt = ParticleManager:CreateParticle(keys.particle, PATTACH_WORLDORIGIN, caster)
  ParticleManager:SetParticleControl(lightningBolt,0,Vector(caster:GetAbsOrigin().x,caster:GetAbsOrigin().y,caster:GetAbsOrigin().z + caster:GetBoundingMaxs().z ))  
  ParticleManager:SetParticleControl(lightningBolt,1,Vector(target:GetAbsOrigin().x,target:GetAbsOrigin().y,target:GetAbsOrigin().z + target:GetBoundingMaxs().z ))  
end
 
Последнее редактирование модератором:
Или, на крайняк, на каждую последующую цель вешать модификатор на 0.5 секи, у которого OnDestroy(и если носитель жив) - пульнуть молнией в следующего. А цели, дабы избежать повторного попадания молнии в того же чувака, записывать в ability.targets = {}, и через этот же массив проверку делать.
 
Не буду я этот код разбирать, тут всё делается в 30 строк, но меня снова обзовут велосипедистом, хотя по сути всё работает без багов.
 
Или, на крайняк, на каждую последующую цель вешать модификатор на 0.5 секи, у которого OnDestroy(и если носитель жив) - пульнуть молнией в следующего. А цели, дабы избежать повторного попадания молнии в того же чувака, записывать в ability.targets = {}, и через этот же массив проверку делать.
Дело говоришь, именно так это обычно и работает.
А точнее:
При срабатывании мы ищем первую ближайшую цель, записываем ее в ability.targets, создаем проджектил и наносим урон, после через 0.25сек повторяем со след целью, но уже с места текущий цели.
---
Еще вариант, на цель удара вешать модификатор который длится (макс_целей*время_между_целями + 1) (во избежания повторного удара), далее мы вешаем модификатор который наносит урон, и таймер на 0.25сек который вешает модификатор(что уже нанесли урон) на след цель, делает урон и снаряд и повторить пока макс цели не кончатся/цели просто не кончатся.
 
Последнее редактирование модератором:
Вот нашел код из ЛИА только почему то он не хочет работать и пишет что не может идентифицировать Тimers

Код:
function dragolnir_lightining( event )
	local ability = event.ability
	local target = event.target

	if not target:IsMagicImmune() then
		local hero = event.caster
		

		
		local damage = ability:GetLevelSpecialValueFor( "bounce_damage", ability:GetLevel() - 1 )
		local bounces = ability:GetLevelSpecialValueFor( "bounces", ability:GetLevel() - 1 )
		local bounce_range = ability:GetLevelSpecialValueFor( "bounce_range", ability:GetLevel() - 1 )
		local decay = ability:GetLevelSpecialValueFor( "bounce_decay", ability:GetLevel() - 1 ) * 0.01
		local time_between_bounces = ability:GetLevelSpecialValueFor( "time_between_bounce", ability:GetLevel() - 1 )



		local lightningBolt = ParticleManager:CreateParticle("particles/items_fx/chain_lightning.vpcf", PATTACH_WORLDORIGIN, hero)
		ParticleManager:SetParticleControl(lightningBolt,0,Vector(hero:GetAbsOrigin().x,hero:GetAbsOrigin().y,hero:GetAbsOrigin().z + hero:GetBoundingMaxs().z ))	
		ParticleManager:SetParticleControl(lightningBolt,1,Vector(target:GetAbsOrigin().x,target:GetAbsOrigin().y,target:GetAbsOrigin().z + target:GetBoundingMaxs().z ))	

		EmitSoundOn("Hero_Zuus.ArcLightning.Target", target)	
		ApplyDamage({ victim = target, attacker = hero, damage = damage, damage_type = DAMAGE_TYPE_MAGICAL, ability = ability })

		local targetsStruck = {}
		target.struckByChain = true
		table.insert(targetsStruck,target)

		local dummy = nil
		local units = nil

		ability:StartCooldown(ability:GetCooldown(ability:GetLevel()))
		ability:ApplyDataDrivenModifier(hero,hero,"modifier_item_lia_lightning_spear_cooldown",nil)
		hero:RemoveModifierByName("modifier_item_lia_lightning_spear_lightning")

		CreateTimer(DoUniqueString("ChainLightning"), {
			endTime = time_between_bounces,
			callback = function()
		
				units = FindUnitsInRadius(hero:GetTeamNumber(), target:GetOrigin(), target, bounce_range, DOTA_UNIT_TARGET_TEAM_ENEMY, 
							DOTA_UNIT_TARGET_BASIC + DOTA_UNIT_TARGET_HERO, DOTA_UNIT_TARGET_FLAG_NONE, FIND_ANY_ORDER, true)

				targetVec = target:GetAbsOrigin()
				targetVec.z = target:GetAbsOrigin().z + target:GetBoundingMaxs().z
				if dummy ~= nil then
					dummy:RemoveSelf()
				end
				dummy = CreateUnitByName("dummy_unit", targetVec, false, hero, hero, hero:GetTeam())

				local possibleTargetsBounce = {}
				for _,v in pairs(units) do
					if not v.struckByChain then
						table.insert(possibleTargetsBounce,v)
					end
				end

				local newTarget 
				local distance = 9999999
				local newTargetVec
				for _,v in pairs(possibleTargetsBounce) do
					newTargetVec = v:GetAbsOrigin()
					--print(v,DistanceBetweenVectors(targetVec,newTargetVec)) 
					if v ~= target then
						if DistanceBetweenPoints(targetVec,newTargetVec) < distance then
							newTarget = v
							distance = DistanceBetweenPoints(targetVec,newTargetVec)
						end
					end
				end
				target = newTarget

				if target then
					target.struckByChain = true
					table.insert(targetsStruck,target)		
				else
					for _,v in pairs(targetsStruck) do
					  v.struckByChain = false
					  v = nil
					end
					return	
				end


				local lightningChain = ParticleManager:CreateParticle("particles/items_fx/chain_lightning.vpcf", PATTACH_WORLDORIGIN, dummy)
				ParticleManager:SetParticleControl(lightningChain,0,Vector(dummy:GetAbsOrigin().x,dummy:GetAbsOrigin().y,dummy:GetAbsOrigin().z + dummy:GetBoundingMaxs().z ))	
				
				damage = damage - (damage*decay)
				ApplyDamage({ victim = target, attacker = hero, damage = damage, damage_type = DAMAGE_TYPE_MAGICAL, ability = ability })
				print("Bounce "..bounces.." Hit Unit "..target:GetEntityIndex().. " for "..damage.." damage")

				EmitSoundOn("Hero_Zuus.ArcLightning.Target",target)

				ParticleManager:SetParticleControl(lightningChain,1,Vector(target:GetAbsOrigin().x,target:GetAbsOrigin().y,target:GetAbsOrigin().z + target:GetBoundingMaxs().z ))
		
				bounces = bounces - 1

				if bounces > 0 then
					return time_between_bounces
				else
					for _,v in pairs(targetsStruck) do
					  	v.struckByChain = false
					  	v = nil
					end
				end
			end
		})

	end
end
 
Последнее редактирование модератором:
Последнее редактирование модератором:
[quote author=CryDeS link=topic=969.msg4961#msg4961 date=1466076237]
Timer - отдельная библеотека от BMD.
Потом в главном файле делаешь require('timers')
https://dropmefiles.com/kMQSL
[/quote]
Спасибо, понял.
 
Реклама: