28

» WarCraft 3 / Заклинания на заказ

Desgul, бле, код в кавычки забыл обернуть и отредактировать уже нельзя, офигенно 👍
28

» WarCraft 3 / Заклинания на заказ

Выполнение заказа

Заклинание готово!

Ярость Синдрагосы

инструкция по импорту
скопировать папку Initialization и вставить в свою карту
перекопировать редактор объектов и вставить в свою карту
в триггере Spell на строках:
272 - указать равкод даммика который кастует замедление
261 - указать абилку призыва дракона
235-236 - смещение проявления дракона за спину кастера
238 - равкод дракона
244 - стартовая высота дракона (400)
245 - высота дракона во время полёта (300 - какую высоту установить, 100 - с какой скоростью установить эту высоту, т.е. с учётом стартовой высоты, дракон достигнет этой высоты за одну секунду)
246 - раскрас дракона (последний аргумент должен быть на 0)
251 - максимальное расстояние всего полёта с учётом проявления и исчезновения
140 - скорость полёта дракона
154 - при какой оставшейся дистанции начать выпускать ледяные волны
156 - индекс анимки полёта дракона
160 - при какой оставшейся дистанции начать исчезновение дракона
161 - формула исчезновения дракона ( 255.00 / ( указать параметр на 160 строке / speed ) )
162 - раскрас дракона, последний параметр не нужно трогать
164 - формула взлёта дракона ( скорость взлёта * ( 1.00 - d / указать параметр на 160 строке ) )
167 - другой индекс анимки полёта дракона (взмах крыльями)
170 - указать параметр на 160 строке + параметр на 173 строке
173 - периодичность спавна ледяных волн в зависимости от пройденной дистанции (т.е. каждые 35 единиц)
177-178 - смещение начала волны поближе к морде дракона
180 - равкод ледяной волны
186 - стартовая высота волны (на 75 единиц ниже высоты дракона)
192 - указать параметр на 170 строке
204 - дистанция до которой дракон должен проявиться
205 - формула проявления дракона ( 255.00 / ( ( максимальная дистанция - параметр на 204 строке ) / speed ) )
206 - то же самое, что и 162
32-33 - скорость полёта волны
37 - скорость полёта волны по Z
43 - радиус урона (300 + макс коллизия)
53 - радиус урона
57 - приказ замедления
58 - урон
64-110 - визуальные кPаКаЗяБрЫ

Код

Spell
function GetCorX takes real x returns real
if x > udg_MapRectXY[0] then
return udg_MapRectXY[0]
elseif x < udg_MapRectXY[1] then
return udg_MapRectXY[1]
endif

return x
endfunction
function GetCorY takes real y returns real
if y > udg_MapRectXY[2] then
return udg_MapRectXY[2]
elseif y < udg_MapRectXY[3] then
return udg_MapRectXY[3]
endif

return y
endfunction
function MoveEffect takes nothing returns nothing
local timer t = GetExpiredTimer( )
local integer i = GetHandleId( t )
local unit u
local unit caster
local unit dummy = LoadUnitHandle( udg_H, i, 0 )
local real x = GetUnitX( dummy )
local real y = GetUnitY( dummy )
local real a = GetUnitFacing( dummy ) * bj_DEGTORAD
local group g

set x = GetCorX( x + 10.00 * Cos( a ) )
set y = GetCorY( y + 10.00 * Sin( a ) )

call SetUnitX( dummy, x )
call SetUnitY( dummy, y )
call SetUnitFlyHeight( dummy, GetUnitFlyHeight( dummy ) - 5.00, 0.00 )

if GetUnitFlyHeight( dummy ) <= 0.11 then
call SetUnitAnimation( dummy, "death" )
call UnitApplyTimedLife( dummy, 'BTLF', 1.00 )

call GroupEnumUnitsInRange( udg_TempGroup, x, y, 500.00, null )
set caster = LoadUnitHandle( udg_H, i, 1 )
set g = LoadGroupHandle( udg_H, i, 2 )
set bj_groupEnumOwningPlayer = GetOwningPlayer( caster )

loop
set u = FirstOfGroup( udg_TempGroup )
exitwhen u == null
call GroupRemoveUnit( udg_TempGroup, u )

if IsUnitInRangeXY( u, x, y, 300.00 ) then
if not IsUnitInGroup( u, g ) then
if IsUnitEnemy( u, bj_groupEnumOwningPlayer ) and not IsUnitType( u, UNIT_TYPE_DEAD ) then
call GroupAddUnit( g, u )
call IssueTargetOrder( udg_TempUnit, "frostnova", u )
call UnitDamageTarget( caster, u, 100.00, false, false, null, null, null )
endif
endif
endif
endloop

set dummy = CreateUnit( Player( PLAYER_NEUTRAL_PASSIVE ), 'u003', x, y, GetRandomReal( 0.00, 360.00 ) )
call SetUnitAnimation( dummy, "death" )
call UnitApplyTimedLife( dummy, 'BTLF', 2.00 )
call UnitAddAbility( dummy, 'Arav' )
call SetUnitX( dummy, x + GetRandomReal( -200.00, 200.00 ) )
call SetUnitY( dummy, y + GetRandomReal( -200.00, 200.00 ) )
call SetUnitFlyHeight( dummy, GetRandomReal( 32.00, 150.00 ), 0.00 )

set dummy = CreateUnit( Player( PLAYER_NEUTRAL_PASSIVE ), 'u004', x, y, GetRandomReal( 0.00, 360.00 ) )
call SetUnitAnimation( dummy, "death" )
call UnitApplyTimedLife( dummy, 'BTLF', 2.00 )
call UnitAddAbility( dummy, 'Arav' )
call SetUnitX( dummy, x + GetRandomReal( -200.00, 200.00 ) )
call SetUnitY( dummy, y + GetRandomReal( -200.00, 200.00 ) )
call SetUnitFlyHeight( dummy, GetRandomReal( 32.00, 150.00 ), 0.00 )

set dummy = CreateUnit( Player( PLAYER_NEUTRAL_PASSIVE ), 'u005', x, y, GetRandomReal( 0.00, 360.00 ) )
call SetUnitAnimation( dummy, "death" )
call UnitApplyTimedLife( dummy, 'BTLF', 2.00 )
call UnitAddAbility( dummy, 'Arav' )
call SetUnitX( dummy, x + GetRandomReal( -200.00, 200.00 ) )
call SetUnitY( dummy, y + GetRandomReal( -200.00, 200.00 ) )
call SetUnitFlyHeight( dummy, GetRandomReal( 32.00, 150.00 ), 0.00 )

set dummy = CreateUnit( Player( PLAYER_NEUTRAL_PASSIVE ), 'u006', x, y, GetRandomReal( 0.00, 360.00 ) )
call SetUnitAnimation( dummy, "death" )
call UnitApplyTimedLife( dummy, 'BTLF', 2.00 )
call UnitAddAbility( dummy, 'Arav' )
call SetUnitX( dummy, x + GetRandomReal( -200.00, 200.00 ) )
call SetUnitY( dummy, y + GetRandomReal( -200.00, 200.00 ) )
call SetUnitFlyHeight( dummy, GetRandomReal( 32.00, 150.00 ), 0.00 )

set dummy = CreateUnit( Player( PLAYER_NEUTRAL_PASSIVE ), 'u007', x, y, GetRandomReal( 0.00, 360.00 ) )
call SetUnitAnimation( dummy, "death" )
call UnitApplyTimedLife( dummy, 'BTLF', 2.00 )
call UnitAddAbility( dummy, 'Arav' )
call SetUnitX( dummy, x + GetRandomReal( -200.00, 200.00 ) )
call SetUnitY( dummy, y + GetRandomReal( -200.00, 200.00 ) )
call SetUnitFlyHeight( dummy, GetRandomReal( 32.00, 150.00 ), 0.00 )

set dummy = CreateUnit( Player( PLAYER_NEUTRAL_PASSIVE ), 'u008', x, y, GetRandomReal( 0.00, 360.00 ) )
call SetUnitAnimation( dummy, "death" )
call UnitApplyTimedLife( dummy, 'BTLF', 2.00 )
call UnitAddAbility( dummy, 'Arav' )
call SetUnitX( dummy, x + GetRandomReal( -200.00, 200.00 ) )
call SetUnitY( dummy, y + GetRandomReal( -200.00, 200.00 ) )
call SetUnitFlyHeight( dummy, GetRandomReal( 32.00, 150.00 ), 0.00 )

if LoadInteger( udg_H, i, 3 ) == 1 then
call DestroyGroup( g )
endif

call PauseTimer( t )
call FlushChildHashtable( udg_H, i )
call DestroyTimer( t )

set g = null
set caster = null
endif

set t = null
set dummy = null
endfunction
function Move takes nothing returns nothing
local timer t = GetExpiredTimer( )
local timer n
local integer i = GetHandleId( t )
local integer j
local unit caster = LoadUnitHandle( udg_H, i, 0 )
local unit dummy = LoadUnitHandle( udg_H, i, 1 )
local real x = GetUnitX( dummy )
local real y = GetUnitY( dummy )
local real a = GetUnitFacing( dummy ) * bj_DEGTORAD
local real d = LoadReal( udg_H, i, 3 )
local real r
local real speed = 5.00

if speed > d then
set speed = d
endif

set x = GetCorX( x + speed * Cos( a ) )
set y = GetCorY( y + speed * Sin( a ) )

call SetUnitX( dummy, x )
call SetUnitY( dummy, y )

set d = d - speed

if d <= 2300 then
if LoadInteger( udg_H, i, 4 ) == 0 then
call SetUnitAnimationByIndex( dummy, 4 )
call SaveInteger( udg_H, i, 4, 1 )
endif

if d <= 400.00 then
set r = LoadReal( udg_H, i, 5 ) - 255.00 / ( 400.00 / speed )
call SetUnitVertexColor( dummy, 175, 175, 175, R2I( r ) )
call SaveReal( udg_H, i, 5, r )
call SetUnitFlyHeight( dummy, GetUnitFlyHeight( dummy ) + 5.00 * ( 1.00 - d / 400.00 ), 0.00 )

if LoadInteger( udg_H, i, 4 ) == 1 then
call SetUnitAnimationByIndex( dummy, 3 )
call SaveInteger( udg_H, i, 4, 2 )
endif
elseif d > 435.00 then
set r = LoadReal( udg_H, i, 6 ) + speed

if r >= 35.00 then
set r = 0.00
set n = CreateTimer( )
set j = GetHandleId( n )
set x = GetCorX( x + 275.00 * Cos( a ) )
set y = GetCorY( y + 275.00 * Sin( a ) )

set bj_lastCreatedUnit = CreateUnit( GetOwningPlayer( caster ), 'u002', x, y, a * bj_RADTODEG )
call SetUnitAnimation( bj_lastCreatedUnit, "birth" )
call QueueUnitAnimation( bj_lastCreatedUnit, "stand" )
call UnitAddAbility( bj_lastCreatedUnit, 'Arav' )
call SetUnitX( bj_lastCreatedUnit, x )
call SetUnitY( bj_lastCreatedUnit, y )
call SetUnitFlyHeight( bj_lastCreatedUnit, GetUnitFlyHeight( dummy ) - 75.00, 0.00 )

call SaveUnitHandle( udg_H, j, 0, bj_lastCreatedUnit )
call SaveUnitHandle( udg_H, j, 1, caster )
call SaveGroupHandle( udg_H, j, 2, LoadGroupHandle( udg_H, i, 2 ) )

if d - speed <= 435.00 then
call SaveInteger( udg_H, j, 3, 1 )
endif

call TimerStart( n, 0.01, true, function MoveEffect )
set n = null
endif

call SaveReal( udg_H, i, 6, r )
endif
endif

if d > 2000.00 then
set r = LoadReal( udg_H, i, 5 ) + 255.00 / ( ( 2500.00 - 2000.00 ) / speed )
call SetUnitVertexColor( dummy, 175, 175, 175, R2I( r ) )
call SaveReal( udg_H, i, 5, r )
endif

if d <= 0.00 then
call PauseTimer( t )
call FlushChildHashtable( udg_H, i )
call DestroyTimer( t )

call SetUnitVertexColor( dummy, 0, 0, 0, 0 )
call KillUnit( dummy )
else
call SaveReal( udg_H, i, 3, d )
endif

set t = null
set dummy = null
set caster = null
endfunction
function Trig_Spell_Actions takes nothing returns nothing
local timer t = CreateTimer( )
local integer i = GetHandleId( t )
local unit caster = GetTriggerUnit( )
local real x = GetUnitX( caster )
local real y = GetUnitY( caster )
local real a = Atan2( GetSpellTargetY( ) - y, GetSpellTargetX( ) - x )

set x = GetCorX( x - 800.00 * Cos( a ) )
set y = GetCorY( y - 800.00 * Sin( a ) )

set bj_lastCreatedUnit = CreateUnit( GetOwningPlayer( caster ), 'u001', x, y, a * bj_RADTODEG )
call SetUnitAnimation( bj_lastCreatedUnit, "birth" )
call QueueUnitAnimation( bj_lastCreatedUnit, "stand" )
call UnitAddAbility( bj_lastCreatedUnit, 'Arav' )
call SetUnitX( bj_lastCreatedUnit, x )
call SetUnitY( bj_lastCreatedUnit, y )
call SetUnitFlyHeight( bj_lastCreatedUnit, 400.00, 0.00 )
call SetUnitFlyHeight( bj_lastCreatedUnit, 300.00, 100.00 )
call SetUnitVertexColor( bj_lastCreatedUnit, 175, 175, 175, 0 )

call SaveUnitHandle( udg_H, i, 0, caster )
call SaveUnitHandle( udg_H, i, 1, bj_lastCreatedUnit )
call SaveGroupHandle( udg_H, i, 2, CreateGroup( ) )
call SaveReal( udg_H, i, 3, 2500.00 )

call TimerStart( t, 0.01, true, function Move )

set t = null
set caster = null
endfunction
===========================================================================
function Trig_Spell_Conditions takes nothing returns boolean
return GetSpellAbilityId() == 'A000'
endfunction
function InitTrig_Spell takes nothing returns nothing
local rect r = GetWorldBounds( )

set gg_trg_Spell = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Spell, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_Spell, Condition( function Trig_Spell_Conditions ) )
call TriggerAddAction( gg_trg_Spell, function Trig_Spell_Actions )

set udg_TempUnit = CreateUnit( Player( PLAYER_NEUTRAL_PASSIVE ), 'u009', 0.00, 0.00, 0.00 )

set udg_MapRectXY[0] = GetRectMaxX( r )
set udg_MapRectXY[1] = GetRectMinX( r )
set udg_MapRectXY[2] = GetRectMaxY( r )
set udg_MapRectXY[3] = GetRectMinY( r )

call RemoveRect( r )

set r = null
endfunction
""
Загруженные файлы
28

» WarCraft 3 / Заклинания на заказ

Вышла новая версия! Прокрутить к ресурсу
FIRERANGER, убрал GroupForEachUnit и воспользовался обычным FirstOfGroup, заменил SetUnitStunned на BlzPauseUnitEx
DamageEvent
library DamageEventLib
globals
    private constant group TempGroup = CreateGroup( )
endglobals

private struct SpellS
    timer t
    unit caster
    player p
    group g
    real angle
    real speed
endstruct

private function Damage takes nothing returns nothing
    local SpellS A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
    local real d = 0.00 
    local real a = GetUnitFacing( A.caster ) * bj_DEGTORAD
    local real x = GetUnitX( A.caster )
    local real y = GetUnitY( A.caster )
    local real x1 = x + 125.00 * Cos( a + bj_PI * 0.30 )
    local real y1 = y + 125.00 * Sin( a + bj_PI * 0.30 )
    local real x2 = x + 125.00 * Cos( a - bj_PI * 0.30 )
    local real y2 = y + 125.00 * Sin( a - bj_PI * 0.30 )
    local unit u
    
    set A.angle = A.angle + A.speed
    
    loop
        call GroupEnumUnitsInRange( TempGroup, x, y, 400.00 + UNIT_MAX_COLLISION, null )
        
        loop
            set u = FirstOfGroup( TempGroup )
            exitwhen u == null
            call GroupRemoveUnit( TempGroup, u )
            
            if not IsUnitInGroup( u, A.g ) then
                if IsUnitInRangeXY( u, x1, y1, 32.00 ) or IsUnitInRangeXY( u, x2, y2, 32.00 )then
                    if UnitAlive( u ) and IsUnitEnemy( u, A.p ) and not IsUnitType( u, UNIT_TYPE_FLYING ) then
                        call GroupAddUnit( A.g, u )
                        call UnitDamageTarget( A.caster, u, 150.00, false, false, null, null, null )
                    endif
                endif
            endif
        endloop
        
        set d = d + 32.00
        exitwhen d >= 200.00
        set x1 = x1 + 32.00 * Cos( a + A.angle )
        set y1 = y1 + 32.00 * Sin( a + A.angle )
        set x2 = x2 + 32.00 * Cos( a - A.angle )
        set y2 = y2 + 32.00 * Sin( a - A.angle )
        
        call DestroyEffect( AddSpecialEffect( "Abilities\\Weapons\\IllidanMissile\\IllidanMissile.mdl", x1, y1 ) )
        call DestroyEffect( AddSpecialEffect( "Abilities\\Weapons\\IllidanMissile\\IllidanMissile.mdl", x2, y2 ) )
    endloop
    
    if A.angle * bj_RADTODEG >= 120.00 or not UnitAlive( A.caster ) then
        call PauseTimer( A.t )
        call DestroyTimer( A.t )
        call FlushChildHashtable( H, GetHandleId( A.t ) )
        
        call BlzPauseUnitEx( A.caster, false )
        call DestroyGroup( A.g )
        
        set A.t = null
        set A.g = null
        set A.caster = null
        call A.destroy( )
    else
        call TimerStart( A.t, 0.05, false, function Damage )
    endif
endfunction

private function DamageEvent_Actions takes nothing returns nothing
    local SpellS A
    
    if GetUnitAbilityLevel( GetEventDamageSource( ), 'A000' ) > 0 and BlzGetEventIsAttack( ) and GetRandomInt( 1, 100 ) <= 100 then
        set A = SpellS.create( )
        
        set A.t = CreateTimer( )
        set A.caster = GetEventDamageSource( )
        set A.p = GetOwningPlayer( A.caster )
        set A.g = CreateGroup( )
        set A.angle = 60.00 * bj_DEGTORAD
        set A.speed = 60.00 / 0.75 * 0.05 * bj_DEGTORAD
        
        call BlzPauseUnitEx( A.caster, true )
        call SetUnitAnimation( A.caster, "spell slam" )
        call QueueUnitAnimation( A.caster, "stand" )
        
        call SaveInteger( H, GetHandleId( A.t ), 0, A )
        call TimerStart( A.t, 0.25, false, function Damage )
    endif
endfunction

//===========================================================================
function InitTrig_DamageEvent takes nothing returns nothing
    set gg_trg_DamageEvent = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_DamageEvent, EVENT_PLAYER_UNIT_DAMAGED )
    call TriggerAddAction( gg_trg_DamageEvent, function DamageEvent_Actions )
endfunction
endlibrary


стоит 100% шанс, как изменить я уже описывал выше
Загруженные файлы
28

» WarCraft 3 / Какая проверка на то что юнит жив лучше? - [Jass]

nazarpunk, нормальные люди не используют это, нормальные люди не используют то, не используют сё, ничем не пользуются, в варкрафте не сидят, норм люди на анриле лямы зарабатывают
28

» WarCraft 3 / Какая проверка на то что юнит жив лучше? - [Jass]

nazarpunk, что значит ручками вставить до первой пользовательской функции? типа в war3map.j вставить, а не в редакторе?
28

» WarCraft 3 / Заклинания на заказ

FIRERANGER, добавь приставки Blz к каждой из функций, что показывает тебе ошибка. То есть не SetUnitStunned а BlzSetUnitStunned и всё заработает (если эти функции там есть конечно, иначе действительно придется переписывать некоторые моменты и добавить систему стана)
28

» WarCraft 3 / Какая проверка на то что юнит жив лучше? - [Jass]

LastUchiha, UnitAlive юзай, но для него вджасс нужен, чтобы объявить нативку, если ты на 1.26 конечно, потому что вроде на версиях выше можно без объявления юзать эту функцию
28

» WarCraft 3 / Какая проверка на то что юнит жив лучше? - [Jass]

LastUchiha, хз быстрее ли и почему тебе не пофиг, вряд ли у тебя будет 10к проверок в цикле, чтобы ты эту разницу ощутил. По логике вещей UnitAlive будет быстрее, потому что сразу душевую возвращает, когда WidgetLife'y нужно уже сравнить значение с определенным числом
28

» WarCraft 3 / Какая проверка на то что юнит жив лучше? - [Jass]

UnitAlive. Если ты мёртвому юниту добавишь хп, то WidgetLife посчитает, что юнит жив

Вообще юзать WidgetLife это уже моветон, когда есть проверка без vjass'a, используя IsUnitType( u, UNIT_TYPE_DEAD ) or GetUnitTypeId( u ) == 0
28

» WarCraft 3 / Заклинания на заказ

Выполнение заказа

Заклинание готово!

Подобрать эффекты, модельки, немного подогнать под это дело код и в принципе будет сносно. Но у блинка так-то сделана иначе сама система кастов, типа нет таргетных абилок (ими нужно попадать) и в зависимости от того есть ли в радиусе поражения юнит, какая разница высот, какая дистанция между ними - происходят соответствующие действия, вроде прыжка/телепорта вверх, сокращение дистанции телепортами и т.д. и т.п.
инструкция по импорту
убрать триггер Untitled Trigger 001 и скопировать папку Initialization в свою карту
в триггере Spell на 232 строке указать равкод абилки
на 177 строке указать урон от первого удара
на 87 строке урон от второго удара
на 65 урон от серии ударов
на 142 урон при окончании серии ударов
всё остальное требует минимальных знаний джасса

Код

AllGlobals
library AllGlobalsLib
globals
    constant hashtable H = InitHashtable( )
endglobals

struct vector
    real x
    real y
    real z
    
    method length takes nothing returns real
        return SquareRoot( x * x + y * y + z * z )
    endmethod
    
    method normalize takes nothing returns nothing
        local real l = length( )
        
        if l == 0.00 then
            set l = 1.00
        endif
        
        set x = x / l
        set y = y / l
        set z = z / l
    endmethod
    
    static method create takes real x, real y, real z returns thistype
        local thistype this = thistype.allocate( )
        
        set this.x = x
        set this.y = y
        set this.z = z
        
        return this
    endmethod
endstruct

function ParabolaZ takes real h, real d, real x returns real
    return (4 * h / d) * (d - x) * (x / d)
endfunction

private function AlphaTeleportPeriodic takes nothing returns nothing
    local timer t = GetExpiredTimer( )
    local integer i = GetHandleId( t )
    local real r = LoadReal( H, i, 1 ) + 0.01
    local real k = LoadReal( H, i, 2 )
    
    call SetUnitVertexColor( LoadUnitHandle( H, i, 0 ), 255, 255, 255, R2I( 255.00 - ParabolaZ( 255.00, k, r ) ) )
    
    if r >= k then
        call PauseTimer( t )
        call DestroyTimer( t )
        call FlushChildHashtable( H, i )
    else
        call SaveReal( H, i, 1, r )
    endif
    
    set t = null
endfunction

function AlphaTeleport takes unit u, real time returns nothing
    local timer t = CreateTimer( )
    local integer i = GetHandleId( t )
    
    call SaveUnitHandle( H, i, 0, u )
    call SaveReal( H, i, 1, 0.00 )
    call SaveReal( H, i, 2, time )
    call TimerStart( t, 0.01, true, function AlphaTeleportPeriodic )
    
    set t = null
endfunction

private function Falling takes nothing returns nothing
    local timer t = GetExpiredTimer( )
    local integer i = GetHandleId( t )
    local unit u = LoadUnitHandle( H, i, 0 )
    local real s = LoadReal( H, i, 1 ) - 0.25
    local real f = GetUnitFlyHeight( u ) + s
    
    call SetUnitFlyHeight( u, f, 0.00 )
    
    if f <= 0.00 then
        call PauseTimer( t )
        call FlushChildHashtable( H, i )
        call DestroyTimer( t )
        
        call RemoveSavedHandle( H, GetHandleId( u ), UnitFallingKey )
    else
        call SaveReal( H, i, 1, s )
    endif
    
    set t = null
    set u = null
endfunction

function UnitStartFalling takes unit u, real speed returns nothing
    local timer t = LoadTimerHandle( H, GetHandleId( u ), UnitFallingKey )
    
    if t == null then
        set t = CreateTimer( )
        
        call SaveTimerHandle( H, GetHandleId( u ), UnitFallingKey, t )
        call SaveUnitHandle( H, GetHandleId( t ), 0, u )
        
        call TimerStart( t, 0.01, true, function Falling )
    endif
    
    call SaveReal( H, GetHandleId( t ), 1, speed )
    
    set t = null
endfunction
endlibrary

//===========================================================================
//function InitTrig_AllGlobals takes nothing returns nothing
    //set gg_trg_AllGlobals = CreateTrigger(  )
//endfunction

Spell
library SpellLib
globals
    constant key UnitFallingKey
endglobals

private struct SpellS
    timer t
    unit caster
    unit target
    real time
    real speed
    integer action
    boolean localPlayer
    vector v
endstruct

private function Move takes nothing returns nothing
    local SpellS A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
    local real x
    local real y
    
    if A.action < 4 then
        set x = GetUnitX( A.target ) + A.speed * A.v.x
        set y = GetUnitY( A.target ) + A.speed * A.v.y
    
        call SetUnitX( A.target, x )
        call SetUnitY( A.target, y )
        
        set A.time = A.time - 0.01
    else
        set x = GetUnitX( A.caster ) - A.speed * A.v.x
        set y = GetUnitY( A.caster ) - A.speed * A.v.y
    
        call SetUnitX( A.caster, x )
        call SetUnitY( A.caster, y )
    endif
    
    if A.localPlayer then
        call SetCameraField( CAMERA_FIELD_ZOFFSET, GetUnitFlyHeight( A.caster ), 0.25 )
    endif
    
    if A.action == 0 then
        if A.time <= 0.10 then
            call SetUnitFlyHeight( A.caster, GetUnitFlyHeight( A.caster ) + 60.00, 0.00 )
        endif
    elseif A.action == 1 or A.action == 2 then
        if A.action == 2 then
            if A.time == 0.20 then
                call SetUnitTimeScale( A.caster, 2.00 )
                call SetUnitAnimation( A.caster, "attack slam" )
                call QueueUnitAnimation( A.caster, "stand" )
            elseif A.time == 0.10 then
                call SetUnitTimeScale( A.caster, 1.00 )
            endif
        endif
        
        if A.time == 0.10 then
            call AlphaTeleport( A.caster, 0.20 )
        endif
    elseif A.action == 3 then
        call SetUnitFlyHeight( A.target, GetUnitFlyHeight( A.target ) - 0.25, 0.00 )
        call SetUnitFlyHeight( A.caster, GetUnitFlyHeight( A.target ) + 50.00, 0.00 )
        call UnitStartFalling( A.target, 0.00 )
        
        call UnitDamageTarget( A.caster, A.target, 1.00, false, false, null, null, null )
        
        if GetRandomInt( 0, 1 ) == 0 then
            call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Weapons\\VengeanceMissile\\VengeanceMissile.mdl", A.target, "overhead" ) )
        else
            call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Weapons\\VengeanceMissile\\VengeanceMissile.mdl", A.caster, "weapon" ) )
        endif
    endif
    
    if A.time <= 0.00 or ( A.action == 4 and GetUnitFlyHeight( A.caster ) <= 0.11 ) then
        if A.action == 0 then
            call SetUnitTimeScale( A.caster, 2.00 )
            
            call SetUnitAnimationByIndex( A.caster, 5 )
            call QueueUnitAnimation( A.caster, "stand" )
            
            set A.time = 0.25
            set A.action = 1
        elseif A.action == 1 then
            set A.action = 2
            set A.speed = 12.00
            
            call UnitDamageTarget( A.caster, A.target, 50.00, false, false, null, null, null )
            
            call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile.mdl", A.target, "chest" ) )
            
            set bj_lastCreatedUnit = CreateUnit( GetOwningPlayer( A.caster ), 'u000', GetUnitX( A.caster ), GetUnitY( A.caster ), GetUnitFacing( A.caster ) )
            call UnitAddAbility( bj_lastCreatedUnit, 'Arav' )
            call SetUnitX( bj_lastCreatedUnit, GetUnitX( A.caster ) )
            call SetUnitY( bj_lastCreatedUnit, GetUnitY( A.caster ) )
            call SetUnitFlyHeight( bj_lastCreatedUnit, GetUnitFlyHeight( A.caster ), 0.00 )
            call UnitApplyTimedLife( bj_lastCreatedUnit, 'BTLF', 2.00 )
            
            call SetUnitX( A.caster, x - 128.00 * A.v.x )
            call SetUnitY( A.caster, y - 128.00 * A.v.y )
            call SetUnitFlyHeight( A.caster, GetUnitFlyHeight( A.target ), 0.00 )
            
            set bj_lastCreatedUnit = CreateUnit( GetOwningPlayer( A.caster ), 'u000', GetUnitX( A.caster ), GetUnitY( A.caster ), GetUnitFacing( A.caster ) )
            call UnitAddAbility( bj_lastCreatedUnit, 'Arav' )
            call SetUnitX( bj_lastCreatedUnit, GetUnitX( A.caster ) )
            call SetUnitY( bj_lastCreatedUnit, GetUnitY( A.caster ) )
            call SetUnitFlyHeight( bj_lastCreatedUnit, GetUnitFlyHeight( A.caster ), 0.00 )
            call UnitApplyTimedLife( bj_lastCreatedUnit, 'BTLF', 2.00 )
            
            call UnitStartFalling( A.caster, 0.00 )
            set A.time = 0.30
        elseif A.action == 2 then
            set bj_lastCreatedUnit = CreateUnit( GetOwningPlayer( A.caster ), 'u000', GetUnitX( A.caster ), GetUnitY( A.caster ), GetUnitFacing( A.caster ) )
            call UnitAddAbility( bj_lastCreatedUnit, 'Arav' )
            call SetUnitX( bj_lastCreatedUnit, GetUnitX( A.caster ) )
            call SetUnitY( bj_lastCreatedUnit, GetUnitY( A.caster ) )
            call SetUnitFlyHeight( bj_lastCreatedUnit, GetUnitFlyHeight( A.caster ), 0.00 )
            call UnitApplyTimedLife( bj_lastCreatedUnit, 'BTLF', 2.00 )
            
            call SetUnitX( A.caster, x - 96.00 * A.v.x )
            call SetUnitY( A.caster, y - 96.00 * A.v.y )
            call SetUnitFlyHeight( A.caster, GetUnitFlyHeight( A.target ), 0.00 )
            
            set bj_lastCreatedUnit = CreateUnit( GetOwningPlayer( A.caster ), 'u000', GetUnitX( A.caster ), GetUnitY( A.caster ), GetUnitFacing( A.caster ) )
            call UnitAddAbility( bj_lastCreatedUnit, 'Arav' )
            call SetUnitX( bj_lastCreatedUnit, GetUnitX( A.caster ) )
            call SetUnitY( bj_lastCreatedUnit, GetUnitY( A.caster ) )
            call SetUnitFlyHeight( bj_lastCreatedUnit, GetUnitFlyHeight( A.caster ), 0.00 )
            call UnitApplyTimedLife( bj_lastCreatedUnit, 'BTLF', 2.00 )
            
            set A.speed = 0.00
            
            call UnitStartFalling( A.caster, 0.00 )
            call UnitStartFalling( A.target, 0.00 )
            
            set A.time = 0.50
            set A.action = 3
        elseif A.action == 3 then
            set A.action = 4
            set A.time = 0.01
            set A.speed = 2.50
            
            call UnitDamageTarget( A.caster, A.target, 10.00, false, false, null, null, null )
            
            call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile.mdl", A.target, "overhead" ) )
            
            call UnitStartFalling( A.caster, 10.00 )
            call UnitStartFalling( A.target, -20.00 )
        elseif A.action == 4 then
            call PauseTimer( A.t )
            call FlushChildHashtable( H, GetHandleId( A.t ) )
            call DestroyTimer( A.t )
            
            call PauseUnit( A.caster, false )
            call PauseUnit( A.target, false )
            
            set A.t = null
            set A.caster = null
            set A.target = null
            call A.v.destroy( )
            call A.destroy( )
        endif
    endif
endfunction

private function Slam takes nothing returns nothing
    local SpellS A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
    local real x = GetUnitX( A.target )
    local real y = GetUnitY( A.target )
    
    if UnitAddAbility( A.target, 'Arav' ) then
        call UnitRemoveAbility( A.target, 'Arav' )
    endif
    
    if UnitAddAbility( A.caster, 'Arav' ) then
        call UnitRemoveAbility( A.caster, 'Arav' )
    endif
    
    call UnitDamageTarget( A.caster, A.target, 40.00, false, false, null, null, null )
    
    call DestroyEffect( AddSpecialEffect( "Abilities\\Spells\\Other\\Volcano\\VolcanoDeath.mdl", GetUnitX( A.caster ), GetUnitY( A.caster ) ) )
    
    set bj_lastCreatedUnit = CreateUnit( GetOwningPlayer( A.caster ), 'u001', x, y, GetUnitFacing( A.caster ) )
    call UnitAddAbility( bj_lastCreatedUnit, 'Arav' )
    call SetUnitX( bj_lastCreatedUnit, x )
    call SetUnitY( bj_lastCreatedUnit, y )
    call SetUnitFlyHeight( bj_lastCreatedUnit, GetUnitFlyHeight( A.caster ), 0.00 )
    call UnitApplyTimedLife( bj_lastCreatedUnit, 'BTLF', 2.00 )
    call SetUnitTimeScale( bj_lastCreatedUnit, 1.50 )
    
    call UnitStartFalling( A.target, 17.50 )
    
    call SetUnitTimeScale( A.caster, 1.00 )
    call SetUnitAnimation( A.caster, "attack slam" )
    call QueueUnitAnimation( A.caster, "stand" )
    
    set A.action = 0
    set A.speed = 3.00
    set A.time = 0.30
    
    call TimerStart( A.t, 0.01, true, function Move )
endfunction

private function SetAnim takes nothing returns nothing
    local SpellS A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
    
    call PauseUnit( A.caster, true )
    call SetUnitTimeScale( A.caster, 2.00 )
    call SetUnitAnimation( A.caster, "spell slam" )
    call QueueUnitAnimation( A.caster, "stand" )
    
    call TimerStart( A.t, 0.30, false, function Slam )
endfunction

private function Spell_Actions takes nothing returns nothing
    local SpellS A = SpellS.create( )
    
    set A.t = CreateTimer( )
    set A.caster = GetTriggerUnit( )
    set A.target = GetSpellTargetUnit( )
    set A.v = vector.create( GetUnitX( A.target ) - GetUnitX( A.caster ), GetUnitY( A.target ) - GetUnitY( A.caster ), 0.00 )
    call A.v.normalize( )
    
    set A.localPlayer = GetLocalPlayer( ) == GetOwningPlayer( A.caster )
    
    call PauseUnit( A.target, true )
    
    call SaveInteger( H, GetHandleId( A.t ), 0, A )
    call TimerStart( A.t, 0.00, false, function SetAnim )
endfunction

//===========================================================================
private function Spell_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A000'
endfunction

function InitTrig_Spell takes nothing returns nothing
    set gg_trg_Spell = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Spell, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Spell, Condition( function Spell_Conditions ) )
    call TriggerAddAction( gg_trg_Spell, function Spell_Actions )
endfunction
endlibrary

Загруженные файлы
28

» WarCraft 3 / Заклинания на заказ

FIRERANGER, скрин ошибки нужен, я просто названия функций не знаю на рефе, но скорее будет жаловаться только на GetEventIsAttack( ) где нужно добавить Blz вначале названия функции
28

» WarCraft 3 / Заклинания на заказ

nazarpunk, проверка на наличие воды в точке на южапи некорректно работает, поэтому заказ выполнять не буду
28

» WarCraft 3 / Как удалять локальные переменные типа location?

EugeAl, ну раз уж такие очевидные дела, то оно автоматом добавляет и stand анимацию в очередь после birth
28

» WarCraft 3 / Заклинания на заказ

Gosick3000, АХАХАХАХ, рад видеть любителя работ blink'a, всегда мечтал научиться делать такие же спеллы, и даже попробовал что-то придумать: xgm.guru/p/wc3/UjAPI-Bahisa-Spellpack-qQU
Следующим спеллпаком хотел лучницу сделать, но нет идей для оригинальной ульты и одного обычного скилла. Мб возьму опалесценцию из отчаяния
Без должных моделек с анимациями и эффектами будет убого выглядеть. В следующий раз лучше предоставлять материалы для работы, чтобы мог более корректно выполнить тз
Попробую на стандарте что-то придумать с этим
28

» WarCraft 3 / Опалесценция (атакующая)

Вышла новая версия! Прокрутить к ресурсу
обновил код, убрал всё, что было сделано для гуишников, дамажит теперь всех врагов, а не только нежить, оставил старую версию
28

» WarCraft 3 / Как удалять локальные переменные типа location?

EugeAl, ничерта он не успеет проиграть, если время разложения эффектов выставишь 0 в константах
28

» WarCraft 3 / Поиск игроков

дискорд хгм либо телеграм хгм* в спец чатах по поиску игроков писать