Добавлен , опубликован
Способ реализации:
Lua
Версия Warcraft:
В основе наработки лежит новая функция BlzPauseUnitEx и 2 её самые главные особенности:
  1. Не исчезают иконки с панели приказов, в отличии от старой паузы
  2. Если юнит уже запаузен, то он не выйдет из паузы после её окончания, есть так называемый счетчик пауз (жаль его количество нельзя узнать), Вкратце: если на юнита 10 раз наложили паузу, нужно её 10 раз снять
раскрыть
stunEff="Abilities\\Spells\\Human\\Thunderclap\\ThunderclapTarget"
StunSystem={}
function StunUnit(hero,dur)
	if not StunSystem[GetHandleId(hero)] then
	--	print("оглушен первый раз")
		StunSystem[GetHandleId(hero)]={
			Time=0,
			Eff=nil,
			Timer=nil
		}
	end
	local data=StunSystem[GetHandleId(hero)]
	local curdur=0
	if data.Time==0 then
		data.Timer=CreateTimer()
		--print("старт нового таймера")
		data.Eff=AddSpecialEffectTarget(stunEff,hero,"overhead")
		BlzPauseUnitEx(hero,true)
	end

	if data.Time<dur  then
		--print("Более сильное оглушение, обновляем время")
		data.Time=dur
	else
		--print("Есть более долгое оглушение ничего не делаем")
		return
	end

	TimerStart(data.Timer, 0.1, true, function()
		curdur=curdur+0.1
		data.Time=data.Time-0.1
		if curdur>=dur or not UnitAlive(hero) then
			--print("Вышел из стана")
			BlzPauseUnitEx(hero,false)
			DestroyTimer(GetExpiredTimer())
			data.Time=0
			DestroyEffect(data.Eff)
			data.Timer=nil
		end
	end)
end
Вызывать в любом месте через StunUnit(hero,dur).
Где hero - юнит которого хотим оглушить
А dur - время оглушения в секундах
Чтобы узнать в стане ли юнит, достаточно проверить состояние функцией IsUnitPaused, тут конечно да, есть пересечения с простой паузой, но можно этим просто пренебречь.
В будущем планируется:
  1. Добавить индикатор стана в виде прогресс бара, для оглушенного юнита или же просто отображать секунды через текстаг
  2. Добавить очищение от оглушения, ну скажем сильное развеивание достаточно редкая вещь, как только надобность появиться - сразу сделаю
`
ОЖИДАНИЕ РЕКЛАМЫ...
9
Еще нужно добавить параметр, что стан не продлевается, а начинает отсчет заново.
Ну или если стан который чел получил по времени меньше, чем текущий(который остался), то заменить, иначе - нет.
22
Я лишь прочитал текст описания и код. Пожалуй раскритикую данную функцию.
  • В статус баре юнита нет иконки баффа "Оглушения" (или другого баффа вообще)
  • При паузе у юнита ставятся на паузу таймеры все баффоы, типа ауры, отравленный нож...
  • Как писал quq_CCCP, нативное оглушение в вар3 - это приказ, а поскольку механика в функции отличается, то могут быть проблемы с метаморфозами и сном (в теории)
21
В будущем планируется:
Добавить индикатор стана в виде прогресс бара, для оглушенного юнита или же просто отображать секунды через текстаг
а шо мешало сразу это добавить? )

Если юнит уже запаузен, то он не выйдет из паузы после её окончания, есть так называемый счетчик пауз (жаль его количество нельзя узнать), Вкратце: если на юнита 10 раз наложили паузу, нужно её 10 раз снять
внатуре? ля так это ж изи тогда ваще

В статус баре юнита нет иконки баффа "Оглушения" (или другого баффа вообще)
ну это легко дополнить, если добавить кастомный бафф
Тут суть в другом - имеет ли смысл этот метод, если в мапе энивэй используется дамми для каких-нибудь других целей? Если используется дамми для чего-то ещё, то просто тогда сделать стан от дамми и не париться
Тем более, что можно параметры абилки менять щас, т.е. можно перед кастом стана от дамми, установить ему нужную длительность стана и всё
22
local dbUnits = {}

function SetUnitStun(u, c)
local h = GetHandleId(u)

if dbUnits[h] == nil then
dbUnits[h] = 0
end

local step = c - dbUnits[h]
local isDelete = step < 0
dbUnits[h] = c

if isDelete then
step = (step * -1)
end

while step do
if isDelete then
BlzPauseUnitEx(u, false)
else
BlzPauseUnitEx(u, true)
end
step = step - 1
end


end

function GetUnitStun(unit)
return dbUnits[GetHandleId(unit)] or 0
end

вот и все 2 функция готов и спокойно знаете счетчик

итог спокойно можно
SetUnitStun(unit, 10)
то счетчик будет обновлять
Забыл добавить для обновление бд юнита счетчик

и можно проверку делать чтобы ниже 0 не ставилось а указал количество от 0 до 10
SetUnitStun(unit, 10)
10 раз установит паузу
SetUnitStun(unit, 4)
Снимает 6 раз паузу
15
Вероятно стоит хукнуть функцию UnitRemoveBuff, чтобы стан снимался ее вызовом, а так же добавить флаги positive/negative/neutral.
33
За замечания и предложения всем спасибо, буду развивать дальше
Bornikkeny, бафф в статусе пусть идёт лесом, в 1 карте я смог все эффекты повторить без ваших дамми кастов, поэтому нет смысла вообще поддерживать всякие яды и замедлялки сидите и дальше в своем РО.
32
Ну как сказать, все это дело не быстрее стандартных абилок, так что продвигать как панацею для замены всех станов эту наработку не нужно.
И если уж решил делать кастом стан - как насчет попутно реализовать стандартный диспел для последнего? При смерти или при еще каких действиях.
Насколько помню - эта нативка работа рук китайцев и отличается лишь отключенным сайленсом у дефолтной паузы, хз что оно еще делает, не ломает ли длительность баффов и прочего?
33
quq_CCCP, ах лол, снова это слово "быстрее", вы рофлите чтоле все???, тут нет дамми и ро, такое настроить и пееренсти - 1 клик, это быстрее в первую очередь хотя бы поэтому!
quq_CCCP:
так что продвигать как панацею для замены всех станов эту наработку не нужно
Не стоит вообще ничего продвигать, у каждого способы свои плюсы и минусы и все имеют место быть!
Зачем мне вообще париться над длительностью бафов, если у меня нет бафов в принципе, ммм?
При смерти добавлено всё, юнит очищается от стана, ты написал комментарий даже не читая текст, найс просто
16
Зачем использовать бгмерзский таймер, если ты хочешь детектить смерть юнита? Если его реснут за период таймера, то счётчик останется.
Если юнит сменит форму во время стана, визуалка отвалится, поэтому её крепят к абилке - баффу.
Обычный стан болт будет быстрее на дистанции за счёт того, что не требует таймера 0.1 и выполнения кода после броска. Для коротких станов скорость не имеет значения
Ну и если использовать триггерный стан на кастера в момент каста, то кд не начнётся, в отличие от н классического болта.
Во тебе пространство для улучшений)
33
DracoL1ch, ок спасибо

Но оглушение накладывается мгновенно, а не ждёт первого тика таймера, тут уже проблем нет, таймер для подсчета секунд и оглушение, насчет воскрешения спасибо что сказал, реально если реснуть за период таймера 0.1, это конечно случай 1 на 1000, поймать этот баг, но хорошо что я знал об это заранее, спасибище
DracoL1ch:
Ну и если использовать триггерный стан на кастера в момент каста, то кд не начнётся,
Верно поэтому у меня все кастаймы по 0 в принципе у себя я это вылечил, тут скорее всего для нормальных условий надо накладывать стан не во момент каста а в момент события endcast, хотя тоже ультра редкое действие как "стан на себя во время каста"
32
Bergi_Bear, я имел ввиду события норм а не проверку таймерами, есть более простые и быстре способы узнать что юнит умер или на него накинули диспел, чем проверять 10 раз в секунду это.
33
ну да, логично, я понял тебя, имеешь ввиду диспелить по событию смерти, да это действительно лучше
32
Bergi_Bear, ну еще можно отлавливать каст диспелов, так сложно сделать бд ид абилок при касте которых снимать стан? Как думаешь, явно лучше чем таймером проверять? При этом 1 триггер как на смерти так и на касты? Не? Сложно?
Чтобы оставить комментарий, пожалуйста, войдите на сайт.