Добавлен , опубликован
Способ реализации:
Версия Warcraft:
Наработка героя Кел'Тузада из игры Heroes of the Storm. Способности MUI. Критика приветствуется.
Список изменений:
1.3
Глобальное обновление: добавлены официальные характеристики урона, здоровья, скорости восстановления и т.д. Теперь требуется версия Warcraft 1.29+
"Ледяной взрыв" теперь корректно летит до трупа.
Изменение "Цепей Кел'Тузада": ускорение притягивание к зданиям, дамми цепей заменены на молнию с текстурой цепей, притягивание больше не работает вплотную.
Исправлен баг, когда область "Смерть и разложение" смещалась в сторону (дамми).
Небольшие изменения в скриптах.
Исправлено описание способности "Цепи Кел'Тузада" при имеющейся цели с эффектом "Цепей".
Бар "Цепей Кел'Тузада" стал локальным.
Замена модели "Ледового шипа".
1.2.2
Небольшая переработка "Цепей Кел'Тузада": ускорено притягивание, оглушение срабатывает при притягивании вместо того, чтобы срабатывать при попадании "Цепями".
Снаряды теперь летят от героя до указанной точки (ранее от героя + некоторое расстояние).
Небольшая работа над эффектами.
1.2.1
Немного переделана пауза у "Ледового шипа".
Эффект молнии возвращен (нет, у меня не биополярное расстройство :D).
Правка быстрого притягивания Цепей.
Оптимизация скриптов.
Добавлена модель Лича (спасибо Daro).
1.2
Кел'Тузад изменен (не полностью) в связи с последним обновлением:
Добавлена новая способность – Ледовый шип.
Иконки заменены на "родные" из HotS.
Перезарядка и затраты маны из HotS.
Заменен и исправлен эффект молнии.
Исправление эффектов.
Исправлены мелкие ошибки.
Удалены лишние баффы.
Убрана тень дамми снаряда способности "Смерть и разложение" [Q].
1.1.4
Смерть и разложение теперь вновь взрывается там, где она попадает по цели, а не в местоположение цели.
Исправление начального местоположения Ледяного взрыва.
Ледяной взрыв немного уменьшен.
Внедрение в юнита числа handle заменен на массив, который его вбирает по номеру массива юнита (Цепи Кел'Тузада).
Правка Цепей Кел'Тузада в MUI.
Добавлено видео последней версии наработки.
Убрана анимация у способности "Владыка холодной тьмы".
1.1.3
Цепями теперь можно притягивать и зданием, если оно носит на себе цепь.
Комментарий: из-за моей невнимательности и игры в "пробном" режиме за Кел'Тузада я не заметил баг, из-за которого цепи застревали в здании, а значит, и не притягивали к себе союзную цель.
Ледяной взрыв больше не восстанавливается при смерти запомненной цели, если снаряд еще не долетел до нее, вместо этого он продолжает лететь до трупа.
Изменение скорости и высоты Ледяного взрыва, теперь как в HotS (полет по наклонной + ускорение). Спасибо за помощь одному очень хорошему человечку.
Мелкие правки.
1.1
Заменено триггерное замедление и обездвиживание на War'овское.
Чуть изменен принцип Цепей, визуально ничего не поменялось.
Способности применяются мгновенно, как и в HotS.
Глобальные переменные вынесены в триггер объявления глобальных переменных: копировать глобальные переменные теперь не нужно.
Исправлено применение способности "Смерть и разложение".
Удалены лишние скрипты.
1.0
Первая версия.
Инструкция по импорту:
  1. скопировать импортируемые модели, удалив лишний путь "war3mapImported\", заклинания, способности, после юнитов.
  2. скопировать код и в нем изменить равкод юнитов и применяемых способностей. (например: 'A000' на тот, что в РО (редакторе объектов). Название и равкод переменных можно посмотреть с помощью сочетания клавиш Ctrl + D.
  3. триггерно создавать/нанимать/и т.д. Кел'Тузадов. Главное – войти в в игровую зону.
Описание:
  • Смерть и разложение: "После паузы в 0,5 сек. запускает сферу, которая взрывается, попав в первую цель на своем пути, и наносит 150 (+2.5% за уровень) ед. урона противникам в области действия. После взрыва остается область разложения, которая существует 2 сек. и каждые 0,5 сек. наносит попавшим в нее противникам 82 (+2.5% за уровень) ед. урона."
  • Кольцо льда: "Создает кольцо, которое после паузы в 1 сек. взрывается, наносит противникам в области действия 180 (+2.5% за уровень) ед. урона и замедляет их на 35% на 2,5 сек. Обездвиживает противников, находящихся в эпицентре, на 1 сек."
  • Цепи Кел'Тузада: "Запускает цепь, наносящую первому герою или строению на своем пути 97 (+2.5% за уровень) ед. урона. В течение 4 сек. после попадания эту способность можно использовать повторно, чтобы запустить цепь во второго противника, притянуть обе цели друг к другу и оглушить их на 0,5 сек."
    "Выпускает новую цепь от первой цели. Если вторая цель попадает в героя или здание, наносит 97 (+2,5% за уровень) урона и притягивает обе цели друг к другу."
    Примечание: В MUI носящий цепь и притягиваемый юниты не могут быть сцеплены повторно в течение 4 секунд или пока герой-владелец не воспользуется Цепями еще раз, для цепей нужна "свежая" цель.
  • Владыка холодной тьмы:
    (!)Задача: каждый раз, когда Кел'Тузад обездвиживает героев "Кольцом льда" или попадает в них "Цепями Кел'Тузада", он получает 1 ед. "Чумы".
    (!)Награда: после накопления 15 ед. "Чумы" Кел'Тузад получает способность "Ледовый шип".
    (!)Награда: после накопления 30 ед. "Чумы" сила способностей повышается на 75%.
    Примечание: способность применяемая и не сбивает приказ (сделано для того, чтобы узнать, сколько Кел'Тузад накопил "Чумы").
  • Ледовый шип (дополнительная способность): "При использовании создает шип, который взрывается после паузы в 4 сек. и наносит 61 (+2.5% за уровень) ед. урона противникам поблизости. «Цепи Кел'Тузада» могут воздействовать на шип. Выполните задачу, чтобы использовать."
    Примечание: в обновлении 36.2 Кел'Тузад утратил способность прикреплять цепи к зданиям и наоборот взамен на новую способность "Ледовый шип". В своей наработке я оставил эту возможность, ибо она слишком крутая.
  • Ледяной взрыв (1 ульт): "Выпускает во вражеского героя ледяной заряд, который наносит 115 (+2.5% за уровень) ед. урона цели и 275 (+2.5% за уровень) ед. урона противникам в области поражения. Обездвиживает всех пораженных противников на 1,5 сек."
  • Прорыв тьмы (2 ульт): "Создает в любой точке поля боя энергетический разлом, который после паузы в 1,5 сек. взрывается и наносит 360 (+2.5% за уровень) ед. урона находящимся в ней героям."
Код
Смерть и разложение
function DaD_Cond takes nothing returns boolean
    return GetSpellAbilityId()=='ADaD'
endfunction

function DaD_Rect takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer h = GetHandleId(t)
    local unit caster = LoadUnitHandle(Hash,h,1)
    local unit dummy = LoadUnitHandle(Hash,h,2)
    local real xRect = LoadReal(Hash,h,3)
    local real yRect = LoadReal(Hash,h,4)
    local real Frect = 125
    local unit enemy
    local real time = LoadReal(Hash,h,5)
    local effect e = LoadEffectHandle(Hash,h,6)
    local integer data = GetUnitUserData(caster)
    local real damage = DamageDaDRect[0][data]
    local player PlayerEnemy
    local player PlayerCaster = GetOwningPlayer(caster)
    local group G = CreateGroup()
    set time = time + 0.5
    call SaveReal(Hash,h,5,time)
    if GetUnitAbilityLevel(caster, 'SPAS') == 3 then
        set damage = damage + (damage * 0.75)
    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_DEATH, null )
            endif
            call GroupRemoveUnit(G,enemy)
            exitwhen enemy == null
        endloop

        if time >= 2 then
            call DestroyEffect(e)
            call RemoveUnit(dummy)
            call FlushChildHashtable(Hash,h)
            call PauseTimer(t)
            call DestroyTimer (t)
        endif
    call GroupClear(G)
    call DestroyGroup(G)
    set t = null
    set caster = null
    set dummy = null
    set e = null
    set G = null
endfunction

function DaD_Move takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer h = GetHandleId(t)
    local unit dad = LoadUnitHandle(Hash,h,1)
    local unit caster = LoadUnitHandle(Hash,h,2)
    local real face = GetUnitFacing(dad)
    local real path = LoadReal(Hash,h,'Path')
    local group G = CreateGroup()
    local unit enemy
    local player PlayerEnemy
    local player PlayerCaster = GetOwningPlayer(caster)
    local integer data = GetUnitUserData(caster)
    local real damage = DamageDaD[0][data]
    local real distance = 600.00
    local real x = GetUnitX(dad) + 10 * Cos(face* bj_DEGTORAD)
    local real y = GetUnitY(dad) + 10 * Sin(face* bj_DEGTORAD)
    local real obl = 60.00
    local boolean b = false
    call SetUnitX(dad, x)
    call SetUnitY(dad, y)
    if GetUnitAbilityLevel(caster, 'SPAS') == 3 then
        set damage = damage + (damage * 0.75)
    endif
    set path = path + 10.00
    call SaveReal(Hash,h,'Path', path)
    call GroupEnumUnitsInRange(G, x, y, obl, null)
        loop
            set enemy = FirstOfGroup(G)
            set PlayerEnemy = GetOwningPlayer(enemy)
            if (IsPlayerEnemy(PlayerEnemy, PlayerCaster)) and GetWidgetLife( enemy ) >.405 then
                set b = true
                call UnitDamageTarget( caster, enemy, damage, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_DEATH, null )
            endif
            call GroupRemoveUnit(G,enemy)
            exitwhen enemy == null or b == true
        endloop

    call GroupClear(G)
    call DestroyGroup(G)
        
    if b == true then
        local timer k = CreateTimer()
        local integer g = GetHandleId(k)
        local unit dummy = CreateUnit( PlayerCaster, 'h002', x, y, 0 )
        local string str = "Abilities\\Spells\\Undead\\DeathandDecay\\DeathandDecayDamage.mdl"
        local effect e = AddSpecialEffect(str,x,y)
        call RemoveUnit(dad)
        call SaveUnitHandle(Hash,g,1,caster)
        call SaveUnitHandle(Hash,g,2,dummy)
        call SaveEffectHandle(Hash,g,6,e)
        call SaveReal(Hash,g,3,x)
        call SaveReal(Hash,g,4,y)
        call FlushChildHashtable(Hash,h)
        call PauseTimer(t)
        call DestroyTimer(t)
        TimerStart(k,0.5,true,function DaD_Rect)
        set dummy = null
        set k = null
        set e = null
    endif

    if path >= distance then
        call RemoveUnit(dad)
        call FlushChildHashtable(Hash,h)
        call PauseTimer(t)
        call DestroyTimer(t)
    endif
    
    set t = null
    set dad = null
    set caster = null
    set G = null
endfunction

function DaD_Cast takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer h = GetHandleId(t)
    local unit caster = LoadUnitHandle(Hash,h,2)
    local player PlayerCaster = GetOwningPlayer(caster)
    local real X1 = LoadReal(Hash,h,3)
    local real X2 = GetUnitX(caster)
    local real Y1 = LoadReal(Hash,h,4)
    local real Y2 = GetUnitY(caster)
    local real angle = Atan2(Y1 - Y2, X1 - X2)
    local real x = X2 + 1 * Cos(angle)
    local real y = Y2 + 1 * Sin(angle)
    local unit dad = CreateUnit( PlayerCaster, 'h001', x, y, angle*bj_RADTODEG )
    local effect e = LoadEffectHandle(Hash,h,5)
    local boolean spell = GetUnitCurrentOrder(caster) == 852089
    call SetUnitPropWindow(dad, 0)
    if spell == true and IsUnitType(caster, UNIT_TYPE_STUNNED) == false or GetWidgetLife( caster ) >.405  then
        local timer k = CreateTimer()
        local integer i = GetHandleId(k)
        call SetUnitX(dad, x)
        call SetUnitY(dad, y)
        call SaveUnitHandle(Hash,i,1,dad)
        call SaveUnitHandle(Hash,i,2,caster)
        call TimerStart(k,.01,true,function DaD_Move)
        set k = null
    endif
    call DestroyEffect(e)
    call FlushChildHashtable(Hash,h)
    call PauseTimer(t)
    call DestroyTimer(t)
    set t = null
    set dad = null
    set caster = null
    set e = null
endfunction

function DaD takes nothing returns nothing
    local timer t = CreateTimer()
    local integer h = GetHandleId(t)
    local unit caster = GetTriggerUnit()
    local real X1 = GetSpellTargetX()
    local real Y1 = GetSpellTargetY()
    local string eff1 = "Abilities\\Spells\\Items\\OrbCorruption\\OrbCorruptionMissile.mdl"
    local string attach = "hand"
    local effect e = AddSpecialEffectTarget(eff1, caster, attach)
    call SetUnitAnimationByIndex(caster,5)
    call QueueUnitAnimation(caster,"stand")
    call SaveUnitHandle(Hash,h,2,caster)
    call SaveReal(Hash,h,3,X1)
    call SaveReal(Hash,h,4,Y1)
    call SaveEffectHandle(Hash,h,5,e)
    call TimerStart(t,.5,false,function DaD_Cast)
    set e = null
    set t = null
    set caster = null
endfunction
Кольцо льда
function RoI_Cond takes nothing returns boolean
    return GetSpellAbilityId()=='ARoI'
endfunction

function RoI_Slowdown takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer h = GetHandleId(t)
    local unit caster = LoadUnitHandle(Hash,h,1)
    local player PlayerEnemy
    local player PlayerCaster = GetOwningPlayer(caster)
    local real x
    local real y
    local real face
    local integer data = GetUnitUserData(caster)
    local real damage = DamageRoI[0][data]
    local integer n = GetUnitUserData(caster)
    local unit enemy = GetEnumUnit()
    local effect e
    
        if GetUnitAbilityLevel(caster, 'SPAS') == 3 then
            set damage = damage + (damage * 0.75)
        endif

            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_COLD, null )
                set x = GetUnitX(enemy)
                set y = GetUnitY(enemy)
                set face = GetUnitFacing(enemy)
                if GetWidgetLife(enemy) > .405 then
                    local unit dummy = CreateUnit(PlayerCaster,'h006',x,y,face)
                    call IssueTargetOrder(dummy,"slow",enemy)
                    call UnitApplyTimedLife(dummy, 'BTFL', 0.1 )
                    call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl", enemy, "origin"))
                    set dummy = null
                endif
            endif
    
    set t = null
    set caster = null
    set enemy = null
    set e = null

endfunction

function RoI_Rect takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer h = GetHandleId(t)
    local unit caster = LoadUnitHandle(Hash,h,1)
    local integer n = GetUnitUserData(caster)
    local integer c = QuestKelThuzad[n]
    local real xRect = LoadReal(Hash,h,2)
    local real yRect = LoadReal(Hash,h,3)
    local real Frect = 200
    local unit enemy
    local effect e = LoadEffectHandle(Hash,h,4)
    local integer data = GetUnitUserData(caster)
    local real damage = DamageRoI[0][data]
    local player PlayerEnemy
    local player PlayerCaster = GetOwningPlayer(caster)
    local group G = CreateGroup()
    call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Undead\\FreezingBreath\\FreezingBreathMissile.mdl", xRect, yRect))
    call DestroyEffect(AddSpecialEffect("Abilities\\Weapons\\LichMissile\\LichMissile.mdl", xRect, yRect))
    if GetUnitAbilityLevel(caster, 'SPAS') == 3 then
        set damage = damage + (damage * 0.75)
    endif
    call GroupEnumUnitsInRange(G, xRect, yRect, Frect, null)
    call ForGroup(G, function RoI_Slowdown)
    call GroupEnumUnitsInRange(G, xRect, yRect, Frect/2, null)
        loop
            set enemy = FirstOfGroup(G)
            set PlayerEnemy = GetOwningPlayer(enemy)
            if IsPlayerEnemy(PlayerEnemy, PlayerCaster) and GetWidgetLife( enemy ) >.405 then
                local real x = GetUnitX(enemy)
                local real y = GetUnitY(enemy)
                local real face = GetUnitFacing(enemy)
                local unit dummy = CreateUnit(PlayerCaster,'h006',x,y,face)
                call UnitRemoveAbility(dummy,'A003')
                call IssueTargetOrder(dummy,"entanglingroots",enemy)
                call UnitApplyTimedLife(dummy, 'BTFL', 0.1 )
                set dummy = null
                call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl", enemy, "origin"))
                

                if IsUnitType(enemy, UNIT_TYPE_HERO) == true
                if QuestKelThuzad[n] < 15 and QuestKelThuzad[n] != -1 then
                    set QuestKelThuzad[n] = QuestKelThuzad[n] + 1
                endif
                    
                        if QuestKelThuzad[n] >= 15 and QuestKelThuzad[n] < 30 then
                            call BlzUnitDisableAbility( caster, 'AISK', false, false )
                            call SetUnitAbilityLevel( caster, 'AISK', 2 )
                            call SetUnitAbilityLevel( caster, 'SPAS', 2 )
                            set QuestKelThuzad[n] = QuestKelThuzad[n] + 1
                        endif
                        
                            if QuestKelThuzad[n] >= 30 then
                                set QuestKelThuzad[n] = -1
                                call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Human\\ReviveHuman\\ReviveHuman.mdl", caster, "origin"))
                                call SetUnitAbilityLevel( caster, 'SPAS', 3 )
                            endif
                endif
            endif
            call GroupRemoveUnit(G,enemy)
            exitwhen enemy == null
        endloop

    if c != QuestKelThuzad[n] then
        call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Other\\TalkToMe\\TalkToMe.mdl", caster, "overhead"))
    endif

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

function RoI takes nothing returns nothing
    local timer t = CreateTimer()
    local integer h = GetHandleId(t)
    local unit caster = GetTriggerUnit()
    local real X1 = GetSpellTargetX()
    local real Y1 = GetSpellTargetY()
    local string eff = "Shiva'sEnchantment.mdx"
    local effect e = AddSpecialEffect(eff, X1, Y1)
    call SaveUnitHandle(Hash,h,1,caster)
    call SaveReal(Hash,h,2,X1)
    call SaveReal(Hash,h,3,Y1)
    call SaveEffectHandle(Hash,h,4,e)
    call TimerStart(t,1,false,function RoI_Rect)
    set e = null
    set t = null
    set caster = null
endfunction
Цепи Кел'Тузада
Способность
function CoK_Cond takes nothing returns boolean
    return GetSpellAbilityId()=='ACoK'
endfunction

function CoK_MoveChain takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer h = GetHandleId(t)
    local unit caster = LoadUnitHandle(Hash,h,1)
    local unit chained = LoadUnitHandle(Hash,h,2)
    local unit enemy = LoadUnitHandle(Hash,h,3)
    local unit cok = LoadUnitHandle(Hash,h,7)
    local lightning chain = LoadLightningHandle(Hash,h,4)
    local integer data = GetUnitUserData(caster)
    local real damage = DamageCoK[0][data]
    local player PlayerCaster = GetOwningPlayer(caster)
    local real X1 = GetUnitX(enemy)
    local real Y1 = GetUnitY(enemy)
    local real X2 = GetUnitX(chained)
    local real Y2 = GetUnitY(chained)
    local real angle = Atan2(Y1 - Y2, X1 - X2)
    local real dist = SquareRoot((X2 - X1) * (X2 - X1) + (Y2 - Y1) * (Y2 - Y1))
    local real x1 = 0
    local real y1 = 0
    local real x2 = 0
    local real y2 = 0
    local real time = LoadReal(Hash,h,5)
    
    if time >= 0.1 or dist <= 120 then
    
    local boolean ifBool = IsUnitType(enemy, UNIT_TYPE_STRUCTURE) == true and GetUnitTypeId(chained) == 'hISK'
    local boolean elseBool = IsUnitType(chained, UNIT_TYPE_STRUCTURE) == true and GetUnitTypeId(enemy) == 'hISK'
    
    if IsUnitType(chained, UNIT_TYPE_STUNNED) == false or IsUnitType(enemy, UNIT_TYPE_STUNNED) == false then

        if IsUnitType(chained, UNIT_TYPE_STRUCTURE) == false then
            local unit dummyChained = CreateUnit( PlayerCaster, 'h006', X2, Y2, angle )
            call IssueTargetOrder(dummyChained,"thunderbolt",chained)
            call UnitApplyTimedLife(dummyChained, 'BTFL', 0.1 )
            set dummyChained = null
        endif

        if IsUnitType(enemy, UNIT_TYPE_STRUCTURE) == false then
            local unit dummyEnemy = CreateUnit( PlayerCaster, 'h006', X1, Y1, angle )
            call IssueTargetOrder(dummyEnemy,"thunderbolt",enemy)
            call UnitApplyTimedLife(dummyEnemy, 'BTFL', 0.1 )
            set dummyEnemy = null
        endif

    endif
    
    if dist <= 120 or enemy == null or chained == null or ifBool == true or elseBool == true then
        local integer i = GetUnitUserData(caster)
        local integer n = ChainedData[i]
        local unit dummy = LoadUnitHandle(Hash,n,3)
        local effect e = LoadEffectHandle(Hash,n,6)
        
        local real faceEnemy = GetUnitFacing(enemy)*-1
        local real xEnemy = GetUnitX(enemy) * Cos(faceEnemy* bj_DEGTORAD)
        local real yEnemy = GetUnitY(enemy) * Sin(faceEnemy* bj_DEGTORAD)
        local unit dummyEnemy = CreateUnit( PlayerCaster, 'h006', xEnemy, yEnemy, faceEnemy )

        local real faceChained = GetUnitFacing(chained)*-1
        local real xChained = GetUnitX(chained) * Cos(faceChained* bj_DEGTORAD)
        local real yChained = GetUnitY(chained) * Sin(faceChained* bj_DEGTORAD)
        local unit dummyChained = CreateUnit( PlayerCaster, 'h006', xChained, yChained, faceChained )
        
        call UnitRemoveAbility(chained, 'B001')
        call UnitRemoveAbility(enemy, 'B001')
            
        call UnitApplyTimedLife(dummyEnemy, 'BTFL', 0.1 )
        call UnitApplyTimedLife(dummyChained, 'BTFL', 0.1 )
        
        call IssueTargetOrder(dummyEnemy,"thunderbolt",enemy)
        call IssueTargetOrder(dummyChained,"thunderbolt",chained)
        
        if GetUnitAbilityLevel(caster, 'SPAS') == 3 then
            set damage = damage + (damage * 0.75)
        endif
        
        call PauseUnit(enemy, false)
        call PauseUnit(chained, false)
        call DestroyLightning(chain)
        call KillUnit(dummy)
        call RemoveUnit(cok)
        call DestroyEffect(e)
        call UnitDamageTarget( caster, enemy, damage, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, null )
        call FlushChildHashtable(Hash,n)
        call FlushChildHashtable(Hash,h)
        call PauseTimer(t)
        call DestroyTimer(t)
        set dummyEnemy = null
        set dummyChained = null
        set dummy = null
        set e = null
        
    else
        if IsUnitType(chained, UNIT_TYPE_STRUCTURE) == false and GetUnitTypeId(chained) != 'hISK' then
            set x2 = X2 + 10 * Cos(angle)
            set y2 = Y2 + 10 * Sin(angle)
            call SetUnitX(chained, x2)
            call SetUnitY(chained, y2)
        else
            set x2 = X2 + 20 * Cos(angle)
            set y2 = Y2 + 20 * Sin(angle)
        endif

        if IsUnitType(enemy, UNIT_TYPE_STRUCTURE) == false and GetUnitTypeId(enemy) != 'hISK' then
            set x1 = X1 - 10 * Cos(angle)
            set y1 = Y1 - 10 * Sin(angle)
            call SetUnitX(enemy, x1)
            call SetUnitY(enemy, y1)
        else
            set x1 = X1 - 20 * Cos(angle)
            set y1 = Y1 - 20 * Sin(angle)
        endif
    
        call SetUnitX(cok, x1)
        call SetUnitY(cok, y1)
        
        call MoveLightningEx(chain, true, x1, y1, 75 + GetUnitFlyHeight(enemy), x2, y2, 75 + GetUnitFlyHeight(chained))
    endif
    
    else
        if GetUnitPropWindow( cok ) * bj_DEGTORAD <= 0 then
            call SetUnitPropWindow(cok, GetUnitDefaultPropWindow( cok ) * bj_DEGTORAD)
        endif

        call SetUnitX(cok, X1)
        call SetUnitY(cok, Y1)
        call MoveLightningEx(chain, true, X1, Y1, 75 + GetUnitFlyHeight(enemy), X2, Y2, 75 + GetUnitFlyHeight(chained))
        set time = time + 0.01
        call SaveReal(Hash,h,5,time)
    endif
    
    set chain = null
    set cok = null
    set t = null
    set caster = null
    set chained = null
    set enemy = null
endfunction

function CoK_Move takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer h = GetHandleId(t)
    local unit cok = LoadUnitHandle(Hash,h,1)
    local unit caster = LoadUnitHandle(Hash,h,2)
    local lightning chainCoC = LoadLightningHandle(Hash,h,6)
    local real z = GetUnitFlyHeight(cok)
    local real face = GetUnitFacing(cok)
    local integer path = LoadInteger(Hash,h,'Path')
    local group G = CreateGroup()
    local unit enemy
    local player PlayerEnemy
    local player PlayerCaster = GetOwningPlayer(caster)
    
    local real distance = 550.00
    local real X2 = LoadReal(Hash,h,4) + 3 * Cos(face* bj_DEGTORAD)
    local real Y2 = LoadReal(Hash,h,5) + 3 * Sin(face* bj_DEGTORAD)
    local real x = GetUnitX(cok) + 15 * Cos(face* bj_DEGTORAD)
    local real y = GetUnitY(cok) + 15 * Sin(face* bj_DEGTORAD)
    local real X = GetUnitX(cok) - 50 * Cos(face* bj_DEGTORAD)
    local real Y = GetUnitY(cok) - 50 * Sin(face* bj_DEGTORAD)
    local real obl = 80.00
    local boolean b = false
    local integer n = GetUnitUserData(caster)
    local integer c = QuestKelThuzad[n]
    local real damage = DamageCoK[0][n]
    local integer j
    local boolean unitBool
    set path = path + 20
    
    call SaveInteger(Hash,h,'Path', path)
    call SaveReal(Hash,h,4,X2)
    call SaveReal(Hash,h,5,Y2)
    call SetUnitX(cok, x)
    call SetUnitY(cok, y)
    
    call MoveLightningEx(chainCoC, true, X2, Y2, z, X, Y, z)

    if GetUnitAbilityLevel(caster, 'SPAS') == 3 then
        set damage = damage + (damage * 0.75)
    endif

    call GroupEnumUnitsInRange(G, x, y, obl, null)
        loop
            set enemy = FirstOfGroup(G)
            set PlayerEnemy = GetOwningPlayer(enemy)
            set unitBool = (IsUnitType(enemy, UNIT_TYPE_HERO) == true or IsUnitType(enemy, UNIT_TYPE_STRUCTURE) == true or GetUnitTypeId(enemy) == 'hISK') and (enemy != Chained[n] and GetUnitAbilityLevel(enemy, 'B001') <= 0)

            if (Chained[n] == null and GetUnitTypeId(enemy) == 'hISK') then
                local unit dummy = CreateUnit(PlayerCaster,'h006',x,y,face)
                call IssueTargetOrder(dummy,"unholyfrenzy",enemy)
                call UnitApplyTimedLife(dummy, 'BTFL', 0.1 )
                set Chained[n] = FirstOfGroup(G)
                set b = true
                set dummy = null
            else
                if (Chained[n] == null and GetWidgetLife(enemy) > .405 and IsPlayerEnemy(PlayerEnemy, PlayerCaster) and GetUnitAbilityLevel(enemy, 'B006') <= 0 and unitBool == true) then
                    local unit dummy = CreateUnit(PlayerCaster,'h006',x,y,face)
                    call IssueTargetOrder(dummy,"unholyfrenzy",enemy)
                    call UnitApplyTimedLife(dummy, 'BTFL', 0.1 )
                    set Chained[n] = FirstOfGroup(G)
                    call UnitDamageTarget( caster, enemy, damage, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, null )
                    set dummy = null
                endif
            endif
            
            if Chained[n] != null then
                if unitBool == true then
                    if IsPlayerEnemy(PlayerEnemy, PlayerCaster) or GetUnitTypeId(enemy) == 'hISK' then
                        set b = true
                    endif
                else
                    if (GetWidgetLife(enemy) > .405 and IsPlayerEnemy(PlayerEnemy, PlayerCaster) and GetUnitAbilityLevel(enemy, 'B006') <= 0 and unitBool == true) then
                        set b = true
                        call UnitDamageTarget( caster, enemy, damage, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, null )
                        if GetWidgetLife(enemy) > .405 and Chained[n] == null then
                            local unit dummy = CreateUnit(PlayerCaster,'h006',x,y,face)
                            call IssueTargetOrder(dummy,"unholyfrenzy",enemy)
                            call UnitApplyTimedLife(dummy, 'BTFL', 0.1 )
                            set Test[n] = false
                            set dummy = null
                        endif
                    endif
                endif
            endif

            call GroupRemoveUnit(G,enemy)
            exitwhen enemy == null or b == true
        endloop

    if Chained[n] == null then
        set Test[n] = false
    endif

    call GroupClear(G)
    call DestroyGroup(G)

    if b == true then
        call SetUnitPropWindow(cok, 0)
        
        if Test[n] == true then
        
            if IsUnitType(enemy, UNIT_TYPE_STRUCTURE) == false or IsUnitType(Chained[n], UNIT_TYPE_STRUCTURE) == false then
        
            local timer k = CreateTimer()
            local integer v = GetHandleId(k)
            
            local real faceChained = GetUnitFacing(Chained[n])*-1
            local real xChained = GetUnitX(Chained[n])
            local real yChained = GetUnitY(Chained[n])
            
            local real faceEnemy = GetUnitFacing(enemy)*-1
            local real xEnemy = GetUnitX(enemy)
            local real yEnemy = GetUnitY(enemy)
            
            call MoveLightningEx(chainCoC, true, xChained, yChained, 75 + GetUnitFlyHeight(Chained[n]), xEnemy, yEnemy, 75 + GetUnitFlyHeight(enemy))
            
            call SetUnitAbilityLevel( caster, 'ACoK', 1 )

            if GetUnitTypeId(Chained[n]) != 'hISK' then
                call PauseUnit(Chained[n], false)
            else
                call PauseUnit(Chained[n], true)
            endif
            
            if GetUnitTypeId(enemy) != 'hISK' then
                call PauseUnit(enemy, false)
            else
                call PauseUnit(enemy, true)
            endif

            if IsUnitType(enemy, UNIT_TYPE_HERO) == true then
                
                if QuestKelThuzad[n] < 15 and QuestKelThuzad[n] != -1 then
                            set QuestKelThuzad[n] = QuestKelThuzad[n] + 1
                        endif
                    
                                if QuestKelThuzad[n] >= 15 and QuestKelThuzad[n] < 30 then
                                    call BlzUnitDisableAbility( caster, 'AISK', false, false )
                                    call SetUnitAbilityLevel( caster, 'AISK', 2 )
                                    call SetUnitAbilityLevel( caster, 'SPAS', 2 )
                                    set QuestKelThuzad[n] = QuestKelThuzad[n] + 1
                                endif
                        
                                    if QuestKelThuzad[n] >= 30 then
                                        set QuestKelThuzad[n] = -1
                                        call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Human\\ReviveHuman\\ReviveHuman.mdl", caster, "origin"))
                                        call SetUnitAbilityLevel( caster, 'SPAS', 3 )
                                    endif
                
            endif
        
                if c != QuestKelThuzad[n] then
                    call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Other\\TalkToMe\\TalkToMe.mdl", caster, "overhead"))
                endif
            
            call SaveUnitHandle(Hash,v,1,caster)
            call SaveUnitHandle(Hash,v,2,Chained[n])
            call SaveUnitHandle(Hash,v,3,enemy)
            call SaveLightningHandle(Hash,v,4,chainCoC)
            call SaveUnitHandle(Hash,v,7,cok)
            
            set Chained[n] = null
            set Test[n] = false
            set ChainedData[n] = 0
            
            call TimerStart(k,0.01,true,function CoK_MoveChain)
            
            call FlushChildHashtable(Hash,h)
            call PauseTimer(t)
            call DestroyTimer(t)
            
            set k = null
            set enemy = null
        else
            local integer data = ChainedData[n]
            local unit dummy = LoadUnitHandle(Hash,data,3)
            local effect e = LoadEffectHandle(Hash,data,6)
            
            call DestroyLightning(chainCoC)
            call SetUnitAbilityLevel( caster, 'ACoK', 2 )
            call PauseUnit(enemy, false)
            call PauseUnit(Chained[n], false)
            
            call RemoveUnit(dummy)
            call DestroyEffect(e)
            call FlushChildHashtable(Hash,data)
            
            set ChainedData[n] = 0
            set Chained[n] = null
            set dummy = null
            set e = null
        endif
        else
            local string str = "Abilities\\Spells\\Undead\\FrostArmor\\FrostArmorTarget.mdl"
            local effect e
            local real xChain = GetUnitX(Chained[n])
            local real yChain = GetUnitY(Chained[n])
            
            if GetUnitTypeId(Chained[n]) != 'hISK' and IsUnitType(Chained[n], UNIT_TYPE_STRUCTURE) == false
                set e  = AddSpecialEffectTarget(str,Chained[n],"chest")
            else
                set str = "Abilities\\Spells\\Undead\\DarkSummoning\\DarkSummonMissile.mdl"
                set e = AddSpecialEffect(str,xChain,yChain)
            endif
            
            call RemoveUnit(cok)
            call DestroyLightning(chainCoC)

            call UnitRemoveAbility( caster, 'ACoK' )
            call UnitAddAbility( caster, 'ACoK' )
            call SetUnitAbilityLevel( caster, 'ACoK', 2 )
            call SaveUnitHandle(Hash,h,1,Chained[n])
            call SaveEffectHandle(Hash,h,6,e)
            set Test[n] = true
            set j = CoK_Update()
            set ChainedData[n] = j
            call FlushChildHashtable(Hash,h)
            call PauseTimer(t)
            call DestroyTimer(t)
            
            set e = null
            set enemy = null
        endif
            
    endif

    if path >= distance and b == false then
        
        local integer i = -1
        
        call SaveInteger(Hash,h,20,i)
        call PauseUnit(Chained[n], false)
        CoK_DummyMoveToCaster()
        
        call SetUnitAbilityLevel( caster, 'ACoK', 1 )
        call RemoveUnit(cok)
        call DestroyLightning(chainCoC)
        
        call FlushChildHashtable(Hash,h)
        call PauseTimer(t)
        call DestroyTimer(t)
    endif
    
    set chainCoC = null
    set t = null
    set cok = null
    set caster = null
    set G = null
endfunction


function CoK takes nothing returns nothing
    local timer t = CreateTimer()
    local integer h = GetHandleId(t)
    local unit caster = GetTriggerUnit()
    local player PlayerCaster = GetOwningPlayer(caster)
    local integer n = GetUnitUserData(caster)
    local real X1 = GetSpellTargetX()
    local real Y1 = GetSpellTargetY()
    local real X2 = GetUnitX(Chained[n])
    local real Y2 = GetUnitY(Chained[n])
    local unit u
    local lightning chainCoC
        
    if Chained[n] == null then
        set X2 = GetUnitX(caster)
        set Y2 = GetUnitY(caster)
    endif

    local real angle = Atan2(Y1 - Y2, X1 - X2)
    local real x = X2 + 1 * Cos(angle)
    local real y = Y2 + 1 * Sin(angle)
    local unit cok
    
    if Chained[n] == null then
        set cok = CreateUnit( PlayerCaster, 'h005', x, y, angle*bj_RADTODEG )
        set u = caster
    else
        set cok = CreateUnit( PlayerCaster, 'h007', x, y, angle*bj_RADTODEG )
        set u = Chained[n]
    endif
    
    set chainCoC = AddLightningEx("COKT", true, X2, Y2, 75 + GetUnitFlyHeight(u), x, y, 75 + GetUnitFlyHeight(cok))
    call SaveUnitHandle(Hash,h,1,cok)
    call SaveUnitHandle(Hash,h,2,caster)
    call SaveReal(Hash,h,4,X2)
    call SaveReal(Hash,h,5,Y2)
    call SaveLightningHandle(Hash,h,6,chainCoC)
    call TimerStart(t,.01,true,function CoK_Move)
    set cok = null
    set t = null
    set caster = null
    set chainCoC = null
    set u = null
endfunction
Дополнительно (скопировать до блока "Способность")
function CoK_DummyMoveToCaster takes nothing returns integer
    local timer t = GetExpiredTimer()
    local integer h = GetHandleId(t)
    local unit caster = LoadUnitHandle(Hash,h,2)
    local unit array dummy
    local effect e = LoadEffectHandle(Hash,h,6)
    local real time = LoadReal(Hash,h,4)
    local integer i = LoadInteger(Hash,h,20)
    local integer n = GetUnitUserData(caster)
    local integer numb = 0
    local integer c = ChainedData[n]
    local real x = GetUnitX(caster)
    local real y = GetUnitY(caster)
    set time = time + 0.01
    call SaveReal(Hash,h,4,time)
    
    if time < 4 and GetWidgetLife (Chained[n]) >.405 and i != -1 then
        loop
        exitwhen (numb == 11)
            set dummy[numb] = LoadUnitHandle(Hash,h,3+numb)
            call SetUnitX(dummy[numb], x)
            call SetUnitY(dummy[numb], y)
            set dummy[numb] = null
        set numb = numb + 1
        endloop
    else

        loop
        exitwhen (numb == 11)
            set dummy[numb] = LoadUnitHandle(Hash,h,3+numb)
            call KillUnit(dummy[numb])
            set dummy[numb] = null
        set numb = numb + 1
        endloop

        call SetUnitAbilityLevel( caster, 'ACoK', 1 )
        call PauseUnit(Chained[n], false)
        set ChainedData[n] = 0
        set Test[n] = false
        set Chained[n] = null
        call DestroyEffect(e)
        call FlushChildHashtable(Hash,h)
        call PauseTimer(t)
        call DestroyTimer(t)
    endif

    set t = null
    set e = null
    set caster = null
    
    return h
endfunction

function CoK_Update takes nothing returns integer

    local timer t = GetExpiredTimer()
    local integer h = GetHandleId(t)
    local unit caster = LoadUnitHandle(Hash,h,2)
    local unit chained = LoadUnitHandle(Hash,h,1)
    local effect e = LoadEffectHandle(Hash,h,6)
    local integer i = LoadInteger(Hash,h,20)
    local integer j
    
    local integer n = GetUnitUserData(caster)
    local integer c = QuestKelThuzad[n]

    local real x = GetUnitX(caster)
    local real y = GetUnitY(caster)
    local player PlayerCaster = GetOwningPlayer(caster)
    local real face = GetUnitFacing(caster)

    local timer f = CreateTimer()
    local integer v = GetHandleId(f)

    local unit array dummy

    local integer rav = 'h00A'
    local integer ln = 0
    loop
	exitwhen (ln == 11)
        if (ln == GetPlayerId(PlayerCaster) and GetLocalPlayer() == PlayerCaster) then
            rav = 'h000'
        endif
    set dummy[ln] = CreateUnit( Player(ln), rav, x, y, face )
    call SetUnitTimeScale( dummy[ln], 0.25 )
    call SetUnitScale( dummy[ln], 1.5, 0.5, 1 )
    call SaveUnitHandle(Hash,v,3+ln,dummy[ln])
        set rav = 'h00A'
    set dummy[ln] = null
	set ln = ln + 1
    endloop
    set j = v

    call SaveUnitHandle(Hash,v,2,caster)
    call SaveEffectHandle(Hash,v,6,e)
    call SaveInteger(Hash,v,20,i)
    set i = 0
    call SaveInteger(Hash,h,20,i)
    call TimerStart(f,0.01,true,function CoK_DummyMoveToCaster)

    if chained != null then
        if IsUnitType(chained, UNIT_TYPE_STRUCTURE) == false then
            if QuestKelThuzad[n] < 15 and QuestKelThuzad[n] != -1 then
                            set QuestKelThuzad[n] = QuestKelThuzad[n] + 1
                        endif
                    
                                if QuestKelThuzad[n] >= 15 and QuestKelThuzad[n] < 30 then
                                    call BlzUnitDisableAbility( caster, 'AISK', false, false )
                                    call SetUnitAbilityLevel( caster, 'AISK', 2 )
                                    call SetUnitAbilityLevel( caster, 'SPAS', 2 )
                                    set QuestKelThuzad[n] = QuestKelThuzad[n] + 1
                                endif
                        
                                    if QuestKelThuzad[n] >= 30 then
                                        set QuestKelThuzad[n] = -1
                                        call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Human\\ReviveHuman\\ReviveHuman.mdl", caster, "origin"))
                                        call SetUnitAbilityLevel( caster, 'SPAS', 3 )
                                    endif
        
            if c != QuestKelThuzad[n] then
                call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Other\\TalkToMe\\TalkToMe.mdl", caster, "overhead"))
            endif

        endif
    endif

    call FlushChildHashtable(Hash,h)
    call PauseTimer(t)
    call DestroyTimer(t)
    
    set chained = null
    set f = null
    set e = null
    set t = null
    set caster = null

return j

endfunction
Ледовый шип
Создание
function ISK_Cond takes nothing returns boolean
    return GetSpellAbilityId()=='AISK'
endfunction

function ISK_Animation takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer h = GetHandleId(t)
    local unit isk = LoadUnitHandle(Hash,h,1)
    call SetUnitAnimation(isk, "death")
    call FlushChildHashtable(Hash,h)
    call PauseTimer(t)
    call DestroyTimer(t)
    set t = null
    set isk = null
endfunction

function ISK_Create takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer h = GetHandleId(t)
    local unit caster = LoadUnitHandle(Hash,h,1)
    local player PlayerCaster = GetOwningPlayer(caster)
    local real X1 = LoadReal(Hash,h,2)
    local real X2 = GetUnitX(caster)
    local real Y1 = LoadReal(Hash,h,3)
    local real Y2 = GetUnitY(caster)
    local real angle = Atan2(Y1 - Y2, X1 - X2)
    local unit isk = CreateUnit( PlayerCaster, 'hISK', X1, Y1, angle*bj_RADTODEG )
    local integer data = GetUnitUserData(caster)

    call SetUnitUserData(isk, data)
    call UnitApplyTimedLife(isk, 'BTFL', 4 )
    call SaveUnitHandle(Hash,h,1,isk)
    call TimerStart(t, 2.8, false, function ISK_Animation)
    set t = null
    set isk = null
    set caster = null
endfunction

function ISK takes nothing returns nothing
    local timer t = CreateTimer()
    local integer h = GetHandleId(t)
    local unit caster = GetTriggerUnit()
    local real X1 = GetSpellTargetX()
    local real Y1 = GetSpellTargetY()
    call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Human\\SpellSteal\\SpellStealTarget.mdl", X1, Y1))
    call SaveUnitHandle(Hash,h,1,caster)
    call SaveReal(Hash,h,2,X1)
    call SaveReal(Hash,h,3,Y1)
    call TimerStart(t,1,false,function ISK_Create)
    set t = null
    set caster = null
endfunction
Взрыв
function Trig_ISK_Conditions takes nothing returns boolean
    return GetUnitTypeId(GetTriggerUnit()) == 'hISK'
endfunction

function Trig_ISK_Actions takes nothing returns nothing
    local unit isk = GetTriggerUnit()
    local player PlayerCaster = GetOwningPlayer(isk)
    local real x = GetUnitX(isk)
    local real y = GetUnitY(isk)
    local group G = CreateGroup()
    local player PlayerEnemy
    local unit enemy
    local integer data = GetUnitUserData(isk)
    local real damage = DamageISK[0][data]
    call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Undead\\FreezingBreath\\FreezingBreathMissile.mdl", x, y))
    call GroupEnumUnitsInRange(G, x, y, 150, null)
        loop
            set enemy = FirstOfGroup(G)
            set PlayerEnemy = GetOwningPlayer(enemy)
            if IsPlayerEnemy(PlayerEnemy, PlayerCaster) and GetWidgetLife( enemy ) >.405 then
                call UnitDamageTarget( isk, enemy, damage, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_DEMOLITION, null )
            endif
            call GroupRemoveUnit(G,enemy)
            exitwhen enemy == null
        endloop
    call GroupClear(G)
    call DestroyGroup(G)
    set G = null
    set isk = null
endfunction
Ледяной взрыв
function IceBlast_Cond takes nothing returns boolean
    return GetSpellAbilityId()=='AKIB'
endfunction

function IceBlast_Slowdown takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer h = GetHandleId(t)
    local unit caster = LoadUnitHandle(Hash,h,1)
    local player PlayerEnemy
    local player PlayerCaster = GetOwningPlayer(caster)
    local real x = 0
    local real y = 0
    local real face
    local integer data = GetUnitUserData(caster)
    local real damage = DamageKIBRect[0][data]
    local integer n = GetUnitUserData(caster)
    local unit enemy = GetEnumUnit()
    local effect e
    
        if GetUnitAbilityLevel(caster, 'SPAS') == 3 then
            set damage = damage + (damage * 0.75)
        endif

            set PlayerEnemy = GetOwningPlayer(enemy)
            if IsPlayerEnemy(PlayerEnemy, PlayerCaster) and GetWidgetLife( enemy ) >.405 and IsUnitType(enemy, UNIT_TYPE_STRUCTURE) == false then
                call UnitDamageTarget( caster, enemy, damage, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_COLD, null )
                set x = GetUnitX(enemy)
                set y = GetUnitY(enemy)
                set face = GetUnitFacing(enemy)
                if GetWidgetLife(enemy) > .405 then
                    local unit dummy = CreateUnit(PlayerCaster,'h006',x,y,face)
                    call UnitRemoveAbility(dummy,'A002')
                    call IssueTargetOrder(dummy,"entanglingroots",enemy)
                    call UnitApplyTimedLife(dummy, 'BTFL', 0.1 )
                    call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl", enemy, "origin"))
                    set dummy = null
                endif
            endif
    
    set t = null
    set caster = null
    set enemy = null
    set e = null

endfunction

function IceBlast_Move takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer h = GetHandleId(t)
    local unit iceblast = LoadUnitHandle(Hash,h,1)
    local unit target = LoadUnitHandle(Hash,h,2)
    local unit caster = LoadUnitHandle(Hash,h,3)
    local real X1 = GetUnitX(iceblast)
    local real X2
    local real Y1 = GetUnitY(iceblast)
    local real Y2
    local real angle
    local player PlayerCaster = GetOwningPlayer(caster)
    local integer data = GetUnitUserData(caster)
    local real damageLow = DamageKIB[0][data]
    local real dist
    local boolean b = false
    local group G = CreateGroup()
    local real speed = LoadReal(Hash,h,4)
    local real x
    local real y
    set speed = speed + 0.05
    call SaveReal(Hash,h,4,speed)
    
    if GetWidgetLife(target) >.405 then
        set X2 = GetUnitX(target)
        set Y2 = GetUnitY(target)
    else
        set X2 = LoadReal(Hash,h,5)
        set Y2 = LoadReal(Hash,h,6)
    endif
    
    set angle = Atan2(Y2 - Y1, X2 - X1)
    set dist = SquareRoot((X2 - X1) * (X2 - X1) + (Y2 - Y1) * (Y2 - Y1))
    set x = GetUnitFlyHeight(iceblast) / dist + speed
    set y = GetUnitFlyHeight(iceblast) / dist + speed

    call SetUnitFacing(iceblast, angle*bj_RADTODEG)
    call SetUnitFlyHeight(iceblast,GetUnitFlyHeight(iceblast) / dist + 75, 250)
    call SetUnitX(iceblast, X1 + x * Cos(angle))
    call SetUnitY(iceblast, Y1 + y * Sin(angle))
    
    if GetUnitAbilityLevel(caster, 'SPAS') == 3 then
        set damageLow = damageLow + (damageLow * 0.75)
    endif

        if dist <= 75 then
            set b = true
            call KillUnit(iceblast)
            call GroupEnumUnitsInRange(G, X1, Y1, 300, null)
            call GroupRemoveUnit(G,target)
            ForGroup(G, function IceBlast_Slowdown)
        endif

    call GroupClear(G)
    call DestroyGroup(G)
    
    if b == true then
        if GetWidgetLife(target) >.405 then
            set x = GetUnitX(target)
            set y = GetUnitY(target)
        else
            set x = LoadReal(Hash,h,5)
            set y = LoadReal(Hash,h,6)
        endif

        local real face = GetUnitFacing(target)
        local unit dummy = CreateUnit(PlayerCaster,'h006',x,y,face)

        if GetUnitAbilityLevel(caster, 'SPAS') == 3 then
            set damageLow = damageLow + (damageLow * 0.75)
        endif

        call GroupEnumUnitsInRange(G, x, y, 300, null)
        call ForGroup(G, function IceBlast_Slowdown)
        call UnitDamageTarget( caster, target, damageLow, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_COLD, null )
    
        if GetWidgetLife (target) > .405 then
            call UnitRemoveAbility(dummy,'A002')
            call IssueTargetOrder(dummy,"entanglingroots",target)
            call UnitApplyTimedLife(dummy, 'BTFL', 0.1 )
        else
            call RemoveUnit(dummy)
        endif
    
        call GroupClear(G)
        call DestroyGroup(G)
    
        call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl", target, "origin"))
        IceBlast_Slowdown()
        call FlushChildHashtable(Hash,h)
        call PauseTimer(t)
        call DestroyTimer(t)
        
        set dummy = null
    else
        call SaveReal(Hash,h,5, X2)
        call SaveReal(Hash,h,6, Y2)
    endif
    
    set t = null
    set iceblast = null
    set caster = null
    set target = null
    set G = null
endfunction

function IceBlast_Create takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer h = GetHandleId(t)
    local unit iceblast = LoadUnitHandle(Hash,h,1)
    local unit target = LoadUnitHandle(Hash,h,2)
    local unit caster = LoadUnitHandle(Hash,h,3)
    local real X2
    local real Y2
    
    if GetWidgetLife(target) >.405 then
        set X2 = GetUnitX(target)
        set Y2 = GetUnitY(target)
    else
        set X2 = LoadReal(Hash,h,5)
        set Y2 = LoadReal(Hash,h,6)
    endif
    
    local timer k = CreateTimer()
    local integer i = GetHandleId(k)
    call SaveUnitHandle(Hash,i,1,iceblast)
    call SaveUnitHandle(Hash,i,2,target)
    call SaveUnitHandle(Hash,i,3,caster)
    call SaveReal(Hash,i,5,X2)
    call SaveReal(Hash,i,6,Y2)
    call TimerStart(k,.01,true,function IceBlast_Move)

    call PauseTimer(t)
    call DestroyTimer(t)
    set k = null
    set t = null
    set iceblast = null
    set caster = null
    set target = null
endfunction

function IceBlast takes nothing returns nothing
    local unit caster = GetTriggerUnit()
    local unit target = GetSpellTargetUnit()
    local timer t = CreateTimer()
    local integer h = GetHandleId(t)
    local player PlayerCaster = GetOwningPlayer(caster)
    local real X1 = GetUnitX(caster)
    local real X2 = GetUnitX(target)
    local real Y1 = GetUnitY(caster)
    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))
    local unit iceblast = CreateUnit( PlayerCaster, 'h004', X1 - 60 * Cos(angle), Y1 - 60 * Sin(angle), angle*bj_RADTODEG )
    call DestroyEffect(AddSpecialEffectTarget("Abilities\\Weapons\\ColdArrow\\ColdArrowMissile.mdl", caster, "overhead")) //Abilities\\Spells\\Other\\FrostBolt\\FrostBoltMissile.mdl
    call SetUnitPathing( iceblast, false )
    call SetUnitFlyHeight(iceblast, 250, 10000)
    call SaveUnitHandle(Hash,h,1,iceblast)
    call SaveUnitHandle(Hash,h,2,target)
    call SaveUnitHandle(Hash,h,3,caster)
    call SaveReal(Hash,h,5,X2)
    call SaveReal(Hash,h,6,Y2)
    call TimerStart(t,1,false,function IceBlast_Create)
    set t = null
    set iceblast = null
    set caster = null
    set target = null
endfunction
Прорыв тьмы
function KBD_Cond takes nothing returns boolean
    return GetSpellAbilityId()=='AKBD'
endfunction

function KBD_Rect takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer h = GetHandleId(t)
    local unit caster = LoadUnitHandle(Hash,h,1)
    local real xRect = LoadReal(Hash,h,3)
    local real yRect = LoadReal(Hash,h,4)
    local real Frect = 150
    local unit enemy
    local real time = LoadReal(Hash,h,5)
    local effect e = LoadEffectHandle(Hash,h,2)
    local integer data = GetUnitUserData(caster)
    local real damage = DamageKBD[0][data]
    local player PlayerEnemy
    local player PlayerCaster = GetOwningPlayer(caster)
    local group G = CreateGroup()
    if GetUnitAbilityLevel(caster, 'SPAS') == 3 then
        set damage = damage + (damage * 0.75)
    endif

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

    call DestroyEffect(AddSpecialEffect("AquaSpike.mdx", xRect, yRect))
    call DestroyEffect(e)
    call GroupClear(G)
    call DestroyGroup(G)
    call FlushChildHashtable(Hash,h)
    call PauseTimer(t)
    call DestroyTimer (t)
    set t = null
    set caster = null
    set e = null
    set G = null
endfunction

function KBD takes nothing returns nothing
    local timer t = CreateTimer()
    local integer h = GetHandleId(t)
    local unit caster = GetTriggerUnit()
    local real X1 = GetSpellTargetX()
    local real Y1 = GetSpellTargetY()
    local effect e = AddSpecialEffect("RingOfIce.mdx", X1, Y1)
    call SaveUnitHandle(Hash,h,1,caster)
    call SaveEffectHandle(Hash,h,2,e)
    call SaveReal(Hash,h,3,X1)
    call SaveReal(Hash,h,4,Y1)
    call TimerStart(t,1.5,false,function KBD_Rect)
    set e = null
    set t = null
    set caster = null
endfunction
Владыка холодной тьмы
function SPAS_Cond takes nothing returns boolean
	return GetSpellAbilityId() == 'SPAS'
endfunction

function SPAS takes nothing returns nothing
    local unit caster = GetTriggerUnit()
    local integer n = GetUnitUserData(caster)
    local integer i = udg_QuestKelThuzad[n]
    if i == -1 then
        call DisplayTimedTextToPlayer( GetOwningPlayer(caster), 0, 0, 1.5, "Накоплено |c0000FF40Чумы:|r " + "30/30" )
    else
        call DisplayTimedTextToPlayer( GetOwningPlayer(caster), 0, 0, 1.5, "Накоплено |c0000FF40Чумы:|r " + I2S(i) + "/30" )
    endif
    call UnitRemoveAbility(caster, 'BKEL')
    set caster = null
endfunction
Инициализация героя
function KelThuzad_Start takes nothing returns nothing
    local unit u = GetTriggerUnit()
    local integer n = GetUnitUserData( u )
        if GetUnitTypeId(u) == 'UKel' then
            if n <= 0 then
                set NumberOfKelThuzad = NumberOfKelThuzad + 1
                set LifeRegen[0][NumberOfKelThuzad] = 0.03
                set ManaRegen[0][NumberOfKelThuzad] = 0.03
                set Life[0][NumberOfKelThuzad] = GetUnitState(u, UNIT_STATE_MAX_LIFE)
                set Mana[0][NumberOfKelThuzad] = GetUnitState(u, UNIT_STATE_MAX_MANA)
                set DamageDaD[0][NumberOfKelThuzad] = 150
                set DamageDaDRect[0][NumberOfKelThuzad] = 82
                set DamageRoI[0][NumberOfKelThuzad] = 180
                set DamageCoK[0][NumberOfKelThuzad] = 97
                set DamageKIB[0][NumberOfKelThuzad] = 115
                set DamageKIBRect[0][NumberOfKelThuzad] = 275
                set DamageKBD[0][NumberOfKelThuzad] = 360
                set DamageISK[0][NumberOfKelThuzad] = 61
                set Damage[0][NumberOfKelThuzad] = BlzGetUnitBaseDamage(u, 1)
                call SetUnitUserData( u, NumberOfKelThuzad )
                set DamageDaD[0][NumberOfKelThuzad] = DamageDaD[0][NumberOfKelThuzad] + (DamageDaD[0][NumberOfKelThuzad] * 0.025)
                set DamageDaDRect[0][NumberOfKelThuzad] = DamageDaDRect[0][NumberOfKelThuzad] + (DamageDaDRect[0][NumberOfKelThuzad] * 0.025)
                set DamageRoI[0][NumberOfKelThuzad] = DamageRoI[0][NumberOfKelThuzad] + (DamageRoI[0][NumberOfKelThuzad] * 0.025)
                set DamageCoK[0][NumberOfKelThuzad] = DamageCoK[0][NumberOfKelThuzad] + (DamageCoK[0][NumberOfKelThuzad] * 0.025)
                set DamageKIB[0][NumberOfKelThuzad] = DamageKIB[0][NumberOfKelThuzad] + (DamageKIB[0][NumberOfKelThuzad] * 0.025)
                set DamageKIBRect[0][NumberOfKelThuzad] = DamageKIB[0][NumberOfKelThuzad] + (DamageKIB[0][NumberOfKelThuzad] * 0.025)
                set DamageKBD[0][NumberOfKelThuzad] = DamageKBD[0][NumberOfKelThuzad] + (DamageKBD[0][NumberOfKelThuzad] * 0.025)
                set DamageISK[0][NumberOfKelThuzad] = DamageISK[0][NumberOfKelThuzad] + (DamageISK[0][NumberOfKelThuzad] * 0.025)
                set QuestKelThuzad[NumberOfKelThuzad] = 0
                call BlzUnitDisableAbility( u, 'AISK', true, false )
                set KelThuzad[NumberOfKelThuzad] = 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( KelThuzad[n], UNIT_STATE_LIFE, GetUnitState(KelThuzad[n], UNIT_STATE_LIFE) + LifeRegen[0][n])
        call SetUnitState( KelThuzad[n], UNIT_STATE_MANA, GetUnitState(KelThuzad[n], UNIT_STATE_MANA) + ManaRegen[0][n])
    exitwhen n == NumberOfKelThuzad or NumberOfKelThuzad == 0
    endloop
endfunction
Повышение уровня
function Trig_LvlUp_Conditions takes nothing returns boolean
    return GetUnitTypeId(GetTriggerUnit()) == 'UKel'
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) + 0.5
    set Mana[0][data] = Mana[0][data] + 10
    set Damage[0][data] = Damage[0][data] + (Damage[0][data] * 0.04)
    set DamageDaD[0][data] = DamageDaD[0][data] + (DamageDaD[0][data] * 0.025)
    set DamageDaDRect[0][data] = DamageDaDRect[0][data] + (DamageDaDRect[0][data] * 0.025)
    set DamageRoI[0][data] = DamageRoI[0][data] + (DamageRoI[0][data] * 0.025)
    set DamageCoK[0][data] = DamageCoK[0][data] + (DamageCoK[0][data] * 0.025)
    set DamageKIB[0][data] = DamageKIB[0][data] + (DamageKIB[0][data] * 0.025)
    set DamageKIBRect[0][data] = DamageKIB[0][data] + (DamageKIB[0][data] * 0.025)
    set DamageKBD[0][data] = DamageKBD[0][data] + (DamageKBD[0][data] * 0.025)
    set DamageISK[0][data] = DamageISK[0][data] + (DamageISK[0][data] * 0.025)
    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]))
    call BlzSetUnitMaxMana( u, R2I(Mana[0][data]))
    call BlzSetUnitBaseDamage( u, R2I(Damage[0][data]), 1 )
    set u = null
endfunction
Визуальное исправление анимаций при мгновенном применении способностей
function Trig_AnimationSpell_Conditions takes nothing returns boolean
	return GetUnitTypeId(GetTriggerUnit()) == 'UKel'
endfunction

function Trig_AnimationSpell_Actions takes nothing returns nothing
    local unit caster = GetTriggerUnit()
    local integer abil = GetSpellAbilityId()
    if abil != 'ADaD' and abil != 'SPAS' then
        call SetUnitAnimation(caster,"spell")
        QueueUnitAnimation(caster,"stand")
    endif
    set caster = null
endfunction
Отдельная благодарность nvc123
Примечание: видео версии 1.1.4.


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

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
16
Видео неинформативно, но выглядит эпично.
8
Naadir, что, по твоему мнению, будет информативным для подобных наработок? Мне интересно твое мнение.
15
Слишком много вражеских юнитов, среди атак которых не разобрать, где способности. Демонстрацию нужно разделить на несколько этапов, где способности тестируются на пассивных противниках. Уже после можно озадачиться рубиловом.
8
GetLocalPlayer, впрочем, соглашусь. В скором времени обновлю как саму наработку (с замедлением косяк, ибо упор был в основном на "Цепи"), так и видео.
12
Наработку героя нужно перенести в другой раздел на сайте, я чисто случайно увидел.Сначала хотел похватить то, что выполнено без всяких структур и либ.Но потом увидел баг с цепями и молнией, которая появляется в центре карты.На скилле Q мешается тень от дамика.На скилле R- задержка и опускание высоты дамика выглядят убого, также медленно смещение рывками.
Ну и на последок раз уж делаете героев из {оста , то не помешали бы и их модели загрузить.
8
Daro, с удовольствием бы вытянул модель с анимациями, если бы умел. А так приходится делать на том, что имеем. Вскоре обновлю с исправлением вышеупомянутых замечаний, а также добавлю кое-что новое. :)
12
У меня есть вот такая модель.Эффекты еще проработай получше.
На счет кода я еще не вчитывлся, скажу что лучше оставить как раз именно на таком джассе без структур.По коду еще можно чуть сократить.Мне понравилось , что квест сделан через CV юнита, за это плюс. IceBlast переделай на 1 таймер и тригг , без лишних разделений на функции
Загруженные файлы
8
Daro, какие именно эффекты, на твое мнение, стоит улучшить?
Таймер один, не знаю, где ты нашел еще...
Daro, через CV я сделал, потому что с помощью этого можно инициализировать и все остальное, в CV лишь находится номер юнита, а дальше свободная площадка для скриптования...
11
Atesla, а как ты создал время действия эффекта притягивания над личем (ну полоска)?
22
ArhiMEN:
Atesla, а как ты создал время действия эффекта притягивания над личем (ну полоска)?
а ничего что автор ресурса хгм не посещает уже год?))
11
Maxlaid, да я не видел, вспомнил, что видел здесь каст тайм, вот и спросил
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.