[lua] Всё о визуализации способностей в Warcraft3

Содержание:

Heart Bit

Создадим пассивную способность, которая будет визуально пульсировать, чтобы игрок знал, как часто она срабатывает и на сколько лечит, просто потому что могу, потому что это прикольно, потому что это нестандартная релизация простых вещей.
и так поехали:
Пульс сердца
Каждое сердцебиение исцеляет мясника
Объём лечения: 50
Частота сердцебиения: 3.
Уменьшается на 0.2 сек за каждые 10% потерянного здоровья. Минимальная 1 сек.

Код

Основой всего кода является функция
function ScalingIconTimed(FrameTexture, secShow, posButton, text,hero)
	if not IsUnitSelected(hero,GetOwningPlayer(hero))  then
		return
	end
	local size = 0
	local sec = 0
	local i = 1
	local turn = true
	local next = 0.039
	local fh = BlzCreateFrameByType("BACKDROP", "FaceButtonIcon", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "", 0)
	BlzFrameSetSize(fh, next, next)
	BlzFrameSetTexture(fh, FrameTexture, 0, true)
	local CBPoz = BlzGetFrameByName("CommandButton_" .. posButton, 0) -- CommandButton_0
	BlzFrameSetPoint(fh, FRAMEPOINT_CENTER, CBPoz, FRAMEPOINT_CENTER, 0, 0)
	local newText = BlzCreateFrameByType("TEXT", "ButtonChargesText", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "", 0)
	BlzFrameSetText(newText, text)
	BlzFrameSetPoint(newText, FRAMEPOINT_CENTER, CBPoz, FRAMEPOINT_CENTER, 0, 0)

	if not GetLocalPlayer()==GetOwningPlayer(hero) then
		BlzFrameSetVisible(fh,false)
		BlzFrameSetVisible(fh,false)
	end

	TimerStart(CreateTimer(), TIMER_PERIOD, true, function()
		sec = sec + TIMER_PERIOD
		size = size + (i * 0.005)
		if sec >= secShow and turn then
			turn = false
			i = i * (-1)
		end
		if size <= 0 then
			DestroyTimer(GetExpiredTimer())
			BlzDestroyFrame(fh)
			BlzDestroyFrame(newText)
			size = 0
		end
		BlzFrameSetSize(fh, next + size, next + size)
		BlzFrameSetScale(newText, (next + size) * 50)
	end)
end
function ScalingIconTimed(FrameTexture, secShow, posButton, text,hero)
где:
FrameTexture - текстура фрейма, я использовал по хитрому через BlzGetAbilityIcon(HeartAbility) получение иконки у способности
secShow - общее время увеличения фрейма в обе стороны, по факту иконку увеличивается в течении 0.1 сек и столько же уменьшается
posButton - позиция нашей иконки от 0 до 11, в панели приказов начиная от левого верхнего угла, где левый верхний угол - 0
text - в центре способности, если ничего не надо можно поставить пустые кавычки ""
hero - юнит нашей способности

Вспомогательные функции

лечение
function HealUnit(hero,amount,flag,eff)
	--1 или nil Сколько вылчено
	--2 Сверхлечение
	if not eff then eff="Abilities\\Spells\\Human\\Heal\\HealTarget" end
	local p=GetOwningPlayer(hero)
	local MaxHP=BlzGetUnitMaxHP(hero)
	local CurrentHP=GetUnitState(hero,UNIT_STATE_LIFE)
	local LoosingHP=MaxHP-CurrentHP
	local OverHeal=amount-LoosingHP
	local TotalHeal=amount
	if LoosingHP<=amount then TotalHeal=LoosingHP	end
	DestroyEffect(AddSpecialEffectTarget(eff,hero,"overhead"))
	SetUnitState(hero,UNIT_STATE_LIFE,CurrentHP+TotalHeal)
	if TotalHeal>1 then
		FlyTextTagHealXY(GetUnitX(hero),GetUnitY(hero),"+"..R2I(TotalHeal),p)
	end
	if not flag or flag==1 then
		return TotalHeal
	end
	if  flag==2 then
		return OverHeal
	end
end
Текстаг
function FlyTextTag(text, textSize, x, y, z, red, green, blue, alpha, xvel, yvel, fadepoint, lifespan, player)
	local t = CreateTextTag()
	SetTextTagText(t, text, textSize)
	SetTextTagPos(t, x, y, z)
	SetTextTagColor(t, red, green, blue, alpha)
	SetTextTagVelocity(t, xvel, yvel)
	SetTextTagFadepoint(t, fadepoint)
	SetTextTagLifespan(t, lifespan)
	SetTextTagPermanent(t, false)
	if player ~= nil then
		SetTextTagVisibility(t, player == GetLocalPlayer())
	end
	return t
end
function FlyTextTagHealXY(x,y, text, player)
	return FlyTextTag(text, 0.024, x, y, 150, 88, 250, 13, 255, 0, 0.03, 1, 3, player)
end
ну и сама способность мясника
function HearBit(hero)
	local healAmount=50
	local loosingHP=100-(GetUnitState(hero,UNIT_STATE_LIFE)/BlzGetUnitMaxHP(hero)*100)
	local nextBit=3-loosingHP*.02
	ScalingIconTimed(BlzGetAbilityIcon(HeartAbility), 0.2, 5, healAmount,hero) -- 5 определяет позицию иконки 1.1
	local tl = Location(GetUnitX(hero),GetUnitY(hero))
	PlaySoundAtPointBJ(soundBit, 100, tl, 0)
	--print("playsoind")
	RemoveLocation(tl)
	--print("Тут лечим юнита "..loosingHP)
	HealUnit(hero,healAmount)
	TimerStart(CreateTimer(), nextBit, false, function()
		if UnitAlive(hero) then
			HearBit(hero)
		else
			HeartAbilityUnits[GetHandleId(hero)]=nil
		end
	end)
end
Ну а как же без видосика,
И карты примера

`
ОЖИДАНИЕ РЕКЛАМЫ...