Одновременный каст одного и того же заклинания от разных юнитов.

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

Epselot

Пользователь
11 Янв 2017
34
0
Взял ульт пугны из имбадоты, убрал то что мне не нужно (ещё чистить нужно не заморачивался).
Всё работает если у нас один юнит использует скилл на другом. А вот когда на юните 1 использует скилл юнит 2 и юнит 3, то при когда юнит 3 начинает кастовать у него не появляется анимация, но ману он начинает получать а юнит 2 прекращает.

Предполагаю что за счёт использования одинаковых переменных поскольку скилл один происходит конфликт, но все же переменные локальные и такого не должно происходить. Просто не так много видимо про язык знаю.
Так как это поправить?

Код:
function LifeDrainAllyStart( keys )
	local caster = keys.caster
	local target = keys.target
	local particle_drain = keys.particle_drain
	local sound_loop = keys.sound_loop

	-- Stop any ongoing looping sound on the target
	target:StopSound(sound_loop)
	target:EmitSound(sound_loop)

	-- End any pre-existing particle
	if target.life_give_particle then
		ParticleManager:DestroyParticle(target.life_give_particle, false)
		ParticleManager:ReleaseParticleIndex(target.life_give_particle)
	end
	
	-- Play ally particle
	target.life_give_particle = ParticleManager:CreateParticle(particle_drain, PATTACH_ABSORIGIN, caster)
	ParticleManager:SetParticleControlEnt(target.life_give_particle, 0, caster, PATTACH_POINT_FOLLOW, "attach_hitloc", caster:GetAbsOrigin(), true)
	ParticleManager:SetParticleControlEnt(target.life_give_particle, 1, target, PATTACH_POINT_FOLLOW, "attach_hitloc", target:GetAbsOrigin(), true)
end

function LifeDrainEnemyStart( keys )
	local caster = keys.caster
	local target = keys.target
	local particle_drain = keys.particle_drain
	local sound_loop = keys.sound_loop

	-- Stop any ongoing looping sound on the target
	target:StopSound(sound_loop)
	target:EmitSound(sound_loop)

	-- End any pre-existing particle
	if target.life_drain_particle then
		ParticleManager:DestroyParticle(target.life_drain_particle, false)
		ParticleManager:ReleaseParticleIndex(target.life_drain_particle)
	end
	
	-- Play ally particle
	target.life_drain_particle = ParticleManager:CreateParticle(particle_drain, PATTACH_ABSORIGIN, caster)
	ParticleManager:SetParticleControlEnt(target.life_drain_particle, 0, caster, PATTACH_POINT_FOLLOW, "attach_hitloc", caster:GetAbsOrigin(), true)
	ParticleManager:SetParticleControlEnt(target.life_drain_particle, 1, target, PATTACH_POINT_FOLLOW, "attach_hitloc", target:GetAbsOrigin(), true)
end

function LifeDrainTickEnemy( keys )
	local caster = keys.caster
	local target = keys.target
	local ability = keys.ability
	local ability_level = ability:GetLevel() - 1
	local modifier_enemy = keys.modifier_enemy
	
	-- Parameters
	local break_range = ability:GetLevelSpecialValueFor("break_range", ability_level) --+ GetCastRangeIncrease(caster)
	local tick_rate = ability:GetLevelSpecialValueFor("tick_rate", ability_level)

	local caster_max_mana = caster:GetMaxMana()
	local target_max_mana = target:GetMaxMana()
	local caster_current_mana = caster:GetMana()
	local target_current_mana = target:GetMana()

	if caster_max_mana ~= caster_current_mana and target_current_mana >= 5 then
	caster:GiveMana(5)
	target:ReduceMana(5)
	end

	-- Update particle color
	ParticleManager:SetParticleControl(target.life_drain_particle, 11, Vector(1, 0, 0))

	-- Check link break conditions
	local should_break = false

	-- Break the link if the caster is stunned or silenced or dead
	if caster:IsStunned() or caster:IsSilenced() or not caster:IsAlive() then
		should_break = true
	end

	-- Break the link if this target is out of the world or no longer visible
	if target:IsOutOfGame() then
		should_break = true
	end

	-- Calculate distance from this target to the caster
	local target_loc = target:GetAbsOrigin()
	local caster_loc = caster:GetAbsOrigin()
	local distance = (target_loc - caster_loc):Length2D()

	-- Break the link if the distance is too large
	if distance > break_range then
		should_break = true
	end

	-- If any of the break conditions is true, break the link
	if should_break then
		target:RemoveModifierByName(modifier_enemy)
	end
end

function LifeDrainCancel( keys )
	local caster = keys.caster
	local ability = keys.ability
	local ability_level = ability:GetLevel() - 1
	local modifier_ally = keys.modifier_ally
	local modifier_enemy = keys.modifier_enemy --не заверщён
	
	-- Parameters
	local search_range = ability:GetLevelSpecialValueFor("search_range", ability_level)

	-- Find all currently tethered allies (Найти все в настоящее время на привязи союзников)
	local allies = FindUnitsInRadius(caster:GetTeamNumber(), caster:GetAbsOrigin(), nil, search_range, DOTA_UNIT_TARGET_TEAM_FRIENDLY, DOTA_UNIT_TARGET_BASIC + DOTA_UNIT_TARGET_HERO, DOTA_UNIT_TARGET_FLAG_INVULNERABLE + DOTA_UNIT_TARGET_FLAG_OUT_OF_WORLD, FIND_ANY_ORDER, false)
	
	-- Iterate through valid allies, removing the life drain modifier
	for _,ally in pairs(allies) do
		ally:RemoveModifierByNameAndCaster(modifier_ally, caster)
	end
	
end

function LifeDrainEnemyEnd( keys )
	local caster = keys.caster
	local target = keys.target
	local sound_loop = keys.sound_loop
	local sound_target = keys.sound_target

	-- End the particle
	ParticleManager:DestroyParticle(target.life_drain_particle, false)
	ParticleManager:ReleaseParticleIndex(target.life_drain_particle)
	target.life_drain_particle = nil

	-- Stop the looping sound
	target:StopSound(sound_target)
	target:StopSound(sound_loop)
end

function LifeDrainAllyEnd( keys )
	local caster = keys.caster
	local target = keys.target
	local sound_loop = keys.sound_loop
	local sound_target = keys.sound_target

	-- End the particle
	ParticleManager:DestroyParticle(target.life_give_particle, false)
	ParticleManager:ReleaseParticleIndex(target.life_give_particle)
	target.life_give_particle = nil

	-- Stop the looping sound
	target:StopSound(sound_target)
	target:StopSound(sound_loop)
end
 
Последнее редактирование модератором:
Epselot, скорее всего просто модификатор один и тот же навешивается, но при этом у него стоит, что он не стаккабл
 
[quote author=I_GRIN_I link=topic=1258.msg7567#msg7567 date=1484665457]
Epselot, написать свой ульт пугны и не париться?
[/quote]

Это совсем простой скил, там только с анимацией наворочено. Но дело не в анимации а в принципе работы переменных насколько понимаю. При касте на одного юнита они как то соприкасаются. Честно не понимаю.
Если напишу скилл сам, итог то не изменится.
 
Если в коде есть таймеры или какие локально-глобальные переменные (чего я беглым взглядом не обнаружил) то да, может быть наложение. В противном случае вряд ли.
 
[quote author=I_GRIN_I link=topic=1258.msg7568#msg7568 date=1484665568]
Epselot, скорее всего просто модификатор один и тот же навешивается, но при этом у него стоит, что он не стаккабл
[/quote]

"AbilitySpecial"
{
"01"
{
"var_type" "FIELD_INTEGER"
"search_range" "1600"
}
}

"OnSpellStart"
{
"RunScript"
{
"ScriptFile" "hero/hero_pugna.lua"
"Function" "LifeDrainCancel"

"modifier_enemy" "modifier_imba_life_drain_enemy"
}
}

Да вот он модификатор modifier_imba_life_drain_ally. Как сделать что бы он скатался?
 
Последнее редактирование модератором:
Это совсем простой скил, там только с анимацией наворочено. Но дело не в анимации а в принципе работы переменных насколько понимаю. При касте на одного юнита они как то соприкасаются. Честно не понимаю.
Если напишу скилл сам, итог то не изменится.
У тебя записывается информация в target. Он глобальный, оттуда и проблемы с наложением(если я конечно тебя правильно понял).
 
Последнее редактирование модератором:
Нужен код модификатора.
Код:
		"OnSpellStart"
		{
			"RunScript"
			{
				"ScriptFile"				"hero/hero_pugna.lua"
				"Function"					"LifeDrain"

				"sound_cast"				"Hero_Pugna.LifeDrain.Cast"
				"sound_target"				"Imba.PugnaLifeDrainTarget"
				"modifier_enemy"			"modifier_imba_life_drain_enemy"
			}
		}

		"Modifiers"
		{
			"modifier_imba_life_drain_enemy"
			{
				"Passive"					"0"
				"IsDebuff"					"1"
				"IsHidden"					"1"
				"IsPurgable"				"0"

				"ThinkInterval"				"%tick_rate"

				"OnIntervalThink"
				{
					"RunScript"
					{
						"ScriptFile"		"hero/hero_pugna.lua"
						"Function"			"LifeDrainTickEnemy"

						"modifier_enemy"	"modifier_imba_life_drain_enemy"
					}
				}

				"OnCreated"
				{
					"RunScript"
					{
						"ScriptFile"		"hero/hero_pugna.lua"
						"Function"			"LifeDrainEnemyStart"

						"particle_drain"	"particles/units/heroes/hero_pugna/pugna_life_drain.vpcf"
						"sound_loop"		"Imba.PugnaLifeDrainLoop"
					}
				}

				"OnDestroy"
				{
					"RunScript"
					{
						"ScriptFile"		"hero/hero_pugna.lua"
						"Function"			"LifeDrainEnemyEnd"

						"sound_loop"		"Imba.PugnaLifeDrainLoop"
						"sound_target"		"Hero_Pugna.LifeDrain.Target"
					}
				}
			}
 
Последнее редактирование модератором:
[quote author=CryDeS link=topic=1258.msg7578#msg7578 date=1484673583]
У тебя записывается информация в target. Он глобальный, оттуда и проблемы с наложением(если я конечно тебя правильно понял).
[/quote]

Подозреваю дело вот в этом ability:ApplyDataDrivenModifier(caster, target, modifier_enemy, {}).
 
Epselot, попробуй все таки в атрибуты к модификаторам записатьMODIFIER_ATTRIBUTE_MULTIPLE
 
[quote author=I_GRIN_I link=topic=1258.msg7598#msg7598 date=1484702833]
Epselot, попробуй все таки в атрибуты к модификаторам записать MODIFIER_ATTRIBUTE_MULTIPLE
[/quote]

С одной стороны получилось, с другой совсем не то что нужно... Когда применяю на первого юнита скилл вторым юнитом, а потом применяю на первого юнита скилл тветьим юнитом, то скил второго юнита отменяется...

Какие ещё решения существуют?
 
С одной стороны получилось, с другой совсем не то что нужно... Когда применяю на первого юнита скилл вторым юнитом, а потом применяю на первого юнита скилл тветьим юнитом, то скил второго юнита отменяется...

Какие ещё решения существуют?
Переписать на ability_lua и не парится
 
Последнее редактирование модератором:
Переписать на ability_lua и не парится

Ты про вот это?
Код:
function modifier_enemy:GetAttributes()
  return MODIFIER_ATTRIBUTE_MULTIPLE
end

Тогда расскажите как этим пользоваться? Пробовал встраивать на основе примеров найденных в интернете, но в лучшем случае просто ничего не работает...
И желательно по подробней, с lua ещё так себе разобрался...
 
Последнее редактирование модератором:
Epselot, просто напиши весь скилл с нуля и модификаторы свои напиши. Ты будешь учиться намного медленне если бцдешь переписывать чужой код, нежели как сам попытаешься все свои задумки самостоятельно реализовать, у меня так с панорамой было
 
[quote author=Epselot link=topic=1258.msg7638#msg7638 date=1484789286]
Ты про вот это?
Код:
function modifier_enemy:GetAttributes()
  return MODIFIER_ATTRIBUTE_MULTIPLE
end

Тогда расскажите как этим пользоваться? Пробовал встраивать на основе примеров найденных в интернете, но в лучшем случае просто ничего не работает...
И желательно по подробней, с lua ещё так себе разобрался...
[/quote]
https://developer.valvesoftware.com/wiki/Dota_2_Workshop_Tools/Lua_Abilities_and_Modifiers
 
[quote author=I_GRIN_I link=topic=1258.msg7639#msg7639 date=1484795399]
Epselot, просто напиши весь скилл с нуля и модификаторы свои напиши. Ты будешь учиться намного медленне если бцдешь переписывать чужой код, нежели как сам попытаешься все свои задумки самостоятельно реализовать, у меня так с панорамой было
[/quote]

Да причём тут скилл. Скилл понимаю как работает.
Не имею понятия как работает:
function modifier_enemy:GetAttributes()
return MODIFIER_ATTRIBUTE_MULTIPLE
end
Внятного объяснения не смог найти в интернете.

И к слову это не первый мой язык программирования и учиться по чужим примерам намного эффективнее, чем пытаться писать самому. (допускаю что не для всех так, но для меня это наиболее краткий путь к освоению)

Проблема в том что не смог найти внятного примера с использованием MODIFIER_ATTRIBUTE_MULTIPLE в ситуации подобной моей.

Если кто понимает с чем едят эту штуку, то поясните.
 
[quote author=Epselot link=topic=1258.msg7654#msg7654 date=1484828259]
Да причём тут скилл. Скилл понимаю как работает.
Не имею понятия как работает:
Код:
function modifier_enemy:GetAttributes()
  return MODIFIER_ATTRIBUTE_MULTIPLE
end
Внятного объяснения не смог найти в интернете.

И к слову это не первый мой язык программирования и учиться по чужим примерам намного эффективнее, чем пытаться писать самому. (допускаю что не для всех так, но для меня это наиболее краткий путь к освоению)

Проблема в том что не смог найти внятного примера с использованием MODIFIER_ATTRIBUTE_MULTIPLE в ситуации подобной моей.

Если кто понимает с чем едят эту штуку, то поясните.
[/quote]
Он позволяет одному и тому же модификатору при накладывании на кого-то не обновлять время своего действия, а накладывать еще раз как еще один модификатор.
Например если у тебя без него стоит, то при повторном накладывании этого модификатора, он лишь восстановит время его действия.
Если же у тебя стоит MODIFIER_ATTRIBUTE_MULTIPLE то при повторном наложении на твоем юните будут два отдельных модификатора, работающих отдельно, и каждый из них будет давать свой бонус.
Пример с MODIFIER_ATTRIBUTE_MULTIPLE это стаки урона у питлорда.
В след разы используй блок code, удобнее читать
 
[quote author=CryDeS link=topic=1258.msg7657#msg7657 date=1484830365]
Он позволяет одному и тому же модификатору при накладывании на кого-то не обновлять время своего действия, а накладывать еще раз как еще один модификатор.
Например если у тебя без него стоит, то при повторном накладывании этого модификатора, он лишь восстановит время его действия.
Если же у тебя стоит MODIFIER_ATTRIBUTE_MULTIPLE то при повторном наложении на твоем юните будут два отдельных модификатора, работающих отдельно, и каждый из них будет давать свой бонус.
Пример с MODIFIER_ATTRIBUTE_MULTIPLE это стаки урона у питлорда.
[/quote]

Благодарю за разъяснения. От части всё получилось, от части бафа передачи маны, а вот от части анимации не получилось и не могло получиться, так как в ней модификатор не используется.

Код:
function LifeDrainAllyStart( keys )
	local caster = keys.caster
	local target = keys.target
	local particle_drain = keys.particle_drain
	local sound_loop = keys.sound_loop

	-- Stop any ongoing looping sound on the target
	target:StopSound(sound_loop)
	target:EmitSound(sound_loop)

	-- End any pre-existing particle
	if target.life_give_particle then
		ParticleManager:DestroyParticle(target.life_give_particle, false)
		ParticleManager:ReleaseParticleIndex(target.life_give_particle)
	end
	
	-- Play ally particle
	target.life_give_particle = ParticleManager:CreateParticle(particle_drain, PATTACH_ABSORIGIN, caster)
	ParticleManager:SetParticleControlEnt(target.life_give_particle, 0, caster, PATTACH_POINT_FOLLOW, "attach_hitloc", caster:GetAbsOrigin(), true)
	ParticleManager:SetParticleControlEnt(target.life_give_particle, 1, target, PATTACH_POINT_FOLLOW, "attach_hitloc", target:GetAbsOrigin(), true)
end

function LifeDrainAllyEnd( keys )
	local caster = keys.caster
	local target = keys.target
	local sound_loop = keys.sound_loop
	local sound_target = keys.sound_target

	-- End the particle
	ParticleManager:DestroyParticle(target.life_give_particle, false)
	ParticleManager:ReleaseParticleIndex(target.life_give_particle)
	target.life_give_particle = nil

	-- Stop the looping sound
	target:StopSound(sound_target)
	target:StopSound(sound_loop)
end

Касаемо анимации не имею представления, как использовать модификатор для отслеживания цели анимации, так как при банальном использовании caster и target анимация применяется у последнего применившего юнита, а у прошлого останавливается. (как понимаю просто меняется caster для данной анимации, новой анимации не создаётся)
 
Последнее редактирование модератором:
[quote author=Epselot link=topic=1258.msg7675#msg7675 date=1484842761]
Благодарю за разъяснения. От части всё получилось, от части бафа передачи маны, а вот от части анимации не получилось и не могло получиться, так как в ней модификатор не используется.

Код:
function LifeDrainAllyStart( keys )
	local caster = keys.caster
	local target = keys.target
	local particle_drain = keys.particle_drain
	local sound_loop = keys.sound_loop

	-- Stop any ongoing looping sound on the target
	target:StopSound(sound_loop)
	target:EmitSound(sound_loop)

	-- End any pre-existing particle
	if target.life_give_particle then
		ParticleManager:DestroyParticle(target.life_give_particle, false)
		ParticleManager:ReleaseParticleIndex(target.life_give_particle)
	end
	
	-- Play ally particle
	target.life_give_particle = ParticleManager:CreateParticle(particle_drain, PATTACH_ABSORIGIN, caster)
	ParticleManager:SetParticleControlEnt(target.life_give_particle, 0, caster, PATTACH_POINT_FOLLOW, "attach_hitloc", caster:GetAbsOrigin(), true)
	ParticleManager:SetParticleControlEnt(target.life_give_particle, 1, target, PATTACH_POINT_FOLLOW, "attach_hitloc", target:GetAbsOrigin(), true)
end

function LifeDrainAllyEnd( keys )
	local caster = keys.caster
	local target = keys.target
	local sound_loop = keys.sound_loop
	local sound_target = keys.sound_target

	-- End the particle
	ParticleManager:DestroyParticle(target.life_give_particle, false)
	ParticleManager:ReleaseParticleIndex(target.life_give_particle)
	target.life_give_particle = nil

	-- Stop the looping sound
	target:StopSound(sound_target)
	target:StopSound(sound_loop)
end

Касаемо анимации не имею представления, как использовать модификатор для отслеживания цели анимации, так как при банальном использовании caster и target анимация применяется у последнего применившего юнита, а у прошлого останавливается. (как понимаю просто меняется caster для данной анимации, новой анимации не создаётся)
[/quote]
Ну запиши в ability. Абилка то у двух разных героев разная.
 
Последнее редактирование модератором:
Реклама: