Добавлен , опубликован
Алгоритмы, Наработки и Способности
Способ реализации:
Jass
Тип:
Способность
Версия Warcraft:
1.29+
Мои первые MUI способности на Jass. Критика приветствуется.
Список изменений:
1.4.1
Исправлены значения из глобального обновления.
Немного переработаны способности.
Убран талант.
Бар каста над Келем теперь локальный.
У "Феникса" приоритетной целью стали герои, даже если они "беззащитные".
Исправлено описание баффа "Зеленеющие сферы".
Дамми живут 0.10 сек. вместо 1.00.
Добавлено измерение урона для теста.
1.4
Глобальное обновление: добавлены официальные характеристики урона, здоровья, скорости восстановления и т.д. Теперь требуется версия Warcraft 1.29+
Изменено описание.
Исправлена и оптимизирована "Живая бомба".
Добавлен недостающий скрипт для "Феникса".
1.3
Добавлены недостающие скрипты для "Живой бомбы" и "Феникса":
"Живая бомба" теперь летит в качестве снаряда до цели, после закрепляется.
"Феникс" теперь летит от Келя в указанную точку и после этого встает в боевую позицию (отсчет времени "Феникса" начинается, когда он долетит до указанной точки).
Изменено действие "Живой бомбы".
"Огненному столбу" возвращена 1 секунда срабатывания.
Ускорение движения "Искажения гравитации" (но уменьшен радиус) и "Огненной глыбы".
Снаряды теперь летят от героя до указанной точки (ранее от героя + некоторое расстояние).
Небольшое увеличение модельки "Феникса".
Добавлены иконки из HotS.
1.2.8
Мелкие правки (плавность анимаций, эффекты).
1.2.7
Живая бомба теперь взрывается при смерти цели с эффектом "Живой бомбы" с задержкой 100мс.
Уменьшен радиус "Живой бомбы".
Правки в области "Огненного столба".
"Огненный столб" больше не накладывает вторую бомбу, если таковой эффект уже есть.
Исправлено применение "Огненной глыбы".
Добавлено видео последней версии наработки героя.
1.2.6
Искажение гравитации теперь оглушает, а не вводит в паузу.
Исправлена визуальная часть Искажения гравитации.
Визуальное улучшение анимаций и способностей.
Правка дистанции/области всех способностей.
Добавлено превью.
1.2.5
Оптимизирована "Живая бомба".
Удалены лишние скрипты после оптимизации. При копировании "Огненного столба" теперь необходим триггер со способностью "Живая бомба".
Применение способностей теперь мгновенное.
1.2.1
Небольшие правки в перезарядке "Зеленеющих сфер".
Добавлено видео для ознакомления.
1.2
Удалены/заменены некоторые скрипты.
Исправлено наложение "Живой бомбы", если эффект "Живой бомбы" уже присутствовал на цели.
Способность "Зеленеющие сферы" (Канал) заменена на способность "Берсерк", дабы не отменять текущий приказ кастера. Добавлена способность-пустышка для триггерного кулдауна.
Добавлены скрипты для кулдауна способности "Зеленеющие сферы" после применения способностей, которые улучшаются "Зеленеющими сферами".
Снижено время жизни дамми до 1 сек.
1.1
Исправлено действие бомбы после первого взрыва.
Добавлена модель, показывающая состояние каста Огненной глыбы.
1.0
Первая версия.
Инструкция по импорту:
  1. в константах убрать прибавку от характеристик героя, кроме маны (+1 за уровень).
  2. скопировать импортируемую модель, иконки, баффы, способности, юнитов.
  3. скопировать код и в нем изменить код юнитов и применяемых способностей. (например: 'A000' на тот, что в РО (редакторе объектов). Название и код переменных можно посмотреть с помощью сочетания клавиш Ctrl + D.
  4. создавать/нанимать героя, чтобы задействовать инициализацию (можно сделать свою, но я привел оптимальный вариант).
ВНИМАНИЕ! ПРЕДУПРЕЖДЕНИЕ! Версия Warcraft должна быть не ниже 1.29 (возможно, работает и на 1.28)!
Описание:
  • Огненный столб: "После 1 сек. наносит 345 (+4% за уровень) ед. урона по области.
    Под воздействием «Зеленеющих сфер» радиус действия способности увеличивается на 50%."
  • Живая бомба: "Наносит противнику 126 (+4% за уровень) ед. урона в течение 3-х секунд, а затем взрывается, нанося еще 215 (+4% за уровень) ед. урона противникам поблизости. Взрыв «Живой бомбы» накладывает эффект этой способности на всех еще не пораженных ею ближайших героев противника.
    Под воздействием "Зеленеющих Сфер" способность не требует затрат маны и не имеет времени восстановления."
  • Искажение гравитации: "Оглушает первого пораженного противника на 1 сек.
    Под воздействием «Зеленеющих Сфер» оглушает до 3-х противников и продлевает время оглушения на 50%."
  • Зеленеющие сферы: "Улучшает первые три способности Кель'таса."
  • Феникс (1 ульт): "Выпускает в выбранную область феникса, наносящего 78 (+4% за уровень) ед. урона всеми противникам на пути. Феникс продолжает существовать в течение 7 сек., нанося противникам 78 (+4% за уровень) ед. урона автоатаками и 50% от этого значения в качестве урона по области."
  • Огненная глыба (2 ульт): "Спустя 1.5 сек. выпускает во вражеского героя медленно летящий огненный шар, наносящий 810 (+5% за уровень) ед. урона цели и 405 (+5% за уровень) ед. урона ближайшим противникам."
Код
Код способностей и систем характеристик
Огненный столб
function SpellFCCond takes nothing returns boolean
    return GetSpellAbilityId()=='A002'
endfunction

function TickFC takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer h = GetHandleId(t)
    local unit enemy
    local unit caster = LoadUnitHandle(Hash,h,2)
    local effect e = LoadEffectHandle(Hash,h,4)
    local real xRect = LoadReal(Hash,h,5)
    local real yRect = LoadReal(Hash,h,7)
    local boolean Gain = LoadBoolean(Hash,h,6)
    local real Frect = 150.00
    local group G = CreateGroup()
    local player PlayerEnemy
    local player PlayerCaster = GetOwningPlayer(caster)
    local integer data = GetUnitUserData(caster)
    local real damage = DamageFlamestrike[0][data]
    
    call DestroyEffect(e)
    
    if Gain == true then
        Frect = 225.00
    endif

        call GroupEnumUnitsInRange(G, xRect, yRect, Frect, null)
        loop
            set enemy = FirstOfGroup(G)
            set PlayerEnemy = GetOwningPlayer(enemy)
            if IsPlayerEnemy(PlayerEnemy, PlayerCaster) and GetWidgetLife( enemy ) >.405 then
                call UnitDamageTarget( caster, enemy, damage, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_FIRE, null )
            endif
        call GroupRemoveUnit(G,enemy)
        exitwhen enemy == null
        endloop

    call GroupClear(G)
    call DestroyGroup(G)
    call FlushChildHashtable(Hash,h)
    call PauseTimer(t)
    call DestroyTimer (t)
        
    set caster = null
    set e = null
    set G = null
    set t = null
endfunction

function SpellFC takes nothing returns nothing
    local timer t = CreateTimer()
    local integer h = GetHandleId(t)
    local unit caster = GetTriggerUnit()
    local real locX = GetSpellTargetX()
    local real locY = GetSpellTargetY()
    local string str = "Abilities\\Spells\\Human\\FlameStrike\\FlameStrike1.mdl"
    local effect e = AddSpecialEffect(str,locX,locY)
    local boolean Gain = false
    if GetUnitAbilityLevel(caster, 'A002') == 2 then
        call ExecuteFunc("OrbsCooldown")
        set Gain = true
        call UnitRemoveAbility(caster, 'Asph' )
        call UnitRemoveAbility(caster, 'B001')
        call SetUnitAbilityLevel( caster, 'A000', 1 )
        call SetUnitAbilityLevel( caster, 'A002', 1 )
        call SetUnitAbilityLevel( caster, 'A003', 1 )
    endif
    call SaveUnitHandle(Hash,h,2,caster)
    call SaveEffectHandle(Hash,h,4,e)
    call SaveReal(Hash,h,5,locX)
    call SaveReal(Hash,h,7,locY)
    call SaveBoolean(Hash,h,6,Gain)
    TimerStart (t,1, false, function TickFC)
    set caster = null
    set e = null
    set t = null
endfunction
Живая бомба
function SpellBombCond takes nothing returns boolean
    return GetSpellAbilityId()=='A000'
endfunction

function TickBombEnd takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer h = GetHandleId(t)
    local unit caster = LoadUnitHandle(Hash,h,2)
    local integer i = LoadInteger(Hash,h,3)
    local unit enemy
    local player PlayerEnemy
    local player PlayerCaster = GetOwningPlayer(caster)
    local real array x
    local real array y
    local unit array target
    local string spell = "Abilities\\Weapons\\LavaSpawnMissile\\LavaSpawnBirthMissile.mdl"
    local string attach = "chest"
    local integer data = GetUnitUserData(caster)
    local real damage = DamageLifeBombRect[0][data]
    local real damageLow = DamageLifeBomb[0][data]
    local real Frect = 200.00
    local integer nMax = LoadInteger(Hash,h,4)
    local integer n = 0
    local group G = CreateGroup()
    local integer numbGroup = 0
    local real timeR = LoadReal(Hash,h,5)
    set timeR = timeR + 0.01
    call SaveReal(Hash,h,5,timeR)
    
    loop
        set n = n + 1
        set target[n] = LoadUnitHandle(Hash,h,n+10)
            if target[n] != null then
                set numbGroup = numbGroup + 1
                set x[n] = GetUnitX(target[n])
                set y[n] = GetUnitY(target[n])
            endif
    exitwhen n == nMax
    endloop
    
    set n = 0
    loop
        set n = n + 1
        if i == 6 and timeR == 3 or GetWidgetLife( target[n] ) <=.405 then
            call GroupEnumUnitsInRange(G, x[n], y[n], Frect, null)
                loop
                    set enemy = FirstOfGroup(G)
                    set PlayerEnemy = GetOwningPlayer(enemy)
                    if IsPlayerEnemy(PlayerEnemy, PlayerCaster) and GetWidgetLife( enemy ) >.405 then
                        call UnitDamageTarget( caster, enemy, damage, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_FIRE, null )
                        call DestroyEffect(AddSpecialEffectTarget(spell, enemy, attach))
                    endif
                    call GroupRemoveUnit(G,enemy)
                    exitwhen enemy == null
                endloop
            if n == nMax or numbGroup == 0 then
                call GroupClear(G)
                call DestroyGroup(G)
                call FlushChildHashtable(Hash,h)
                call PauseTimer(t)
                call DestroyTimer (t)
            endif
        else
            if timeR == 1 or timeR == 2 then
                call UnitDamageTarget( caster, target[n], damageLow, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_FIRE, null )
            endif
        endif
    
    exitwhen n == nMax
    endloop
    
    call GroupClear(G)
    call DestroyGroup(G)
        
        if timeR == 1 or timeR == 2 then
            set i = i + 1
            call SaveInteger(Hash,h,3,i)
        endif
        
        set n = 0
        loop
            set n = n + 1
            set target[n] = null
        exitwhen n == nMax
        endloop

        set t = null
        set caster = null
        set G = null
endfunction

function TickBomb takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer h = GetHandleId(t)
    local unit target = LoadUnitHandle(Hash,h,1)
    local unit caster = LoadUnitHandle(Hash,h,2)
    local integer i = LoadInteger(Hash,h,3)
    local integer n = 1
    local integer data = GetUnitUserData(caster)
    local real damage = DamageLifeBombRect[0][data]
    local real damageLow = DamageLifeBomb[0][data]
    local real timeR = LoadReal(Hash,h,6)
    set timeR = timeR + 0.01
    call SaveReal(Hash,h,6,timeR)
    
    if (i == 3 and timeR == 3) or (GetWidgetLife( target ) <=.405) then
        local group G = CreateGroup()
        local unit enemy
        local string eff1 = "Abilities\\Weapons\\LavaSpawnMissile\\LavaSpawnBirthMissile.mdl"
        local string attach = "chest"
        local string spell = "unholyfrenzy"
        local real x = GetUnitX(target)
        local real y = GetUnitY(target)
        local player PlayerEnemy
        local player PlayerCaster = GetOwningPlayer(caster)
        local unit array arrayEnemy
        local real Frect = 200.00
        local timer k = CreateTimer()
        local integer g = GetHandleId(k)
        local integer nMax = 0
        call DestroyEffect(AddSpecialEffectTarget(eff1, target, attach))
        set n = 0
        set i = i + 1
        call GroupEnumUnitsInRange(G, x, y, Frect, null)
        call UnitDamageTarget( caster, target, damage, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_FIRE, null )
        loop
            set enemy = FirstOfGroup(G)
            set PlayerEnemy = GetOwningPlayer(enemy)
            if IsPlayerEnemy(PlayerEnemy, PlayerCaster) and enemy != target and GetWidgetLife( enemy ) >.405 then
                call UnitDamageTarget( caster, enemy, damage, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_FIRE, null )
                if GetWidgetLife( enemy ) >.405 and IsUnitType(enemy, UNIT_TYPE_HERO) == true then
                    local real face = GetUnitFacing(enemy) * -1.00
                    local real life = 0.1
                    local real x1 = GetUnitX(enemy)
                    local real y1 = GetUnitY(enemy)
                    local unit unitDummy = CreateUnit( PlayerCaster, 'h003', x1, y1, face )
                    set n = n + 1
                    set arrayEnemy[n] = enemy
                    call UnitApplyTimedLife(unitDummy, 'BTFL', life )
                    call IssueTargetOrder(unitDummy, spell, enemy )
                    call SaveUnitHandle(Hash,g,n+10,arrayEnemy[n])
                    call SaveUnitHandle(Hash,g,2,caster)
                    call SaveInteger(Hash,g,3,i)
                    call SaveInteger(Hash,g,4,n)
                    set unitDummy = null
                endif
            endif
            call GroupRemoveUnit(G,enemy)
            exitwhen enemy == null
        endloop
        
        if n > 0 then
            TimerStart (k,0.01, true, function TickBombEnd)
        else
            call FlushChildHashtable(Hash,g)
            call DestroyTimer(k)
        endif

        call GroupClear(G)
        call DestroyGroup(G)
        
        set nMax = n
        set n = 0
        loop
            set n = n + 1
            set arrayEnemy[n] = null
        exitwhen n == nMax or nMax <= 0
        endloop
        
        call FlushChildHashtable(Hash,h)
        call PauseTimer(t)
        call DestroyTimer(t)

        set G = null
        set k = null
    else
        if timeR == 1 or timeR == 2 then
            call UnitDamageTarget( caster, target, damageLow, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_FIRE, null )
            set i = i + 1
            call SaveInteger(Hash,h,3,i)
        endif
    endif
    
    set target = null
    set caster = null
    set t = null
endfunction

function SpellBomb_Move takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer h = GetHandleId(t)
    local unit target = LoadUnitHandle(Hash,h,1)
    local unit caster = LoadUnitHandle(Hash,h,2)
    local integer i = 1
    local unit bomb = LoadUnitHandle(Hash,h,4)
    local real X1 = GetUnitX(bomb)
    local real X2 = GetUnitX(target)
    local real Y1 = GetUnitY(bomb)
    local real Y2 = GetUnitY(target)
    local real angle = Atan2(Y2 - Y1, X2 - X1)
    local real dist = SquareRoot((X2 - X1) * (X2 - X1) + (Y2 - Y1) * (Y2 - Y1))

    call SetUnitX(bomb, X1 + 20 * Cos(angle))
    call SetUnitY(bomb, Y1 + 20 * Sin(angle))
    
    if dist <= 10.00 then
        if GetUnitAbilityLevel(target, 'B000') <= 0 then
            local player PlayerCaster = GetOwningPlayer(caster)
            local unit dummy = CreateUnit( PlayerCaster, 'h003', X2, Y2, angle )
            local integer data = GetUnitUserData(caster)
            local real damage = DamageLifeBomb[0][data]
            local timer r = CreateTimer()
            local integer g = GetHandleId(r)
            local real life = 0.1
            local string spell = "unholyfrenzy"
            
            call UnitApplyTimedLife(dummy, 'BTLF', life )
            call IssueTargetOrder( dummy, spell, target )
            call UnitDamageTarget( caster, target, damage, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_FIRE, null )
            call SaveUnitHandle(Hash,g,1,target)
            call SaveUnitHandle(Hash,g,2,caster)
            call SaveInteger(Hash,g,3,i)
            TimerStart (r,0.01, true, function TickBomb)

            set r = null
            set dummy = null
        endif
        call KillUnit(bomb)
        call FlushChildHashtable(Hash,h)
        call PauseTimer(t)
        call DestroyTimer(t)
    endif

    set t = null
    set target = null
    set caster = null
    set bomb = null
endfunction

function SpellBomb takes nothing returns nothing 
    local timer t = CreateTimer()
    local integer h = GetHandleId(t)
    local unit caster = GetTriggerUnit()
    local unit target = GetSpellTargetUnit()
    local real x = GetUnitX(caster)
    local real y = GetUnitY(caster)
    local real face = GetUnitFacing(caster)
    local real life = 0.1
    local player PlayerCaster = GetOwningPlayer(caster)
    local unit bomb = CreateUnit( PlayerCaster, 'h006', x, y, face )

    if GetUnitAbilityLevel(target, 'B000') <= 0 then
        if GetUnitAbilityLevel(caster, 'A000') == 2 then
            call IssueImmediateOrder(caster, "stop")
            call SetUnitAnimation(caster, "Spell")
                 QueueUnitAnimation(caster, "Stand")
            call ExecuteFunc("OrbsCooldown")
            call UnitRemoveAbility (caster, 'A000')
            call UnitAddAbility (caster, 'A000')
            call UnitRemoveAbility(caster, 'Asph' )
            call UnitRemoveAbility(caster, 'B001')
            call SetUnitAbilityLevel( caster, 'A002', 1 )
            call SetUnitAbilityLevel( caster, 'A003', 1 )
        endif
    call SaveUnitHandle(Hash,h,1,target)
    call SaveUnitHandle(Hash,h,2,caster)
    call SaveUnitHandle(Hash,h,4,bomb)
    TimerStart (t,0.01, true, function SpellBomb_Move)
    else
        if GetUnitAbilityLevel(caster, 'A000') == 2 then
            call IssueImmediateOrder(caster, "stop")
            call UnitRemoveAbility (caster, 'A000')
            call UnitAddAbility (caster, 'A000')
            call SetUnitAbilityLevel( caster, 'A000', 2 )
        else
            call IssueImmediateOrder(caster, "stop")
            call UnitRemoveAbility (caster, 'A000')
            call UnitAddAbility (caster, 'A000')
        endif
    endif
    set t = null
    set target = null
    set caster = null
    set bomb = null
endfunction
Искажение гравитации
function Gravity_Cond takes nothing returns boolean
    return GetSpellAbilityId()=='A003'
endfunction

function Gravity_Act takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer h = GetHandleId(t)
    local unit target = LoadUnitHandle(Hash,h,1)
    call UnitRemoveAbility( target, 'Arav' )
    call UnitRemoveAbility( target, 'Abun' )
    call FlushChildHashtable(Hash,h)
    call DestroyTimer(t)
    set t = null
    set target = null
endfunction

function Gravity_Fly_Off takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer h = GetHandleId(t)
    local unit targetGravity = LoadUnitHandle(Hash,h,5)
    call SetUnitFlyHeight( targetGravity, GetUnitDefaultFlyHeight(targetGravity) - 175, 800 )
    call PauseTimer(t)
    call DestroyTimer(t)
    set targetGravity = null
    set t = null
endfunction

function Gravity_Move takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer h = GetHandleId(t)
    local unit gravity = LoadUnitHandle(Hash,h,1)
    local unit caster = LoadUnitHandle(Hash,h,10)
    local real face = GetUnitFacing(gravity)
    local real path = LoadReal(Hash,h, 17)
    local group G = CreateGroup()
    local unit enemy
    local boolean Gain = LoadBoolean(Hash,h,15)
    local real time
    local player PlayerEnemy
    local player PlayerCaster = GetOwningPlayer(caster)
    local real distance = 450.00
    local real x = GetUnitX(gravity) + 5 * Cos(face* bj_DEGTORAD)
    local real y = GetUnitY(gravity) + 5 * Sin(face* bj_DEGTORAD)
    local real obl = 60.00
    local integer i = LoadInteger(Hash,h,3)
    call SetUnitX(gravity, x)
    call SetUnitY(gravity, y)
    set path = path + 5
    call SaveReal(Hash,h,17,path)
    call GroupEnumUnitsInRange(G, x, y, obl, null)
        loop
            set enemy = FirstOfGroup(G)
            set PlayerEnemy = GetOwningPlayer(enemy)
            if IsPlayerEnemy(PlayerEnemy, PlayerCaster) and GetUnitAbilityLevel(enemy,'B002') <= 0 and GetUnitAbilityLevel(enemy,'Abun') <= 0 and GetWidgetLife( enemy ) >.405 then
                if i < 3 then
                local timer k = CreateTimer()
                local timer jump = CreateTimer()
                local integer g = GetHandleId(k)
                local integer v = GetHandleId(jump)
                local real m = 0.05
                local real x1 = GetUnitX(enemy)
                local real y1 = GetUnitY(enemy)
                local unit dummy = CreateUnit(PlayerCaster,'h003', x1, y1, face)
                local unit e = CreateUnit( PlayerCaster, 'h002', x1, y1, face )
                    if Gain == true then
                        set time = 1.5
                        set i = i + 1
                        call SetUnitAbilityLevel(dummy,'A009',2)
                    else
                        set time = 1.0
                        set i = 3
                    endif
                    call UnitAddAbility(enemy,'Abun')
                    call UnitApplyTimedLife(e, 'BTFL', time - time*0.50)
                    call IssueTargetOrder(dummy,"thunderbolt",enemy)
                    call UnitApplyTimedLife(dummy,'BTFL', 0.1)
                    call SetUnitFlyHeight( enemy, GetUnitDefaultFlyHeight(enemy) + 175, 800 )
                    call UnitAddAbility( enemy, 'Arav' )
                    call SaveUnitHandle(Hash,g,1,enemy)
                    call SaveUnitHandle(Hash,v,5,enemy)
                    call SaveInteger(Hash,h,3,i)
                    call SaveReal(Hash,v,6,m)
                    call SaveReal(Hash,v,7,time)
                    call SaveBoolean(Hash,v,8,Gain)
                    TimerStart(k,time,false,function Gravity_Act)
                    TimerStart(jump,time - time*0.025,false,function Gravity_Fly_Off)
                    set e = null
                    set jump = null
                    set k = null
                    set dummy = null
                    endif
            endif
            call GroupRemoveUnit(G,enemy)
            exitwhen enemy == null
        endloop
        
        if path >= distance or i == 3 then
            call RemoveUnit(gravity)
            call GroupClear(G)
            call DestroyGroup(G)
            call FlushChildHashtable(Hash,h)
            call PauseTimer(t)
            call DestroyTimer(t)
        endif
    
    call GroupClear(G)
    call DestroyGroup(G)
    set t = null
    set gravity = null
    set caster = null
    set G = null
endfunction

function Gravity takes nothing returns nothing
    local timer t = CreateTimer()
    local integer h = GetHandleId(t)
    local unit caster = GetTriggerUnit()
    local player PlayerCaster = GetOwningPlayer(caster)
    local real X1 = GetSpellTargetX()
    local real X2 = GetUnitX(caster)
    local real Y1 = GetSpellTargetY()
    local real Y2 = GetUnitY(caster)
    local real angle = Atan2(Y1 - Y2, X1 - X2)
    local boolean Gain = false
    local real x = X2 + 1 * Cos(angle)
    local real y = Y2 + 1 * Sin(angle)
    local unit gravity = CreateUnit( PlayerCaster, 'h002', x, y, angle*bj_RADTODEG )
    call SetUnitX(gravity, x)
    call SetUnitY(gravity, y)
    if GetUnitAbilityLevel(caster, 'A003') == 2 then
        call ExecuteFunc("OrbsCooldown")
        set Gain = true
        call UnitRemoveAbility(caster, 'Asph' )
        call UnitRemoveAbility(caster, 'B001')
        call SetUnitAbilityLevel(caster, 'A000', 1 )
        call SetUnitAbilityLevel(caster, 'A002', 1 )
        call SetUnitAbilityLevel(caster, 'A003', 1 )
    endif
    call SaveUnitHandle(Hash,h,1,gravity)
    call SaveUnitHandle(Hash,h,10,caster)
    call SaveBoolean(Hash,h,15,Gain)
    call TimerStart(t,.01,true,function Gravity_Move)
    set t = null
    set gravity = null
    set caster = null
endfunction
Зеленеющие сферы
Перезарядка
function OrbsCooldownTime takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer h = GetHandleId(t)
    local unit caster = LoadUnitHandle(Hash,h,1)
    local integer i = LoadInteger(Hash,h,2)
    set i = i + 1
    if i == 6 and GetWidgetLife( caster ) >.405 then
        call UnitAddAbility (caster, 'A00A')
        call UnitRemoveAbility (caster, 'A006')
        call FlushChildHashtable(Hash,h)
        call DestroyTimer(t)
    else
        if i >= 6 then
            set i = 5
        endif
        call SaveInteger(Hash,h,2,i)
    endif
    set t = null
    set caster = null
endfunction

function OrbsCooldown takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local timer y = CreateTimer()
    local integer h = GetHandleId(t)
    local integer i = GetHandleId(y)
    local unit caster = GetTriggerUnit()
    call SaveUnitHandle(Hash,i,1,caster)
    call TimerStart(y,1,true,function OrbsCooldownTime)
    call DestroyTimer(t)
    set t = null
    set caster = null
endfunction
Код
function Trig_Orbs_Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A00A'
endfunction

function Trig_Orbs_Actions takes nothing returns nothing
    local unit caster = GetTriggerUnit()
    call UnitAddAbility(caster, 'Asph' )
    call SetUnitAbilityLevel( caster, 'A000', 2 )
    call SetUnitAbilityLevel( caster, 'A002', 2 )
    call SetUnitAbilityLevel( caster, 'A003', 2 )
    call UnitRemoveAbility (caster, 'A00A')
    call UnitAddAbility (caster, 'A006')
    set caster = null
endfunction
Феникс
function Trig_Phoenix_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A004'
endfunction

function Phoenix_Orders takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer h = GetHandleId(t)
    local unit phoenix = LoadUnitHandle(Hash,h,1)
    local unit enemyOrder = LoadUnitHandle(Hash,h,2)
    local real X1 = GetUnitX(phoenix)
    local real Y1 = GetUnitY(phoenix)
    local player PlayerEnemy
    local player PlayerCaster = GetOwningPlayer(phoenix)
    local group G = CreateGroup()
    local boolean order = false
    local unit enemy
    
    if phoenix != null and GetWidgetLife(phoenix) >.405 then
        if enemyOrder == null or GetWidgetLife(enemyOrder) <=.405 then
            set enemyOrder = null
            call GroupEnumUnitsInRange(G, X1, Y1, 400, null)
            loop
                set enemy = FirstOfGroup(G)
                set PlayerEnemy = GetOwningPlayer(enemy)
                if IsPlayerEnemy(PlayerEnemy, PlayerCaster) and GetWidgetLife( enemy ) >.405 and IsUnitType(enemy, UNIT_TYPE_HERO) == true then
                    set order = true
                    call IssueTargetOrder(phoenix, "attack", enemy)
                    set enemyOrder = enemy
                    call SaveUnitHandle(Hash,h,2,enemyOrder)
                endif
                call GroupRemoveUnit(G,enemy)
                exitwhen enemy == null or order == true
            endloop
        endif
    else
        call GroupClear(G)
        call DestroyGroup(G)
        call FlushChildHashtable(Hash,h)
        call PauseTimer(t)
        call DestroyTimer(t)
    endif
    
    call GroupClear(G)
    call DestroyGroup(G)
    
    set t = null
    set phoenix = null
    set enemyOrder = null
    set G = null
endfunction

function Phoenix_Move takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer h = GetHandleId(t)
    local unit phoenix = LoadUnitHandle(Hash,h,1)
    local unit caster = LoadUnitHandle(Hash,h,2)
    local real X1 = GetUnitX(phoenix)
    local real X2 = LoadReal(Hash,h,3)
    local real Y1 = GetUnitY(phoenix)
    local real Y2 = LoadReal(Hash,h,4)
    local player PlayerEnemy
    local player PlayerCaster = GetOwningPlayer(caster)
    local real dist = SquareRoot((X2 - X1) * (X2 - X1) + (Y2 - Y1) * (Y2 - Y1))
    local real angle = Atan2(Y2 - Y1, X2 - X1)
    local group G = CreateGroup()
    local group DUG = LoadGroupHandle(Hash,h,5)
    local integer data = GetUnitUserData(caster)
    local real damage = DamagePhoenix[0][data]
    local unit enemy
    local boolean order = false
    
    call SetUnitFacing(phoenix, angle*bj_RADTODEG)
    call SetUnitX(phoenix, X1 + 5 * Cos(angle))
    call SetUnitY(phoenix, Y1 + 5 * Sin(angle))
    
    if dist <= 10.00 then
        local timer k = CreateTimer()
        local integer g = GetHandleId(k)
        call GroupEnumUnitsInRange(G, X1, Y1, 400, null)
        loop
            set enemy = FirstOfGroup(G)
            set PlayerEnemy = GetOwningPlayer(enemy)
            if IsPlayerEnemy(PlayerEnemy, PlayerCaster) and GetWidgetLife( enemy ) >.405 and IsUnitType(enemy, UNIT_TYPE_HERO) == true and IsUnitInGroup(enemy, DUG) == false then
                set order = true
                call IssueTargetOrder(phoenix, "attack", enemy)
                call SaveUnitHandle(Hash,g,1,phoenix)
                call SaveUnitHandle(Hash,g,2,enemy)
            endif
            call GroupRemoveUnit(G,enemy)
            exitwhen enemy == null or order == true
        endloop
        call TimerStart(k,0.01,true,function Phoenix_Orders)
        call GroupClear(G)
        call DestroyGroup(G)
        call GroupClear(DUG)
        call DestroyGroup(DUG)
        call FlushChildHashtable(Hash,h)
        call PauseTimer(t)
        call DestroyTimer(t)
        call UnitApplyTimedLife(phoenix, 'BTLF', 7.00 )
        set k = null
    else
        call GroupEnumUnitsInRange(G, X1, Y1, 80, null)
        loop
            set enemy = FirstOfGroup(G)
            set PlayerEnemy = GetOwningPlayer(enemy)
            if IsPlayerEnemy(PlayerEnemy, PlayerCaster) and GetWidgetLife( enemy ) >.405 and IsUnitInGroup(enemy, DUG) == false then
                call UnitDamageTarget( caster, enemy, damage, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_FIRE, null )
                call GroupAddUnit(DUG, enemy)
            endif
            call GroupRemoveUnit(G,enemy)
            exitwhen enemy == null
        endloop
    endif
    
    call SaveGroupHandle(Hash,h,5, DUG)
    call GroupClear(G)
    call DestroyGroup(G)
    
    set caster = null
    set G = null
    set DUG = null
    set t = null
    set phoenix = null
    set enemy = null
endfunction

function Trig_Phoenix_Actions takes nothing returns nothing
    local timer t = CreateTimer()
    local integer h = GetHandleId(t)
    local unit caster = GetTriggerUnit()
    local integer data = GetUnitUserData(caster)
    local unit j = GetTriggerUnit()
    local real X1 = GetSpellTargetX()
    local real X2 = GetUnitX(caster)
    local real Y1 = GetSpellTargetY()
    local real Y2 = GetUnitY(caster)
    local real angle = Atan2(Y1 - Y2, X1 - X2)
    local player pl = GetOwningPlayer(j)
    local unit phoenix = CreateUnit( pl, 'h000', X2, Y2, angle*bj_RADTODEG )
    local group G = CreateGroup()
    call BlzSetUnitBaseDamage( phoenix, R2I(DamagePhoenix[0][data]), 1 )
    call SaveUnitHandle(Hash,h,1,phoenix)
    call SaveUnitHandle(Hash,h,2,caster)
    call SaveReal(Hash,h,3,X1)
    call SaveReal(Hash,h,4,Y1)
    call SaveGroupHandle(Hash,h,5,G)
    call TimerStart(t,0.01,true,function Phoenix_Move)
    set caster = null
    set t = null
    set phoenix = null
    set j = null
    set G = null
endfunction
Огненная глыба
function Pyroblast_Cond takes nothing returns boolean
    return GetSpellAbilityId()=='A005'
endfunction

function Pyroblast_Move takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer h = GetHandleId(t)
    local unit pyroblast = LoadUnitHandle(Hash,h,1)
    local unit target = LoadUnitHandle(Hash,h,2)
    local unit caster = LoadUnitHandle(Hash,h,3)
    local real X1 = GetUnitX(pyroblast)
    local real X2 = GetUnitX(target)
    local real Y1 = GetUnitY(pyroblast)
    local real Y2 = GetUnitY(target)
    local real angle = Atan2(Y2 - Y1, X2 - X1)
    local player PlayerCaster = GetOwningPlayer(caster)
    local integer data = GetUnitUserData(caster)
    local real damage = DamagePyroblast[0][data]
    local real damageLow = DamagePyroblastRect[0][data]
    local real dist = SquareRoot((X2 - X1) * (X2 - X1) + (Y2 - Y1) * (Y2 - Y1))
    local real distance = 200
    if GetWidgetLife( target ) >.405 then
    call SetUnitFacing(pyroblast, angle*bj_RADTODEG)
    call SetUnitFlyHeight(pyroblast,GetUnitFlyHeight(target),dist)
    call SetUnitX(pyroblast, X1 + 2.5 * Cos(angle))
    call SetUnitY(pyroblast, Y1 + 2.5 * Sin(angle))
        if dist <= 10.00 then
            local group G = CreateGroup()
            local unit enemy
            local player player1
            call GroupEnumUnitsInRange(G, X1, Y1, distance, null)
            loop
                set enemy = FirstOfGroup(G)
                player1 = GetOwningPlayer(enemy)
                if IsPlayerEnemy(player1, PlayerCaster) and enemy != target then
                    call UnitDamageTarget( caster, enemy, damageLow, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_FIRE, null )
                endif
                call GroupRemoveUnit(G,enemy)
                exitwhen enemy == null
            endloop
            call UnitDamageTarget( caster, target, damage, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_FIRE, null )
            call KillUnit(pyroblast)
            call GroupClear(G)
            call DestroyGroup(G)
            call FlushChildHashtable(Hash,h)
            call PauseTimer(t)
            call DestroyTimer(t)
            set G = null
            set player1 = null
        endif
    else
        call UnitRemoveAbility( caster, 'A005' )
        call UnitAddAbility( caster, 'A005' )
        call KillUnit(pyroblast)
        call FlushChildHashtable(Hash,h)
        call PauseTimer(t)
        call DestroyTimer(t)
    endif
    
    set t = null
    set pyroblast = null
    set caster = null
    set target = null
endfunction

function Pyroblast_Scale takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer h = GetHandleId(t)
    local unit pyroblast = LoadUnitHandle(Hash,h,1)
    local unit array dummy
    local unit target = LoadUnitHandle(Hash,h,2)
    local unit caster = LoadUnitHandle(Hash,h,3)
    local real scale = LoadReal(Hash,h,4)
    local real face = GetUnitFacing(caster)
    local real X1 = GetUnitX(caster) + 75 * Cos(face* bj_DEGTORAD)
    local real x1 = GetUnitX(caster)
    local real X2 = GetUnitX(target)
    local real Y1 = GetUnitY(caster) + 75 * Sin(face* bj_DEGTORAD)
    local real Y2 = GetUnitY(target)
    local integer n = 0
    local boolean spell = GetUnitCurrentOrder(caster) == 852119
    if spell == true and IsUnitType(caster, UNIT_TYPE_STUNNED) == false or GetWidgetLife( caster ) >.405  then
        local real dist = 1.50
        set scale = scale + 0.05
        call SetUnitScale( pyroblast, scale, scale, scale )
        call SetUnitPosition(pyroblast, X1, Y1)
        call SetUnitFacing(pyroblast,face)
        if scale >= dist then
            local timer tick = CreateTimer()
            local integer l = GetHandleId(tick)
            call UnitRemoveAbility( caster, 'Amrf' )
            loop
            exitwhen (n == 11)
                set dummy[n] = LoadUnitHandle(Hash,h,5+n)
                call KillUnit(dummy[n])
                set dummy[n] = null
            set n = n + 1
            endloop
            call SaveUnitHandle(Hash,l,1,pyroblast)
            call SaveUnitHandle(Hash,l,2,target)
            call SaveUnitHandle(Hash,l,3,caster)
            call TimerStart(tick,.01,true,function Pyroblast_Move)
            call FlushChildHashtable(Hash,h)
            call PauseTimer(t)
            call DestroyTimer(t)
            set tick = null
        else
            call SaveReal(Hash,h,4,scale)
            if scale == 0.65 then
                call SetUnitAnimationByIndex(caster,5)
                QueueUnitAnimation(caster,"stand")
            endif
        endif
        
        set pyroblast = null
        set target = null
        set caster = null
        set t = null
    else
        
        call UnitRemoveAbility( caster, 'A005' )
        call UnitAddAbility( caster, 'A005' )
        loop
        exitwhen (n == 11)
            set dummy[n] = LoadUnitHandle(Hash,h,5+n)
            call KillUnit(dummy[n])
            set dummy[n] = null
        set n = n + 1
        endloop
        call KillUnit(pyroblast)
        call FlushChildHashtable(Hash,h)
        call PauseTimer(t)
        call DestroyTimer(t)
        set pyroblast = null
        set target = null
        set caster = null
        set t = null
    endif
endfunction

function Pyroblast takes nothing returns nothing
    local unit caster = GetTriggerUnit()
    local unit target = GetSpellTargetUnit()
    local timer t = CreateTimer()
    local integer h = GetHandleId(t)
    local real face = GetUnitFacing(caster)
    local player PlayerCaster = GetOwningPlayer(caster)
    local real scale = 1.0
    local real x = GetUnitX(caster) + 75 * Cos(face* bj_DEGTORAD)
    local real x1 = GetUnitX(caster)
    local real y = GetUnitY(caster) + 75 * Sin(face* bj_DEGTORAD)
    local real y1 = GetUnitY(caster)
    local unit pyroblast = CreateUnit( PlayerCaster, 'h001', x, y, face )
    local unit array dummy
    
    local integer i = 'h007'
    local integer l = 0
    loop
	exitwhen (l == 11)
        if (l == GetPlayerId(PlayerCaster) and GetLocalPlayer() == PlayerCaster) then
            i = 'h004'
        endif
    set dummy[l] = CreateUnit( Player(l), i, x, y, face )
    call SetUnitTimeScale( dummy[l], 0.50 )
    call SetUnitScale( dummy[l], 1.5, 1, 1 )
    call SaveUnitHandle(Hash,h,5+l,dummy[l])
        set i = 'h007'
    set dummy[l] = null
	set l = l + 1
    endloop
    call SetUnitPathing( pyroblast, false )
    call SetUnitScale( pyroblast, scale, scale, scale )
    call SaveUnitHandle(Hash,h,1,pyroblast)
    call SaveUnitHandle(Hash,h,2,target)
    call SaveUnitHandle(Hash,h,3,caster)
    call TimerStart(t,.05,true,function Pyroblast_Scale)
    set t = null
    set pyroblast = null
    set caster = null
    set target = null
endfunction
Визуальное исправление анимаций при мгновенном касте
function Trig_AnimationSpell_Conditions takes nothing returns boolean
	return GetUnitTypeId(GetTriggerUnit()) == 'KAEL'
endfunction

function Trig_AnimationSpell_Actions takes nothing returns nothing
    local unit caster = GetTriggerUnit()
    local integer abil = GetSpellAbilityId()
    if abil != 'A005' and abil != 'A00A' then
        call SetUnitAnimation(caster,"spell")
        QueueUnitAnimation(caster,"stand")
    endif
    set caster = null
endfunction

//===========================================================================
function InitTrig_AnimationSpell takes nothing returns nothing
    set gg_trg_AnimationSpell = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_AnimationSpell, EVENT_PLAYER_UNIT_SPELL_ENDCAST )
    call TriggerAddCondition( gg_trg_AnimationSpell, Condition( function Trig_AnimationSpell_Conditions ) )
    call TriggerAddAction( gg_trg_AnimationSpell, function Trig_AnimationSpell_Actions )
endfunction
Глобальная инициализация
function Kael_Start takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local integer n = GetUnitUserData( u )
        if GetUnitTypeId(u) == 'KAEL' then
            if n <= 0 then
                set NumberOfKael = NumberOfKael + 1
                set LifeRegen[0][NumberOfKael] = 0.033
                set ManaRegen[0][NumberOfKael] = 0.03
                set Life[0][NumberOfKael] = GetUnitState(u, UNIT_STATE_MAX_LIFE)
                set Mana[0][NumberOfKael] = GetUnitState(u, UNIT_STATE_MAX_MANA)
                set DamageLifeBomb[0][NumberOfKael] = 126
                set DamageLifeBombRect[0][NumberOfKael] = 215
                set DamageFlamestrike[0][NumberOfKael] = 345
                set DamagePyroblast[0][NumberOfKael] = 810
                set DamagePyroblastRect[0][NumberOfKael] = 405
                set DamagePhoenix[0][NumberOfKael] = 78
                set Damage[0][NumberOfKael] = BlzGetUnitBaseDamage(u, 1)
                call SetUnitUserData( u, NumberOfKael )
                set DamageLifeBomb[0][NumberOfKael] = DamageLifeBomb[0][NumberOfKael] + (DamageLifeBomb[0][NumberOfKael] * 0.04)
                set DamageLifeBombRect[0][NumberOfKael] = DamageLifeBombRect[0][NumberOfKael] + (DamageLifeBombRect[0][NumberOfKael] * 0.04)
                set DamageFlamestrike[0][NumberOfKael] = DamageFlamestrike[0][NumberOfKael] + (DamageFlamestrike[0][NumberOfKael] * 0.04)
                set DamagePyroblast[0][NumberOfKael] = DamagePyroblast[0][NumberOfKael] + (DamagePyroblast[0][NumberOfKael] * 0.05)
                set DamagePyroblastRect[0][NumberOfKael] = DamagePyroblastRect[0][NumberOfKael] + (DamagePyroblastRect[0][NumberOfKael] * 0.05)
                set DamagePhoenix[0][NumberOfKael] = DamagePhoenix[0][NumberOfKael] + (DamagePhoenix[0][NumberOfKael] * 0.04)
                set Kael[NumberOfKael] = u
            endif
        endif
    set u = null
endfunction
Регенерация
function Trig_Regen_Actions takes nothing returns nothing
    local integer n = 0
    loop
        set n = n + 1
        call SetUnitState( Kael[n], UNIT_STATE_LIFE, GetUnitState(Kael[n], UNIT_STATE_LIFE) + LifeRegen[0][n])
        call SetUnitState( Kael[n], UNIT_STATE_MANA, GetUnitState(Kael[n], UNIT_STATE_MANA) + ManaRegen[0][n])
    exitwhen n == NumberOfKael or NumberOfKael == 0
    endloop
endfunction
Повышение уровня
function Trig_LvlUp_Conditions takes nothing returns boolean
    return GetUnitTypeId(GetTriggerUnit()) == 'KAEL'
endfunction

function Trig_LvlUp_Actions takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local integer data = GetUnitUserData(u)
    set Life[0][data] = Life[0][data] + (Life[0][data] * 0.04)
    set Mana[0][data] = Mana[0][data] + 10
    set Damage[0][data] = Damage[0][data] + (Damage[0][data] * 0.04)
    set DamageLifeBomb[0][data] = DamageLifeBomb[0][data] + (DamageLifeBomb[0][data] * 0.04)
    set DamageLifeBombRect[0][data] = DamageLifeBombRect[0][data] + (DamageLifeBombRect[0][data] * 0.04)
    set DamageFlamestrike[0][data] = DamageFlamestrike[0][data] + (DamageFlamestrike[0][data] * 0.04)
    set DamagePyroblast[0][data] = DamagePyroblast[0][data] + (DamagePyroblast[0][data] * 0.05)
    set DamagePyroblastRect[0][data] = DamagePyroblastRect[0][data] + (DamagePyroblastRect[0][data] * 0.05)
    set DamagePhoenix[0][data] = DamagePhoenix[0][data] + (DamagePhoenix[0][data] * 0.04)
    set LifeRegen[0][data] = LifeRegen[0][data] + (LifeRegen[0][data] * 0.04 )
    set ManaRegen[0][data] = ManaRegen[0][data] + (ManaRegen[0][data] * 0.04 )
    call BlzSetUnitMaxHP( u, R2I(Life[0][data] + 0.5))
    call BlzSetUnitMaxMana( u, R2I(Mana[0][data]))
    call BlzSetUnitBaseDamage( u, R2I(Damage[0][data] + 0.5), 1 )
    set u = null
endfunction


`
ОЖИДАНИЕ РЕКЛАМЫ...
0
20
6 лет назад
Отредактирован Diaboliko
0
Кстати, рекомендую использовать вместо
GetUnitState(target, UNIT_STATE_LIFE)<=0
это
GetWidgetLife( target ) < =.405
Многие программисты говорят, что в загруженных картах эта функция (и именно цифра 0.405) лучше и надежнее. Сам не замечал изменений, правда.
0.405 потому-что это такое магическое число. Имея 0.406 хп юнит еще жив. При этом если юнит удалён из игры (деспавном, например), то может твориться неведомая хрень.
А вообще есть хорошая нативка из функций для ИИ UnitAlive. Ее надо явно определить в джасс-скрипте карты, но с ней ни у кого не возникало багов :)
0
28
6 лет назад
0
добавь в ресурс список изменений
и каждый раз как чтото меняешь пиши об этом в этот список
0
28
6 лет назад
0
Многие программисты говорят, что в загруженных картах эта функция (и именно цифра 0.405) лучше и надежнее.
Лучше и надёжнее использовать эти функции.
function UnitIsAlive takes unit u returns boolean
    return not IsUnitType(u, UNIT_TYPE_DEAD)
endfunction

function UnitIsDead takes unit u returns boolean
    return IsUnitType(u, UNIT_TYPE_DEAD) // returns false, if unit does not exist.
endfunction
0
8
6 лет назад
0
В коде пока что у Искажения гравитации есть ошибка в строчке проверки integer переменной (i > 5), должна быть i >= 5.
В самой наработке все правильно.
0
21
6 лет назад
0
PT153, IsUnitType(u, UNIT_TYPE_DEAD) вернет false, если u == null. То есть функция скажет, что несуществующий юнит еще живой.
0
8
6 лет назад
Отредактирован Atesla
0
Ошибся. Не у гравитации, а у перезарядки Сфер.
4
16
6 лет назад
Отредактирован DracoL1ch
4
есть четкая нативка UnitAlive, которую достаточно объявить и использовать. Варианта ЛУЧШЕ этого нет. Проверка на тип мервтого не сгодится для удаленных юнитов, а вот эта работает как надо
0
21
6 лет назад
0
функция от лича действительно ни разу еще не подвела, всем советую:
function IsDead takes unit u returns boolean
return GetWidgetLife(u) < 0.405 or IsUnitType(u,UNIT_TYPE_DEAD)
endfunction
2
28
6 лет назад
Отредактирован PT153
2
IsUnitType(u, UNIT_TYPE_DEAD) вернет false, если u == null. То есть функция скажет, что несуществующий юнит еще живой.
Я об этом и написал в комментарии. Такое поведение логично, нужно отдельно проверять, если юнита нет.
DracoL1ch:
есть четкая нативка UnitAlive
Я почему-то думал, что это функция берёт integer как аргумент.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.