Добавлен , опубликован

Bahisa Spellpack

Обзор


Автоатака

(А) - Автоатака
Герой выполняет рывок в сторону курсора к ближайшему противнику и наносит удар в секторе. Третий удар имеет увеличенный угол поражения врагов. При промахе рывок имеет увеличенную перезарядку.

Неудержимый Удар

(Q) - Неудержимый Удар
Герой прыгает в указанном направлении, совершая резкое приземление вниз с последующим ударом и расколом земли. Раскол создаёт силовую волну, которая оставляет за собой огненные расщелины.

Рассекающий Вихрь

(W) - Рассекающий Вихрь
Герой взмывает в воздух, начиная быстро вращаться по вертикальной оси, с каждым ударом цепляя к себе противников. По приземлению создаётся ударная волна, расталкивающая противников.

Губительная Мечтательность

(E) - Губительная Мечтательность
Герой подготавливает свою следующую мощную круговую атаку, которая наносит дополнительный урон противникам в секторе перед собой. Разбрасывает врагов. Для преждевременной деактивации достаточно отпустить клавишу способности.

Изничтожение

(R) - Изничтожение
Герой концентрирует собственную тёмную энергию в духовную сингулярность, которая притягивает крупицы душ окружающих противников для значительного усиления урона. Затем резко направляет сгусток полученной силы об землю, создавая астральную волну.

Код

AllGlobals
library AllGlobalsLib initializer OnInit
globals
    constant hashtable H = InitHashtable( )
    constant key AbilityKey
    
    //unit array PlayerUnitUnderCursor
    
    real array PlayerMouseWorldX
    real array PlayerMouseWorldY
    //real array PlayerMouseWorldZ
    
    real MaxX
    real MinX
    real MaxY
    real MinY
endglobals

native UnitAlive takes unit id returns boolean

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 AngleDifference takes real a, real a1 returns real
	set a = RAbsBJ( a - a1 )
	
	if a > 180.00 then
		set a = 360.00 - a
	endif

	return a
endfunction

function IsPointInSector takes real x, real y, real x1, real y1, real orientation, real width returns boolean
    local real lenght = SquareRoot( ( x - x1 ) * ( x - x1 ) + ( y - y1 ) * ( y - y1 ) )
    local real angle = Acos( Cos( orientation ) * ( x - x1 ) / lenght + Sin( orientation ) * ( y - y1 ) / lenght )
    
    return angle <= width
endfunction

function SetUnitPositionSmooth takes unit source, real x, real y returns nothing
    local real last_x = GetUnitX(source)
    local real last_y = GetUnitY(source)
    local boolean bx
    local boolean by

    call SetUnitPosition(source, x, y)

    if (RAbsBJ(GetUnitX(source) - x) > 0.5) or (RAbsBJ(GetUnitY(source) - y) > 0.5) then
        
        call SetUnitPosition(source, x, last_y)
        set bx = RAbsBJ(GetUnitX(source) - x) <= 0.5
        call SetUnitPosition(source, last_x, y)
        set by = RAbsBJ(GetUnitY(source) - y) <= 0.5
        
        if bx then
            call SetUnitPosition(source, x, last_y)
        elseif by then
            call SetUnitPosition(source, last_x, y)
        else
            call SetUnitPosition(source, last_x, last_y)
        endif

    endif
endfunction

function GetCorX takes real x returns real
    if x > MaxX then
        return MaxX
    elseif x < MinX then
        return MinX
    endif
    
    return x
endfunction

function GetCorY takes real y returns real
    if y > MaxY then
        return MaxY
    elseif y < MinY then
        return MinY
    endif
    
    return y
endfunction

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

/*private function TrackUnitUnderCursor takes nothing returns nothing
    set PlayerUnitUnderCursor[ GetPlayerId( GetTriggerPlayer( ) ) ] = GetTriggerUnit( )
endfunction*/

private function TrackMouseWorldXYZ takes nothing returns nothing
    local integer i = GetPlayerId( GetTriggerPlayer( ) )
    
    set PlayerMouseWorldX[i] = GetTriggerPlayerMouseWorldX( )
    set PlayerMouseWorldY[i] = GetTriggerPlayerMouseWorldY( )
    //set PlayerMouseWorldZ[i] = GetTriggerPlayerMouseWorldZ( )
endfunction

private function AbilityCast takes nothing returns nothing
    if HaveSavedString( H, GetSpellAbilityId( ), AbilityKey ) then
        call ExecuteFunc( LoadStr( H, GetSpellAbilityId( ), AbilityKey ) )
    endif
endfunction

private function OnInit takes nothing returns nothing
    local trigger trg = CreateTrigger( )
    //local trigger ttg = CreateTrigger( )
    local trigger tgg = CreateTrigger( )
    local integer i = 0
    local rect r = GetWorldBounds( )
    local player p
    
    call SetMouseMoveEventWorldAxisEnabled( true )
    call SetMouseMoveEventScreenAxisEnabled( false )
    
    call SaveStr( H, 'A000', AbilityKey, "Attack_Actions" )
    call SaveStr( H, 'A001', AbilityKey, "UnstoppableImpact_Actions" )
    call SaveStr( H, 'A002', AbilityKey, "DissectionVortex_Actions" )
    call SaveStr( H, 'A003', AbilityKey, "RuinousReverie_Actions" )
    call SaveStr( H, 'A004', AbilityKey, "Demise_Actions" )
    
    loop
        set p = Player( i )
        
        call TriggerRegisterPlayerEvent( trg, p, EVENT_PLAYER_MOUSE_MOVE )
        //call TriggerRegisterPlayerEvent( ttg, p, EVENT_PLAYER_WIDGET_TRACK )
        call TriggerRegisterPlayerUnitEvent( tgg, p, EVENT_PLAYER_UNIT_SPELL_EFFECT, null )
        
        set i = i + 1
        exitwhen i >= bj_MAX_PLAYER_SLOTS
    endloop
    
    call TriggerAddAction( trg, function TrackMouseWorldXYZ )
    //call TriggerAddAction( ttg, function TrackUnitUnderCursor )
    call TriggerAddAction( tgg, function AbilityCast )
    
    set MaxX = GetRectMaxX( r )
    set MinX = GetRectMinX( r )
    set MaxY = GetRectMaxY( r )
    set MinY = GetRectMinY( r )
    
    call RemoveRect( r )
    
    set bj_lastCreatedEffect = AddSpecialEffect( "DustWindFaster3.mdx", 0.00, 0.00 )
    call SetSpecialEffectVisible( bj_lastCreatedEffect, false )
    call DestroyEffect( bj_lastCreatedEffect )
    
    set bj_lastCreatedEffect = AddSpecialEffect( "WindCirclefaster.mdx", 0.00, 0.00 )
    call SetSpecialEffectVisible( bj_lastCreatedEffect, false )
    call DestroyEffect( bj_lastCreatedEffect )
    
    set bj_lastCreatedEffect = AddSpecialEffect( "WindWeak.mdl", 0.00, 0.00 )
    call SetSpecialEffectVisible( bj_lastCreatedEffect, false )
    call DestroyEffect( bj_lastCreatedEffect )
    
    set bj_lastCreatedEffect = AddSpecialEffect( "WindWeak2.mdl", 0.00, 0.00 )
    call SetSpecialEffectVisible( bj_lastCreatedEffect, false )
    call DestroyEffect( bj_lastCreatedEffect )
    
    set bj_lastCreatedEffect = AddSpecialEffect( "WindWeak(Thicker).mdl", 0.00, 0.00 )
    call SetSpecialEffectVisible( bj_lastCreatedEffect, false )
    call DestroyEffect( bj_lastCreatedEffect )
    
    set bj_lastCreatedEffect = AddSpecialEffect( "model (467).mdl", 0.00, 0.00 )
    call SetSpecialEffectVisible( bj_lastCreatedEffect, false )
    call DestroyEffect( bj_lastCreatedEffect )
    
    set bj_lastCreatedEffect = AddSpecialEffect( "animeslashfinal.mdx", 0.00, 0.00 )
    call SetSpecialEffectVisible( bj_lastCreatedEffect, false )
    call DestroyEffect( bj_lastCreatedEffect )
    
    set bj_lastCreatedEffect = AddSpecialEffect( "model (162).mdl", 0.00, 0.00 )
    call SetSpecialEffectVisible( bj_lastCreatedEffect, false )
    call DestroyEffect( bj_lastCreatedEffect )
    
    set bj_lastCreatedEffect = AddSpecialEffect( "e_slashakihasakura.mdl", 0.00, 0.00 )
    call SetSpecialEffectVisible( bj_lastCreatedEffect, false )
    call DestroyEffect( bj_lastCreatedEffect )
    
    set bj_lastCreatedEffect = AddSpecialEffect( "Ground Slam Fire.mdl", 0.00, 0.00 )
    call SetSpecialEffectVisible( bj_lastCreatedEffect, false )
    call DestroyEffect( bj_lastCreatedEffect )
    
    set bj_lastCreatedEffect = AddSpecialEffect( "[TX][JN]dadizhiji.mdl", 0.00, 0.00 )
    call SetSpecialEffectVisible( bj_lastCreatedEffect, false )
    call DestroyEffect( bj_lastCreatedEffect )
    
    set bj_lastCreatedEffect = AddSpecialEffect( "chushou_by_wood_effect_fire_flamecrack.mdl", 0.00, 0.00 )
    call SetSpecialEffectVisible( bj_lastCreatedEffect, false )
    call DestroyEffect( bj_lastCreatedEffect )
    
    set bj_lastCreatedEffect = AddSpecialEffect( "by_wood_effect_order_dange_liangyishi_zhisizhimoyanzhanji.mdl", 0.00, 0.00 )
    call SetSpecialEffectVisible( bj_lastCreatedEffect, false )
    call DestroyEffect( bj_lastCreatedEffect )
    
    set bj_lastCreatedEffect = AddSpecialEffect( "AZ_daoguang-newX_Black.mdl", 0.00, 0.00 )
    call SetSpecialEffectVisible( bj_lastCreatedEffect, false )
    call DestroyEffect( bj_lastCreatedEffect )
    
    set bj_lastCreatedEffect = AddSpecialEffect( "az2_az_laser3-.mdl", 0.00, 0.00 )
    call SetSpecialEffectVisible( bj_lastCreatedEffect, false )
    call DestroyEffect( bj_lastCreatedEffect )
    
    set bj_lastCreatedEffect = AddSpecialEffect( "[tx][jn]dadizhiji-purple.mdl", 0.00, 0.00 )
    call SetSpecialEffectVisible( bj_lastCreatedEffect, false )
    call DestroyEffect( bj_lastCreatedEffect )
    
    set bj_lastCreatedEffect = AddSpecialEffect( "rb3.mdl", 0.00, 0.00 )
    call SetSpecialEffectVisible( bj_lastCreatedEffect, false )
    call DestroyEffect( bj_lastCreatedEffect )
    
    set bj_lastCreatedEffect = AddSpecialEffect( "rb7.mdl", 0.00, 0.00 )
    call SetSpecialEffectVisible( bj_lastCreatedEffect, false )
    call DestroyEffect( bj_lastCreatedEffect )
    
    set bj_lastCreatedEffect = AddSpecialEffect( "model (79).mdl", 0.00, 0.00 )
    call SetSpecialEffectVisible( bj_lastCreatedEffect, false )
    call DestroyEffect( bj_lastCreatedEffect )
    
    set bj_lastCreatedEffect = AddSpecialEffect( "Astral_Fire.mdl", 0.00, 0.00 )
    call SetSpecialEffectVisible( bj_lastCreatedEffect, false )
    call DestroyEffect( bj_lastCreatedEffect )
    
    set bj_lastCreatedEffect = AddSpecialEffect( "Astral_Black_Bolt.mdl", 0.00, 0.00 )
    call SetSpecialEffectVisible( bj_lastCreatedEffect, false )
    call DestroyEffect( bj_lastCreatedEffect )
    
    set bj_lastCreatedEffect = AddSpecialEffect( "2196_red.mdl", 0.00, 0.00 )
    call SetSpecialEffectVisible( bj_lastCreatedEffect, false )
    call DestroyEffect( bj_lastCreatedEffect )
    
    set bj_lastCreatedEffect = AddSpecialEffect( "model (163).mdl", 0.00, 0.00 )
    call SetSpecialEffectVisible( bj_lastCreatedEffect, false )
    call DestroyEffect( bj_lastCreatedEffect )
    
    set r = null
    set trg = null
    //set ttg = null
endfunction
endlibrary


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

SoundSys
library SoundLib
globals
    private constant hashtable H = InitHashtable( )
    private constant real MaxDistance    = 9999999.00 // макс дистанція звуку
    private constant real VisibleXForAll = 0.00 // видимі координати кожному гравцю у будь-який час гри
    private constant real VisibleYForAll = 0.00
    
    private constant location LFZ = Location( 0.00, 0.00 )
endglobals

function GetLocZ takes real x, real y returns real
    call MoveLocation( LFZ, x, y )
    return GetLocationZ( LFZ )
endfunction

struct Sound
    private static hashtable HS = InitHashtable( ) // таблица для звуков, StringHash(string)
    private static real PTIME   = 0.05
    boolean is_playing = false
    integer volume
    integer tick
    sound sound
    timer timer
    unit u
    real x
    real y
    real z
    real time
    real minDist
    real maxDist
    
    // создает и прелоадит новый звук, не использовать!
    // для получения свободного звука из буфера используйте Sound.path2sound(string)
    static method create takes string path, real time returns thistype
        local thistype n = thistype.allocate( )
        local integer hid = StringHash( path )
        local integer count = LoadInteger( HS, hid, 0 ) + 1
        
        set n.sound = CreateSound( path, false, true, false, 10, 10, "" )
        set n.time  = time
        set n.timer = CreateTimer( )
        call SaveInteger( H, 0, GetHandleId( n.timer ), n )
        call SaveInteger( HS, hid, 0, count )
        call SaveInteger( HS, hid, count, n )
        
        call SetSoundDistanceCutoff( n.sound, MaxDistance )
        call SetSoundDistances( n.sound, MaxDistance, MaxDistance )
        call SetSoundConeAngles( n.sound, MaxDistance, MaxDistance, 127 )
        
        return n
    endmethod
    
    method destroy takes nothing returns nothing
        // заглушка, удалять Sound не надо, они кешируются вместе с sound в hashtable
    endmethod
    
    // остановить звук
    method stop takes nothing returns integer
        if this > 0 and .is_playing then
            call PauseTimer( .timer )
            call StopSound( .sound, false, false )
            set .u = null
            set .is_playing = false
        endif
        
        return 0
    endmethod
    
    static method track takes nothing returns nothing
        local thistype snd = LoadInteger( H, 0, GetHandleId( GetExpiredTimer( ) ) )
        local real x
        local real y
        local real z
        local real d
        
        if snd.u != null then
            if GetUnitTypeId( snd.u ) > 0 then
                set x = snd.x
                set y = snd.y
                set z = snd.z
                
                set snd.x = GetUnitX( snd.u )
                set snd.y = GetUnitY( snd.u )
                set snd.z = GetLocZ( snd.x, snd.y ) + GetUnitFlyHeight( snd.u )
                
                if x != snd.x or y != snd.y or z != snd.z then
                    call SetSoundPosition( snd.sound, snd.x, snd.y, snd.z )
                endif
            else
                set snd.u = null
            endif
        endif
            
        set x = GetCameraTargetPositionX( )
        set y = GetCameraTargetPositionY( )
        set z = GetCameraTargetPositionZ( )
        set d = SquareRoot( ( x - snd.x ) * ( x - snd.x ) + ( y - snd.y ) * ( y - snd.y ) + ( z - snd.z ) * ( z - snd.z ) )
        
        if d > snd.minDist then
            if d > snd.maxDist then
                call SetSoundVolume( snd.sound, 0 )
            else
                call SetSoundVolume( snd.sound, R2I( snd.volume * ( 1.00 - ( ( d - snd.minDist ) / ( snd.maxDist - snd.minDist ) ) ) ) )
            endif
        else
            call SetSoundVolume( snd.sound, snd.volume )
        endif
        
        set snd.tick = snd.tick - 1
        
        if snd.tick <= 0 then
            call snd.stop( )
        else
            call TimerStart( snd.timer, PTIME, false, function thistype.track )
        endif
    endmethod
    
    // проиграть звук в точке
    method play takes nothing returns nothing
        if this <= 0 then
            return
        endif
        
        call SetSoundPosition( .sound, VisibleXForAll, VisibleYForAll, 0.00 )
        call StartSound( .sound )
        
        call SetSoundPosition( .sound, .x, .y, z )
        call SetSoundVolume( .sound, .volume )
        call SetSoundPitch( .sound, GetRandomReal( 0.98, 1.02 ) )
        call SetSoundConeOrientation( .sound, .x, .y, z )
        
        set .is_playing = true
        
        set .tick = R2I( .time / PTIME ) + 1
        call TimerStart( .timer, 0.00, false, function thistype.track )
    endmethod
    
    // получить звук по пути (если нет свободного звука создется новый)
    static method path2sound takes string path returns thistype
        local integer hid = StringHash( path )
        local integer count = LoadInteger( HS, hid, 0 )
        local integer i = 1
        local Sound snd
        
        if count <= 0 then
            return 0
        endif
        
        loop
            exitwhen i > count
            set snd = LoadInteger( HS, hid, i )
            
            if not snd.is_playing then
                return snd
            endif 
            
            set i = i + 1
        endloop
        
        return Sound.create( path, thistype( LoadInteger( HS, hid, 1 ) ).time )
    endmethod
    
    // проиграть звук в точке
    static method playPoint takes string path, real x, real y, real mind, real maxd, integer vol returns thistype
        local thistype snd = path2sound( path )
        
        set snd.x = x
        set snd.y = y
        set snd.z = GetLocZ( snd.x, snd.y )
        set snd.minDist = mind
        set snd.maxDist = maxd
        set snd.volume  = vol
        call snd.play( )
        
        return snd
    endmethod
    
    // проиграть звук на юните
    static method playUnit takes string path, unit u, real mind, real maxd, integer vol returns thistype
        local thistype snd = path2sound( path )
        
        set snd.u = u
        set snd.x = GetUnitX( u )
        set snd.y = GetUnitY( u )
        set snd.z = GetLocZ( snd.x, snd.y ) + GetUnitFlyHeight( u )
        set snd.minDist = mind
        set snd.maxDist = maxd
        set snd.volume  = vol
        call snd.play( )
        
        return snd
    endmethod

    // прелоадит звук в библиотеку. все звуки нужно прелоадить 1 раз.
    static method preload takes string path, real time returns nothing
        call thistype.create( path, time )
    endmethod
endstruct
endlibrary

//===========================================================================
function InitTrig_SoundSys takes nothing returns nothing
    //set gg_trg_SoundSys = CreateTrigger(  )
    call Sound.preload( "Sound\\Buildings\\Death\\BuildingDeathLargeOrc.wav", 3.48 )
    call Sound.preload( "Abilities\\Spells\\Orc\\Shockwave\\Shockwave.wav", 2.84 )
endfunction

Attack
library AttackLib
globals
    private constant group TempGroup = CreateGroup( )
    private constant group TempGroup1 = CreateGroup( )
    
    constant key BahisaAttackAnimationKey
    constant key BahisaAttackDashTimerKey
endglobals

struct AttackS
    unit caster
    player p
    
    real angle
    real range
    real damage
    real damageMin
    real damageMax
    real distance
    real attack_damage_point
    
    integer animId
    
    attacktype attackType
    damagetype damageType
    weapontype weaponType
endstruct

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 DestroyBahisaAttackDashTimer takes nothing returns nothing
    local timer t = GetExpiredTimer( )
    
    call RemoveSavedHandle( H, GetHandleId( LoadUnitHandle( H, GetHandleId( t ), 0 ) ), BahisaAttackDashTimerKey )
    
    call FlushChildHashtable( H, GetHandleId( t ) )
    call DestroyTimer( t )
    
    set t = null
endfunction

private function Damage takes nothing returns nothing
    local timer t = GetExpiredTimer( )
    local AttackS A = LoadInteger( H, GetHandleId( t ), 0 )
    local unit u
    local real x = GetUnitX( A.caster )
    local real y = GetUnitY( A.caster )
    local real x1
    local real y1
    local real w = bj_PI * 0.30
    
    set bj_lastCreatedEffect = AddSpecialEffect( "animeslashfinal.mdx", GetUnitX( A.caster ), GetUnitY( A.caster ) )
    call SetSpecialEffectAlpha( bj_lastCreatedEffect, 155 )
    
    if A.animId == 1 then
        call SetSpecialEffectOrientation( bj_lastCreatedEffect, A.angle, 0.00, 135.00 )
        call SetSpecialEffectZ( bj_lastCreatedEffect, GetSpecialEffectZ( bj_lastCreatedEffect ) + 125.00 )
        call SetSpecialEffectScale( bj_lastCreatedEffect, 1.65 )
    elseif A.animId == 2 then
        call SetSpecialEffectOrientation( bj_lastCreatedEffect, A.angle, 0.00, 45.00 )
        call SetSpecialEffectZ( bj_lastCreatedEffect, GetSpecialEffectZ( bj_lastCreatedEffect ) + 125.00 )
        call SetSpecialEffectScale( bj_lastCreatedEffect, 1.65 )
    else
        call SetSpecialEffectOrientation( bj_lastCreatedEffect, A.angle, 0.00, 0.00 )
        call SetSpecialEffectZ( bj_lastCreatedEffect, GetSpecialEffectZ( bj_lastCreatedEffect ) + 75.00 )
        call SetSpecialEffectScale( bj_lastCreatedEffect, 2.00 )
        
        set w = bj_PI * 0.50
    endif
    
    call DestroyEffect( bj_lastCreatedEffect )
    
    // sector damage
    
    call GroupEnumUnitsInRange( TempGroup, x, y, A.range + 200.00, null )
    
    loop
        set u = FirstOfGroup( TempGroup )
        exitwhen u == null
        call GroupRemoveUnit( TempGroup, u )
        
        if IsUnitInRangeXY( u, x, y, A.range ) then
            if UnitAlive( u ) and IsUnitEnemy( u, A.p ) then
                set x1 = GetUnitX( u )
                set y1 = GetUnitY( u )
                
                if IsPointInSector( x1, y1, x, y, A.angle * bj_DEGTORAD, w ) then
                    call UnitDamageTarget( A.caster, u, GetRandomReal( A.damageMin, A.damageMax ), true, false, A.attackType, A.damageType, A.weaponType )
                    
                    call GroupAddUnit( TempGroup1, u )
                    
                    set bj_lastCreatedEffect = AddSpecialEffect( "Objects\\Spawnmodels\\Human\\HumanLargeDeathExplode\\HumanLargeDeathExplode.mdl", x1, y1 )
                    call SetSpecialEffectZ( bj_lastCreatedEffect, GetSpecialEffectZ( bj_lastCreatedEffect ) + 45.00 )
                    call SetSpecialEffectScale( bj_lastCreatedEffect, 0.80 )
                    
                    if A.animId == 1 then
                        call SetSpecialEffectOrientation( bj_lastCreatedEffect, MathAngleBetweenPoints( x, y, x1, y1 ) + 90.00, -30.00, 0.00 )
                    elseif A.animId == 2 then
                        call SetSpecialEffectOrientation( bj_lastCreatedEffect, MathAngleBetweenPoints( x, y, x1, y1 ) - 90.00, -30.00, 0.00 )
                    else
                        call SetSpecialEffectOrientation( bj_lastCreatedEffect, MathAngleBetweenPoints( x, y, x1, y1 ), GetRandomReal( -70.00, -80.00 ), 0.00 )
                    endif
                    
                    //call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdl", u, "chest" ) )
                    
                    call DestroyEffect( bj_lastCreatedEffect )
                endif
            endif
        endif
    endloop
    
    // radius damage
    
    call GroupEnumUnitsInRange( TempGroup, x, y, A.range * 0.50 + 200.00, null )
    
    loop
        set u = FirstOfGroup( TempGroup )
        exitwhen u == null
        call GroupRemoveUnit( TempGroup, u )
        
        if IsUnitInRangeXY( u, x, y, A.range * 0.50 ) then
            if not IsUnitInGroup( u, TempGroup1 ) and UnitAlive( u ) and IsUnitEnemy( u, A.p ) then
                call UnitDamageTarget( A.caster, u, GetRandomReal( A.damageMin, A.damageMax ), true, false, A.attackType, A.damageType, A.weaponType )
                
                set x1 = GetUnitX( u )
                set y1 = GetUnitY( u )
                
                set bj_lastCreatedEffect = AddSpecialEffect( "Objects\\Spawnmodels\\Human\\HumanLargeDeathExplode\\HumanLargeDeathExplode.mdl", x1, y1 )
                call SetSpecialEffectZ( bj_lastCreatedEffect, GetSpecialEffectZ( bj_lastCreatedEffect ) + 45.00 )
                call SetSpecialEffectScale( bj_lastCreatedEffect, 0.80 )
                
                if A.animId == 1 then
                    call SetSpecialEffectOrientation( bj_lastCreatedEffect, MathAngleBetweenPoints( x, y, x1, y1 ) + 90.00, -30.00, 0.00 )
                elseif A.animId == 2 then
                    call SetSpecialEffectOrientation( bj_lastCreatedEffect, MathAngleBetweenPoints( x, y, x1, y1 ) - 90.00, -30.00, 0.00 )
                else
                    call SetSpecialEffectOrientation( bj_lastCreatedEffect, MathAngleBetweenPoints( x, y, x1, y1 ), GetRandomReal( -70.00, -80.00 ), 0.00 )
                endif
                
                call DestroyEffect( bj_lastCreatedEffect )
            endif
        endif
    endloop
    
    call GroupClear( TempGroup1 )
    
    call FlushChildHashtable( H, GetHandleId( t ) )
    call DestroyTimer( t )
    
    call SetUnitStunned( A.caster, false )
    
    set A.caster = null
    call A.destroy( )
    
    set t = null
endfunction

private function Teleport takes nothing returns nothing
    local timer t = GetExpiredTimer( )
    local AttackS A = LoadInteger( H, GetHandleId( t ), 0 )
    local real x = GetUnitX( A.caster )
    local real y = GetUnitY( A.caster )
    
    set x = GetCorX( x + A.distance * MathCosDeg( A.angle ) )
    set y = GetCorY( y + A.distance * MathSinDeg( A.angle ) )
    
    call SetUnitX( A.caster, x )
    call SetUnitY( A.caster, y )
    
    set bj_lastCreatedEffect = AddSpecialEffect( "WindCirclefaster.mdx", x, y )
    call SetSpecialEffectYaw( bj_lastCreatedEffect, A.angle )
    call SetSpecialEffectScale( bj_lastCreatedEffect, 0.35 )
    call SetSpecialEffectAlpha( bj_lastCreatedEffect, 100 )
    call DestroyEffect( bj_lastCreatedEffect )
    
    set bj_lastCreatedEffect = AddSpecialEffect( "model (467).mdl", x, y )
    call SetSpecialEffectOrientation( bj_lastCreatedEffect, A.angle, 90.00, 0.00 )
    call SetSpecialEffectZ( bj_lastCreatedEffect, GetSpecialEffectZ( bj_lastCreatedEffect ) + 50.00 )
    call SetSpecialEffectAlpha( bj_lastCreatedEffect, 200 )
    call DestroyEffect( bj_lastCreatedEffect )
    
    call TimerStart( t, A.attack_damage_point - 0.10, false, function Damage )
    
    set t = null
endfunction

private function SetAnim takes nothing returns nothing
    local timer t = GetExpiredTimer( )
    local AttackS A = LoadInteger( H, GetHandleId( t ), 0 )
    local real x = GetUnitX( A.caster )
    local real y = GetUnitY( A.caster )
    local real x1
    local real y1
    local unit u
    
    call SetUnitStunned( A.caster, true )
    
    call SetUnitAnimationByIndex( A.caster, A.animId )
    call QueueUnitAnimation( A.caster, "stand" )
    call TimerStart( t, A.attack_damage_point, false, function Damage )
    
    if HaveSavedHandle( H, GetHandleId( A.caster ), BahisaAttackDashTimerKey ) then
        set t = null
        return
    endif
    
    call GroupEnumUnitsInRange( TempGroup, x, y, A.range + 200.00, null )
    
    loop
        set u = FirstOfGroup( TempGroup )
        exitwhen u == null
        call GroupRemoveUnit( TempGroup, u )
        
        if IsUnitInRangeXY( u, x, y, A.range ) then
            if UnitAlive( u ) and IsUnitEnemy( u, A.p ) then
                if IsPointInSector( GetUnitX( u ), GetUnitY( u ), x, y, A.angle * bj_DEGTORAD, bj_PI * 0.30 ) then
                    call GroupClear( TempGroup )
                    
                    set t = null
                    set u = null
                    return
                endif
            endif
        endif
    endloop
    
    // if no catched enemy then teleport
    
    set A.distance = 0.00
    
    set bj_lastCreatedEffect = AddSpecialEffect( "DustWindFaster3.mdx", x, y )
    call SetSpecialEffectYaw( bj_lastCreatedEffect, A.angle )
    call SetSpecialEffectScale( bj_lastCreatedEffect, 0.40 )
    call DestroyEffect( bj_lastCreatedEffect )
    
    set bj_lastCreatedEffect = AddSpecialEffect( "WindCirclefaster.mdx", x, y )
    call SetSpecialEffectYaw( bj_lastCreatedEffect, A.angle )
    call SetSpecialEffectScale( bj_lastCreatedEffect, 0.45 )
    call SetSpecialEffectAlpha( bj_lastCreatedEffect, 100 )
    call DestroyEffect( bj_lastCreatedEffect )
    
    set bj_lastCreatedEffect = AddSpecialEffect( "WindWeak.mdl", x, y )
    call SetSpecialEffectOrientation( bj_lastCreatedEffect, A.angle, 90.00, 0.00 )
    call SetSpecialEffectZ( bj_lastCreatedEffect, GetSpecialEffectZ( bj_lastCreatedEffect ) + 50.00 )
    call SetSpecialEffectScale( bj_lastCreatedEffect, 0.25 )
    call DestroyEffect( bj_lastCreatedEffect )
    
    set x1 = x
    set y1 = y
    
    loop
        set x = x + 32.00 * MathCosDeg( A.angle )
        set y = y + 32.00 * MathSinDeg( A.angle )
        
        set A.distance = A.distance + 32.00
        
        call GroupEnumUnitsInRange( TempGroup, x, y, A.range + 200.00, null )
        
        loop
            set u = FirstOfGroup( TempGroup )
            exitwhen u == null
            call GroupRemoveUnit( TempGroup, u )
            
            if IsUnitInRangeXY( u, x, y, A.range ) then
                if UnitAlive( u ) and IsUnitEnemy( u, A.p ) then
                    if IsPointInSector( GetUnitX( u ), GetUnitY( u ), x, y, A.angle * bj_DEGTORAD, bj_PI * 0.30 ) then
                        set A.distance = RMinBJ( 512.00, MathDistanceBetweenPoints( x1, y1, GetUnitX( u ), GetUnitY( u ) ) - A.range / 2.00 - GetUnitRealField( u, UNIT_RF_COLLISION_SIZE ) )
                        
                        call GroupClear( TempGroup )
                        exitwhen true
                    endif
                endif
            endif
        endloop
        
        if u != null then
            exitwhen true
        endif
        
        exitwhen A.distance >= 512.00
    endloop
    
    if GetLocalPlayer( ) == A.p then
        call PanCameraToTimed( GetUnitX( A.caster ) + ( A.distance + A.range ) * MathCosDeg( A.angle ), GetUnitY( A.caster ) + ( A.distance + A.range ) * MathSinDeg( A.angle ), 0.20 )
    endif
    
    call TimerStart( t, 0.10, false, function Teleport )
    
    call AlphaTeleport( A.caster, 0.10 )
    
    set t = LoadTimerHandle( H, GetHandleId( A.caster ), BahisaAttackDashTimerKey )
    
    if t == null then
        set t = CreateTimer( ) 
        
        call SaveTimerHandle( H, GetHandleId( A.caster ), BahisaAttackDashTimerKey, t )
        call SaveUnitHandle( H, GetHandleId( t ), 0, A.caster )
    endif
    
    if u != null then
        call TimerStart( t, GetUnitWeaponRealField( A.caster, UNIT_WEAPON_RF_ATTACK_BASE_COOLDOWN, 0 ), false, function DestroyBahisaAttackDashTimer )
        set u = null
    else
        call TimerStart( t, GetUnitWeaponRealField( A.caster, UNIT_WEAPON_RF_ATTACK_BASE_COOLDOWN, 0 ) * 3.00 + 0.10, false, function DestroyBahisaAttackDashTimer )
    endif
    
    set t = null
endfunction

function Attack_Actions takes nothing returns nothing
    local timer t = CreateTimer( )
    local AttackS A = AttackS.create( )
    
    set A.caster = GetTriggerUnit( )
    set A.p      = GetOwningPlayer( A.caster )
    
    set A.angle  = MathAngleBetweenPoints( GetUnitX( A.caster ), GetUnitY( A.caster ), PlayerMouseWorldX[ GetPlayerId( A.p ) ], PlayerMouseWorldY[ GetPlayerId( A.p ) ] )
    set A.range  = GetUnitWeaponRealField( A.caster, UNIT_WEAPON_RF_ATTACK_RANGE, 0 )
    
    set A.damage = /*GetUnitWeaponIntegerField( A.caster, UNIT_WEAPON_IF_ATTACK_DAMAGE_BASE, 0 ) + */GetUnitWeaponIntegerField( A.caster, UNIT_WEAPON_IF_ATTACK_DAMAGE_BONUS, 0 )
    set A.damageMin = GetUnitWeaponIntegerField( A.caster, UNIT_WEAPON_IF_ATTACK_DAMAGE_BASE_MINIMUM, 0 )
    set A.damageMax = GetUnitWeaponIntegerField( A.caster, UNIT_WEAPON_IF_ATTACK_DAMAGE_BASE_MAXIMUM, 0 )
    
    set A.attack_damage_point = GetUnitWeaponRealField( A.caster, UNIT_WEAPON_RF_ATTACK_DAMAGE_POINT, 0 )
    
    set A.attackType = ConvertAttackType( GetUnitWeaponIntegerField( A.caster, UNIT_WEAPON_IF_ATTACK_ATTACK_TYPE, 0 ) )
    set A.damageType = ConvertDamageType( GetUnitWeaponIntegerField( A.caster, UNIT_WEAPON_IF_ATTACK_WEAPON_TYPE, 0 ) )
    set A.weaponType = ConvertWeaponType( GetUnitWeaponIntegerField( A.caster, UNIT_WEAPON_IF_ATTACK_WEAPON_SOUND, 0 ) )
    
    set A.animId = LoadInteger( H, GetHandleId( A.caster ), BahisaAttackAnimationKey ) + 1
    
    if A.animId > 2 then
        call RemoveSavedInteger( H, GetHandleId( A.caster ), BahisaAttackAnimationKey )
    else
        call SaveInteger( H, GetHandleId( A.caster ), BahisaAttackAnimationKey, A.animId )
    endif
    
    call SetUnitFacing( A.caster, A.angle )
    call StartAbilityCooldown( GetSpellAbility( ), GetUnitWeaponRealField( A.caster, UNIT_WEAPON_RF_ATTACK_BASE_COOLDOWN, 0 ) - 0.10 )
    
    call SaveInteger( H, GetHandleId( t ), 0, A )
    call TimerStart( t, 0.00, false, function SetAnim )
    
    set t = null
endfunction
endlibrary

//===========================================================================
//function InitTrig_Attack takes nothing returns nothing
    //set gg_trg_Attack = CreateTrigger(  )
//endfunction

UnstoppableImpact
library UnstoppableImpactLib
globals
    private constant group TempGroup = CreateGroup( )
endglobals

struct DiscardingS
    unit target
    vector v
    
    real z
    real speed
endstruct

struct UnstoppableImpactS
    unit caster
    player p
    vector v
    vector l
    effect e
    effect e1
    group g
    
    real height
    real damage
    real speed
    real distance
    real radius
endstruct

function Discarding takes nothing returns nothing
    local DiscardingS A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
    local real x = GetUnitX( A.target )
    local real y = GetUnitY( A.target )
    
    set x = GetCorX( x + A.speed * A.v.x )
    set y = GetCorY( y + A.speed * A.v.y )
    set A.z = A.z + A.speed * A.v.z
    
    set A.v.z = A.v.z - 0.05
    
    call SetUnitX( A.target, x )
    call SetUnitY( A.target, y )
    call SetUnitHeight( A.target, A.z )
    
    if GetUnitHeight( A.target ) <= A.speed or not UnitAlive( A.target ) then
        call SetUnitStunned( A.target, false )
        call SetUnitHeight( A.target, 0.00 )
        
        call PauseTimer( GetExpiredTimer( ) )
        call FlushChildHashtable( H, GetHandleId( GetExpiredTimer( ) ) )
        call DestroyTimer( GetExpiredTimer( ) )
        
        set A.target = null
        call A.v.destroy( )
        call A.destroy( )
    endif
endfunction

private function WaveDamage takes nothing returns nothing
    local UnstoppableImpactS A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
    local unit u
    
    set A.height = A.height - 0.01
    
    if A.height <= 0.00 then
        set A.height = 0.50
    
        call GroupEnumUnitsInRange( TempGroup, A.v.x, A.v.y, A.radius + 200.00, null )
            
        loop
            set u = FirstOfGroup( TempGroup )
            exitwhen u == null
            call GroupRemoveUnit( TempGroup, u )
            
            if IsUnitInRangeXY( u, A.v.x, A.v.y, A.radius ) then
                if UnitAlive( u ) and IsUnitEnemy( u, A.p ) then
                    call UnitDamageTarget( A.caster, u, A.damage, false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_FIRE, null )
                    call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Weapons\\LordofFlameMissile\\LordofFlameMissile.mdl", u, "chest" ) )
                endif
            endif
        endloop
    endif
    
    set A.distance = A.distance - 0.01
    
    if A.distance < 1.00 then
        call SetSpecialEffectAlpha( A.e, R2I( 255.00 * A.distance / 1.00 ) )
        call SetSpecialEffectAlpha( A.e1, R2I( 255.00 * A.distance / 1.00 ) )
        
        if A.distance <= 0.50 then
            call SetSpecialEffectZ( A.e, GetSpecialEffectZ( A.e ) - 2.50 )
        endif
    endif
    
    if A.distance <= 0.00 then
        call PauseTimer( GetExpiredTimer( ) )
        call FlushChildHashtable( H, GetHandleId( GetExpiredTimer( ) ) )
        call DestroyTimer( GetExpiredTimer( ) )
        
        call SetSpecialEffectVisible( A.e, false )
        call DestroyEffect( A.e )
        call DestroyEffect( A.e1 )
        
        set A.e = null
        set A.e1 = null
        set A.caster = null
        
        call A.v.destroy( )
        call A.destroy( )
    endif
endfunction

private function MoveWave takes nothing returns nothing
    local UnstoppableImpactS A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
    local UnstoppableImpactS B
    local DiscardingS S
    local timer t
    local unit u
    
    if A.speed > A.distance then
        set A.speed = A.distance
    endif
    
    set A.l.x = A.l.x + A.speed * A.v.x
    set A.l.y = A.l.y + A.speed * A.v.y
    
    set A.distance = A.distance - A.speed
    
    set A.height = A.height - 0.01
    
    call DestroyEffect( AddSpecialEffect( "Abilities\\Weapons\\AncientProtectorMissile\\AncientProtectorMissile.mdl", A.l.x, A.l.y ) )
    
    if A.height <= 0.00 then
        set A.height = 0.06
        
        set bj_lastCreatedEffect = AddSpecialEffect( "Abilities\\Weapons\\TreantMissile\\TreantMissile.mdl", A.l.x, A.l.y )
        call SetSpecialEffectFacing( bj_lastCreatedEffect, Atan2( A.v.y, A.v.x ) * bj_RADTODEG - 180.00 )
        call SetSpecialEffectScale( bj_lastCreatedEffect, 1.50 + 1.00 * A.distance / 800.00 )
        call DestroyEffect( bj_lastCreatedEffect )
        
        set t = CreateTimer( )
        set B = UnstoppableImpactS.create( )
        
        set B.caster = A.caster
        set B.p = A.p
        set B.v = vector.create( A.l.x, A.l.y, 0.00 )
        set B.radius = 64.00 + 96.00 * A.distance / 800.00
        set B.distance = 5.00
        set B.height = 0.50
        set B.damage = A.damage * 0.10
        
        set B.e = AddSpecialEffect( "Doodads\\Barrens\\Rocks\\BarrensFissure\\BarrensFissure" + I2S( GetRandomInt( 0, 1 ) ) + ".mdl", B.v.x, B.v.y )
        call SetSpecialEffectScale( B.e, 0.40 + 0.50 * A.distance / 800.00 )
        call SetSpecialEffectFacing( B.e, Atan2( A.v.y, A.v.x ) * bj_RADTODEG )
        
        set B.e1 = AddSpecialEffect( "Abilities\\Spells\\Orc\\EarthQuake\\EarthQuakeTarget.mdl", B.v.x, B.v.y )
        call SetSpecialEffectFacing( B.e1, GetRandomReal( 0.00, 360.00 ) )
        call SetSpecialEffectScale( B.e1, 0.40 + 0.50 * A.distance / 800.00 )
    
        call SaveInteger( H, GetHandleId( t ), 0, B )
        call TimerStart( t, 0.01, true, function WaveDamage )
    endif
    
    call GroupEnumUnitsInRange( TempGroup, A.l.x, A.l.y, ( 64.00 + 96.00 * A.distance / 800.00 ) + 200.00, null )
        
    loop
        set u = FirstOfGroup( TempGroup )
        exitwhen u == null
        call GroupRemoveUnit( TempGroup, u )
        
        if not IsUnitInGroup( u, A.g ) and IsUnitInRangeXY( u, A.l.x, A.l.y, ( 64.00 + 96.00 * A.distance / 800.00 ) ) then
            if UnitAlive( u ) and IsUnitEnemy( u, A.p ) then
                call GroupAddUnit( A.g, u )
                
                call UnitDamageTarget( A.caster, u, A.damage, false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SONIC, null )
                call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Weapons\\AncientProtectorMissile\\AncientProtectorMissile.mdl", u, "chest" ) )
                
                set t = CreateTimer( )
                set S = DiscardingS.create( )
                
                set S.target = u
                set S.z = 100.00
                
                call SetUnitHeight( u, S.z )
                
                set S.v = vector.create( ( A.l.x - 100.00 * A.v.x ) - GetUnitX( u ), ( A.l.y - 100.00 * A.v.y ) - GetUnitY( u ), 1.00 )
                
                set S.speed = 3.00 + S.v.length( ) * 0.001
                
                call S.v.normalize( )
                
                set S.v.z = 0.30
                
                call SetUnitStunned( u, true )
                
                call SaveInteger( H, GetHandleId( t ), 0, S )
                call TimerStart( t, 0.01, true, function Discarding )
            endif
        endif
    endloop
    
    call SetSpecialEffectPosition( A.e, A.l.x, A.l.y )
    call SetSpecialEffectScale( A.e, 1.25 + 0.75 * A.distance / 800.00 )
    call SetSpecialEffectAlpha( A.e, R2I( 255.00 * ( A.distance / 800.00 ) ) )
    
    if A.distance <= 0.00 then
        set t = GetExpiredTimer( )
        
        call PauseTimer( t )
        call FlushChildHashtable( H, GetHandleId( t ) )
        call DestroyTimer( t )
        
        call DestroyEffect( A.e )
        call DestroyGroup( A.g )
        
        set A.g = null
        set A.e = null
        set A.caster = null
        
        call A.l.destroy( )
        call A.v.destroy( )
        call A.destroy( )
    endif
    
    set t = null
endfunction

private function Jump takes nothing returns nothing
    local UnstoppableImpactS A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
    local DiscardingS S
    local real x = GetUnitX( A.caster )
    local real y = GetUnitY( A.caster )
    local unit u
    local timer t
    
    if A.speed > A.distance then
        set A.speed = A.distance
    endif
    
    set x = x + A.speed * A.v.x
    set y = y + A.speed * A.v.y
    
    call SetUnitX( A.caster, GetCorX( x ) )
    call SetUnitY( A.caster, GetCorY( y ) )
    
    set A.distance = A.distance - A.speed
    
    if A.height < 150.00 then
        set A.height = A.height + 5.00
        call SetUnitHeight( A.caster, 50.00 + A.height )
        
        if A.height >= 150.00 then
            call SetUnitFacingInstant( A.caster, Atan2( A.v.y, A.v.x ) * bj_RADTODEG )
            
            set bj_lastCreatedEffect = AddSpecialEffect( "WindWeak.mdl", x, y )
            call SetSpecialEffectOrientation( bj_lastCreatedEffect, Atan2( A.v.y, A.v.x ) * bj_RADTODEG, 90.00, 0.00 )
            call SetSpecialEffectZ( bj_lastCreatedEffect, GetSpecialEffectZ( bj_lastCreatedEffect ) + 200.00 )
            call SetSpecialEffectScale( bj_lastCreatedEffect, 0.50 )
            call DestroyEffect( bj_lastCreatedEffect )
            
            set x = GetCorX( x + 100.00 * A.v.x )
            set y = GetCorY( y + 100.00 * A.v.y )
            
            set bj_lastCreatedEffect = AddSpecialEffect( "DustWindFaster3.mdx", x + 175.00 * A.v.x, y + 175.00 * A.v.y )
            call SetSpecialEffectYaw( bj_lastCreatedEffect, Atan2( A.v.y, A.v.x ) * bj_RADTODEG )
            call SetSpecialEffectScale( bj_lastCreatedEffect, 0.75 )
            call SetSpecialEffectZ( bj_lastCreatedEffect, GetSpecialEffectZ( bj_lastCreatedEffect ) + 200.00 )
            call SetSpecialEffectAlpha( bj_lastCreatedEffect, 155 )
            call DestroyEffect( bj_lastCreatedEffect )
            
            set bj_lastCreatedEffect = AddSpecialEffect( "WindWeak.mdl", x, y )
            call SetSpecialEffectOrientation( bj_lastCreatedEffect, Atan2( A.v.y, A.v.x ) * bj_RADTODEG, 90.00, 0.00 )
            call SetSpecialEffectZ( bj_lastCreatedEffect, GetSpecialEffectZ( bj_lastCreatedEffect ) + 200.00 )
            call SetSpecialEffectScale( bj_lastCreatedEffect, 0.25 )
            call DestroyEffect( bj_lastCreatedEffect )
            
            set bj_lastCreatedEffect = AddSpecialEffect( "model (467).mdl", x, y )
            call SetSpecialEffectOrientation( bj_lastCreatedEffect, Atan2( A.v.y, A.v.x ) * bj_RADTODEG, 90.00, 0.00 )
            call SetSpecialEffectZ( bj_lastCreatedEffect, GetSpecialEffectZ( bj_lastCreatedEffect ) + 200.00 )
            call DestroyEffect( bj_lastCreatedEffect )
            
            call SetUnitX( A.caster, x )
            call SetUnitY( A.caster, y )
            
            set A.distance = A.distance - 100.00
            
            set A.speed = A.speed * 2.50
        endif
    endif
    
    if GetLocalPlayer( ) == A.p then
        call SetCameraField( CAMERA_FIELD_ZOFFSET, 50.00 + A.height, 0.10 )
    endif
    
    if A.distance <= 0.00 then
        set x = x + 156.00 * A.v.x
        set y = y + 156.00 * A.v.y
        
        call GroupEnumUnitsInRange( TempGroup, x, y, A.radius + 200.00, null )
        
        loop
            set u = FirstOfGroup( TempGroup )
            exitwhen u == null
            call GroupRemoveUnit( TempGroup, u )
            
            if IsUnitInRangeXY( u, x, y, A.radius ) then
                if UnitAlive( u ) and IsUnitEnemy( u, A.p ) then
                    call GroupAddUnit( A.g, u )
                    
                    call UnitDamageTarget( A.caster, u, A.damage, false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SONIC, null )
                    call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Weapons\\AncientProtectorMissile\\AncientProtectorMissile.mdl", u, "chest" ) )
                    
                    set t = CreateTimer( )
                    set S = DiscardingS.create( )
                    
                    set S.target = u
                    set S.z = 100.00
                    
                    call SetUnitHeight( u, S.z )
                    
                    set S.v = vector.create( GetUnitX( u ) - x, GetUnitY( u ) - y, 1.00 )
                    
                    set S.speed = S.v.length( )
                    
                    if S.speed > 250.00 then
                        set S.speed = 250.00
                    endif
                    
                    call S.v.normalize( )
                    
                    set S.v.z = 2.50 * ( 1.00 - S.speed / 250.00 )
                    
                    set S.speed = 2.00 + S.speed * 0.01
                    
                    call SetUnitStunned( u, true )
                    
                    call SaveInteger( H, GetHandleId( t ), 0, S )
                    call TimerStart( t, 0.01, true, function Discarding )
                endif
            endif
        endloop
        
        set t = null
        
        set bj_lastCreatedEffect = AddSpecialEffect( "Ground Slam Fire.mdl", x, y )
        call SetSpecialEffectScale( bj_lastCreatedEffect, 2.00 )
        call SetSpecialEffectYaw( bj_lastCreatedEffect, GetRandomReal( 0.00, 360.00 ) )
        call DestroyEffect( bj_lastCreatedEffect )
        
        set bj_lastCreatedEffect = AddSpecialEffect( "WindWeak2.mdl", x, y )
        call SetSpecialEffectScale( bj_lastCreatedEffect, 4.00 )
        call SetSpecialEffectYaw( bj_lastCreatedEffect, GetRandomReal( 0.00, 360.00 ) )
        call DestroyEffect( bj_lastCreatedEffect )
        
        set bj_lastCreatedEffect = AddSpecialEffect( "[TX][JN]dadizhiji.mdl", x, y )
        call SetSpecialEffectScale( bj_lastCreatedEffect, 2.00 )
        call SetSpecialEffectYaw( bj_lastCreatedEffect, Atan2( A.v.y, A.v.x ) * bj_RADTODEG )
        call DestroyEffect( bj_lastCreatedEffect )
        
        set bj_lastCreatedEffect = AddSpecialEffect( "chushou_by_wood_effect_fire_flamecrack.mdl", x, y )
        call SetSpecialEffectYaw( bj_lastCreatedEffect, GetRandomReal( 0.00, 360.00 ) )
        call DestroyEffect( bj_lastCreatedEffect )
        
        set bj_lastCreatedEffect = AddSpecialEffect( "by_wood_effect_order_dange_liangyishi_zhisizhimoyanzhanji.mdl", x, y )
        call SetSpecialEffectScale( bj_lastCreatedEffect, 2.00 )
        call SetSpecialEffectYaw( bj_lastCreatedEffect, GetRandomReal( 0.00, 360.00 ) )
        call DestroyEffect( bj_lastCreatedEffect )
        
        set bj_lastCreatedEffect = AddSpecialEffect( "e_slashakihasakura.mdl", x, y )
        call SetSpecialEffectOrientation( bj_lastCreatedEffect, Atan2( A.v.y, A.v.x ) * bj_RADTODEG, -90.00, 0.00 )
        call SetSpecialEffectZ( bj_lastCreatedEffect, GetSpecialEffectZ( bj_lastCreatedEffect ) + 175.00 )
        call SetSpecialEffectScale( bj_lastCreatedEffect, 1.25 )
        call SetSpecialEffectTimeScale( bj_lastCreatedEffect, 1.75 )
        call DestroyEffect( bj_lastCreatedEffect )
        
        call SetUnitHeight( A.caster, 0.00 )
        call SetUnitStunned( A.caster, false )
        
        if GetLocalPlayer( ) == A.p then
            call ResetToGameCamera( 0.10 )
            call CameraSetSmoothingFactor( 0.00 )
        endif
        
        // create wave
        set A.e = AddSpecialEffect( "model (162).mdl", x, y )
        set A.l = vector.create( x, y, 0.00 )
        set A.distance = 800.00
        set A.speed = 15.00
        set A.height = 0.06
        
        call SetSpecialEffectScale( A.e, 2.00 )
        call SetSpecialEffectYaw( A.e, Atan2( A.v.y, A.v.x ) * bj_RADTODEG )
        
        call TimerStart( GetExpiredTimer( ), 0.01, true, function MoveWave )
    endif
endfunction

private function SetAnim takes nothing returns nothing
    local timer t = GetExpiredTimer( )
    local UnstoppableImpactS A = LoadInteger( H, GetHandleId( t ), 0 )
    
    call SetUnitStunned( A.caster, true )
    call SetUnitAnimation( A.caster, "spell one" )
    call QueueUnitAnimation( A.caster, "stand" )
    
    set bj_lastCreatedEffect = AddSpecialEffect( "model (467).mdl", GetUnitX( A.caster ), GetUnitY( A.caster ) )
    call SetSpecialEffectScale( bj_lastCreatedEffect, 0.50 )
    call DestroyEffect( bj_lastCreatedEffect )
            
    call TimerStart( t, 0.01, true, function Jump )
    
    set t = null
endfunction

function UnstoppableImpact_Actions takes nothing returns nothing
    local timer t = CreateTimer( )
    local UnstoppableImpactS A = UnstoppableImpactS.create( )
    local real x
    local real y
    local integer i
    
    set A.caster = GetTriggerUnit( )
    set A.p = GetOwningPlayer( A.caster )
    
    set i = GetPlayerId( A.p )
    set x = GetUnitX( A.caster )
    set y = GetUnitY( A.caster )
    
    set A.v = vector.create( PlayerMouseWorldX[i] - x, PlayerMouseWorldY[i] - y, 1.00 )
    
    call SetUnitFacing( A.caster, Atan2( A.v.y, A.v.x ) * bj_RADTODEG )
    
    set A.distance = A.v.length( )
    
    if A.distance < 300.00 then
        set A.distance = 300.00
    elseif A.distance > 850.00 then
        set A.distance = 850.00
    endif
    
    set A.damage = ( GetUnitWeaponIntegerField( A.caster, UNIT_WEAPON_IF_ATTACK_DAMAGE_BASE, 0 ) + GetUnitWeaponIntegerField( A.caster, UNIT_WEAPON_IF_ATTACK_DAMAGE_BONUS, 0 ) ) * 5.00
    set A.speed = A.distance * 0.01
    set A.radius = 250.00
    set A.height = 0.00
    set A.g = CreateGroup( )
    
    call A.v.normalize( )
    
    if GetLocalPlayer( ) == A.p then
        call CameraSetSmoothingFactor( 1.00 )
        call SetCameraTargetController( A.caster, 256.00 * A.v.x, 256.00 * A.v.y, false )
    endif
    
    call SaveInteger( H, GetHandleId( t ), 0, A )
    call TimerStart( t, 0.00, false, function SetAnim )
    
    set t = null
endfunction
endlibrary

//===========================================================================
//function InitTrig_UnstoppableImpact takes nothing returns nothing
    //set gg_trg_UnstoppableImpact = CreateTrigger(  )
//endfunction

DissectionVortex
library DissectionVortexLib requires UnstoppableImpactLib
globals
    private constant group TempGroup = CreateGroup( )
endglobals

struct DissectionVortexS
    unit caster
    effect casterEff = null
    effect e
    effect e1
    effect e2
    player p
    vector v
    
    real height
    real damage
    real damageTime
    real speed
    real distance
    real radius
    real angle
endstruct

private function Jump takes nothing returns nothing
    local DissectionVortexS A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
    local real x = GetUnitX( A.caster )
    local real y = GetUnitY( A.caster )
    local real z
    local real a
    local unit u
    local timer t
    local DiscardingS S
    
    set x = GetCorX( x + A.speed * A.v.x )
    set y = GetCorY( y + A.speed * A.v.y )
    
    call SetUnitX( A.caster, x )
    call SetUnitY( A.caster, y )
    
    if A.casterEff != null then
        set A.height = A.height - 15.00
        set A.damageTime = A.damageTime + 0.01
        
        if A.damageTime >= 0.05 then
            set A.damageTime = 0.00
            call GroupEnumUnitsInRange( TempGroup, x, y, A.radius + 200.00, null )
            
            loop
                set u = FirstOfGroup( TempGroup )
                exitwhen u == null
                call GroupRemoveUnit( TempGroup, u )
                
                if IsUnitInRangeXY( u, x, y, A.radius ) then
                    if UnitAlive( u ) and IsUnitEnemy( u, A.p ) then
                        if RAbsBJ( GetUnitFlyHeight( u ) - A.height ) <= A.radius * 2.00 then
                            set a = Atan2( y - GetUnitY( u ), x - GetUnitX( u ) )
                            call SetUnitX( u, GetUnitX( u ) + 20.00 * Cos( a ) )
                            call SetUnitY( u, GetUnitY( u ) + 20.00 * Sin( a ) )
                            
                            call UnitDamageTarget( A.caster, u, A.damage * 0.35, false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_DEMOLITION, null )
                            call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdl", u, "chest" ) )
                            
                            call IssueImmediateOrder( u, "stop" )
                        endif
                    endif
                endif
            endloop
        endif
        
        set z = GetAxisZ( x, y ) + A.height
        call SetSpecialEffectPositionWithZ( A.casterEff, x + 128.00 * Cos( A.angle ), y + 128.00 * Sin( A.angle ), z + 50.00 )
        call SetSpecialEffectPositionWithZ( A.e, x, y, z )
        call SetSpecialEffectPositionWithZ( A.e1, x, y, z + 50.00 )
        call SetSpecialEffectPositionWithZ( A.e2, x, y, z + 50.00 )
    else
        set A.height = A.height + 5.00
        
        if A.height >= 150.00 then
            set A.height = 640.00
            set A.casterEff = AddSpecialEffect( "Bahisa.mdx", x, y )
            
            call SetSpecialEffectAnimationByIndex( A.casterEff, 3 )
            call SetSpecialEffectOrientation( A.casterEff, Atan2( A.v.y, A.v.x ) * bj_RADTODEG - 180.00, 90.00, 90.00 )
            
            call SetUnitVertexColor( A.caster, 255, 255, 255, 0 )
            call SetUnitAnimationByIndex( A.caster, 3 )
            call QueueUnitAnimation( A.caster, "stand" )
            
            set bj_lastCreatedEffect = AddSpecialEffect( "WindWeak.mdl", x, y )
            call SetSpecialEffectOrientation( bj_lastCreatedEffect, Atan2( A.v.y, A.v.x ) * bj_RADTODEG, -25.00, 0.00 )
            call SetSpecialEffectZ( bj_lastCreatedEffect, GetSpecialEffectZ( bj_lastCreatedEffect ) + 200.00 )
            call SetSpecialEffectScale( bj_lastCreatedEffect, 0.40 )
            call DestroyEffect( bj_lastCreatedEffect )
            
            set x = GetCorX( x + 100.00 * A.v.x )
            set y = GetCorY( y + 100.00 * A.v.y )
    
            call SetUnitX( A.caster, x )
            call SetUnitY( A.caster, y )
            
            set A.e = AddSpecialEffect( "az2_az_laser3-.mdl", x, y )
            call SetSpecialEffectYaw( A.e, Atan2( A.v.y, A.v.x ) * bj_RADTODEG - 90.00 )
            call SetSpecialEffectZ( A.e, GetSpecialEffectZ( A.e ) + A.height )
            
            set A.e1 = AddSpecialEffect( "AZ_daoguang-newX_Black.mdl", x, y )
            call SetSpecialEffectOrientation( A.e1, Atan2( A.v.y, A.v.x ) * bj_RADTODEG - 90.00, 90.00, 0.00 )
            call SetSpecialEffectZ( A.e1, GetSpecialEffectZ( A.e1 ) + A.height )
            
            set A.e2 = AddSpecialEffect( "AZ_daoguang-newX_Black.mdl", x, y )
            call SetSpecialEffectOrientation( A.e2, Atan2( A.v.y, A.v.x ) * bj_RADTODEG + 90.00, 90.00, 0.00 )
            call SetSpecialEffectZ( A.e2, GetSpecialEffectZ( A.e2 ) + A.height )
        endif
        
        call SetUnitHeight( A.caster, 50.00 + A.height )
    endif
    
    if GetLocalPlayer( ) == A.p then
        call SetCameraField( CAMERA_FIELD_ZOFFSET, 50.00 + A.height, 0.10 )
    endif
    
    if A.height <= 0.00 then
        call SetUnitHeight( A.caster, 0.00 )
        call SetUnitVertexColor( A.caster, 255, 255, 255, 255 )
        call SetUnitStunned( A.caster, false )
        
        call DestroyEffect( AddSpecialEffect( "model (163).mdl", x, y ) )
    
        set bj_lastCreatedEffect = AddSpecialEffect( "2196_red.mdl", x, y )
        call SetSpecialEffectScale( bj_lastCreatedEffect, 1.50 )
        call SetSpecialEffectAlpha( bj_lastCreatedEffect, 35 )
        call DestroyEffect( bj_lastCreatedEffect )
        
        call SetSpecialEffectVisible( A.casterEff, false )
        call DestroyEffect( A.casterEff )
        call DestroyEffect( A.e )
        call DestroyEffect( A.e1 )
        call DestroyEffect( A.e2 )
        
        set A.casterEff = null
        set A.e = null
        set A.e1 = null
        set A.e2 = null
        
        set t = GetExpiredTimer( )
        
        call PauseTimer( t )
        call FlushChildHashtable( H, GetHandleId( t ) )
        call DestroyTimer( t )
        
        call GroupEnumUnitsInRange( TempGroup, x, y, A.radius * 2.00 + 200.00, null )
        
        loop
            set u = FirstOfGroup( TempGroup )
            exitwhen u == null
            call GroupRemoveUnit( TempGroup, u )
            
            if IsUnitInRangeXY( u, x, y, A.radius * 2.00 ) then
                if UnitAlive( u ) and IsUnitEnemy( u, A.p ) then
                    call UnitDamageTarget( A.caster, u, A.damage, false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_DEMOLITION, null )
                    call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Weapons\\AncientProtectorMissile\\AncientProtectorMissile.mdl", u, "chest" ) )
                
                    set t = CreateTimer( )
                    set S = DiscardingS.create( )
                    
                    set S.target = u
                    set S.z = 60.00
                    
                    call SetUnitHeight( u, S.z )
                    
                    set S.v = vector.create( GetUnitX( u ) - x, GetUnitY( u ) - y, 1.00 )
                    
                    set S.speed = S.v.length( )
                    
                    if S.speed > 250.00 then
                        set S.speed = 250.00
                    endif
                    
                    call S.v.normalize( )
                    
                    set S.v.z = 2.00 * ( 1.00 - S.speed / 250.00 )
                    
                    set S.speed = 2.00 + ( 250.00 - S.speed ) * 0.01
                    
                    call SetUnitStunned( u, true )
                    
                    call SaveInteger( H, GetHandleId( t ), 0, S )
                    call TimerStart( t, 0.01, true, function Discarding )
                endif
            endif
        endloop
        
        if GetLocalPlayer( ) == A.p then
            call ResetToGameCamera( 0.10 )
            call CameraSetSmoothingFactor( 0.00 )
        endif
        
        set A.caster = null
        call A.v.destroy( )
        call A.destroy( )
        
        set t = null
    endif
endfunction

private function SetAnim takes nothing returns nothing
    local timer t = GetExpiredTimer( )
    local DissectionVortexS A = LoadInteger( H, GetHandleId( t ), 0 )
    
    call SetUnitStunned( A.caster, true )
    call SetUnitAnimation( A.caster, "spell one" )
    call QueueUnitAnimation( A.caster, "stand" )
    
    set bj_lastCreatedEffect = AddSpecialEffect( "model (467).mdl", GetUnitX( A.caster ), GetUnitY( A.caster ) )
    call SetSpecialEffectScale( bj_lastCreatedEffect, 0.50 )
    call DestroyEffect( bj_lastCreatedEffect )
    
    set bj_lastCreatedEffect = AddSpecialEffect( "WindCirclefaster.mdl", GetUnitX( A.caster ), GetUnitY( A.caster ) )
    call SetSpecialEffectScale( bj_lastCreatedEffect, 1.50 )
    call SetSpecialEffectVertexColour( bj_lastCreatedEffect, 255, 155, 155, 155 )
    call DestroyEffect( bj_lastCreatedEffect )
    
    call TimerStart( t, 0.01, true, function Jump )
    
    set t = null
endfunction

function DissectionVortex_Actions takes nothing returns nothing
    local timer t = CreateTimer( )
    local DissectionVortexS A = DissectionVortexS.create( )
    local real x
    local real y
    local integer i
    
    set A.caster = GetTriggerUnit( )
    set A.p = GetOwningPlayer( A.caster )
    
    set i = GetPlayerId( A.p )
    set x = GetUnitX( A.caster )
    set y = GetUnitY( A.caster )
    
    set A.v = vector.create( PlayerMouseWorldX[i] - x, PlayerMouseWorldY[i] - y, 1.00 )
    
    set A.angle = Atan2( A.v.y, A.v.x )
    call SetUnitFacing( A.caster, A.angle * bj_RADTODEG )
    
    set A.angle = A.angle + bj_PI * 0.50
    set A.distance = A.v.length( )
    
    call A.v.normalize( )
    
    if A.distance < 128.00 then
        set A.distance = 128.00
    elseif A.distance > 512.00 then
        set A.distance = 512.00
    endif
    
    set A.damage = ( GetUnitWeaponIntegerField( A.caster, UNIT_WEAPON_IF_ATTACK_DAMAGE_BASE, 0 ) + GetUnitWeaponIntegerField( A.caster, UNIT_WEAPON_IF_ATTACK_DAMAGE_BONUS, 0 ) ) * 4.00
    set A.speed = A.distance * 0.01
    set A.radius = 185.00
    set A.height = 0.00
    set A.damageTime = 0.00
    
    if GetLocalPlayer( ) == A.p then
        call CameraSetSmoothingFactor( 1.00 )
        call SetCameraTargetController( A.caster, 256.00 * A.v.x, 256.00 * A.v.y, false )
    endif
    
    call SaveInteger( H, GetHandleId( t ), 0, A )
    call TimerStart( t, 0.00, false, function SetAnim )
    
    set t = null
endfunction
endlibrary

//===========================================================================
//function InitTrig_DissectionVortex takes nothing returns nothing
    //set gg_trg_DissectionVortex = CreateTrigger(  )
//endfunction

RuinousReverie
library RuinousReverieLib initializer OnInit requires UnstoppableImpactLib
globals
    private constant group TempGroup = CreateGroup( )
    private boolean array RuinousReverieKeyPressed
    private framehandle CastBarBorder = null
    private framehandle CastBarBackdrop = null
    private framehandle CastBar = null
    private framehandle CastBarText = null
endglobals

struct RuinousReverieS
    unit caster
    player p
    vector v
    effect e
    effect e1
    
    real time
    real angle
    real radius
    real damage
endstruct

private function RuinousReverie_Actions_2 takes nothing returns nothing
    call TriggerSleepAction( 0.00 )
    
    set RuinousReverieKeyPressed[ GetPlayerId( GetTriggerPlayer( ) ) ] = false
endfunction

function FadeEffectPeriodic takes nothing returns nothing
    local timer t = GetExpiredTimer( )
    local integer i = GetHandleId( t )
    local integer r = LoadInteger( H, i, 1 ) - 1
    
    call SetSpecialEffectVertexColour( LoadEffectHandle( H, i, 0 ), 255, 255, 255, r )
    
    if r <= 0 then
        call DestroyEffect( LoadEffectHandle( H, i, 0 ) )
        
        call PauseTimer( t )
        call DestroyTimer( t )
        call FlushChildHashtable( H, i )
    else
        call SaveInteger( H, i, 1, r )
    endif

    set t = null
endfunction

function FadeEffect takes effect e, real time returns nothing
    local timer t = CreateTimer( )
    
    call SaveEffectHandle( H, GetHandleId( t ), 0, e )
    call SaveInteger( H, GetHandleId( t ), 1, 255 )
    
    call TimerStart( t, time, true, function FadeEffectPeriodic )

    set t = null
endfunction

private function CheckTimeKey takes nothing returns nothing
    local RuinousReverieS A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
    local DiscardingS S
    local timer t
    local unit u
    local real x
    local real y
    
    set A.time = A.time - 0.01
    
    if A.time < 1.00 then
        call SetSpecialEffectScale( A.e, GetSpecialEffectScale( A.e ) + 0.01 )
    endif
    
    if GetLocalPlayer( ) == A.p then
        call SetFrameText( CastBarText, I2S( R2I( ( 1.00 - A.time / 1.50 ) / 0.01 ) ) +"%" )
        call SetFrameTextColour( CastBarText, ConvertColour( 255, 55 + R2I( 200 - 200 * A.time / 1.50 ), 55 + R2I( 200 * A.time / 1.50 ), 255 ) )
        call SetFrameSize( CastBar, 0.20 - 0.20 * ( A.time / 1.50 ), 0.02 )
    endif
    
    call SetSpecialEffectAlpha( A.e, R2I( ParabolaZ( 50.00, 1.50, A.time ) ) )
    
    if A.time <= 0.00 or ( A.time <= 1.40 and not RuinousReverieKeyPressed[ GetPlayerId( A.p ) ] ) then
        call SetUnitTimeScale( A.caster, 1.00 )
        call SetSpecialEffectTimeScale( A.e, 1.00 )
        call SetUnitStunned( A.caster, false )
        
        call SetUnitAnimationOffsetPercent( A.caster, 0.15 )
        
        set x = GetUnitX( A.caster )
        set y = GetUnitY( A.caster )
        
        set A.radius = A.radius * ( 0.50 + 0.50 * ( 1.00 - A.time / 1.50 ) )
        
        call GroupEnumUnitsInRange( TempGroup, x, y, A.radius + 200.00, null )
        
        loop
            set u = FirstOfGroup( TempGroup )
            exitwhen u == null
            call GroupRemoveUnit( TempGroup, u )
            
            if IsUnitInRangeXY( u, x, y, A.radius ) then
                if UnitAlive( u ) and IsUnitEnemy( u, A.p ) then
                    set t = CreateTimer( )
                    set S = DiscardingS.create( )
                    
                    set S.target = u
                        
                    set S.v = vector.create( GetUnitX( u ) - x, GetUnitY( u ) - y, 1.00 )
                    
                    if IsPointInSector( GetUnitX( u ), GetUnitY( u ), x, y, A.angle * bj_DEGTORAD, bj_PI * 0.50 ) then
                        call UnitDamageTarget( A.caster, u, A.damage * ( 1.00 - A.time / 1.50 ), false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SONIC, null )
                        call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Spells\\Undead\\OrbOfDeath\\OrbOfDeathMissile.mdl", u, "chest" ) )
                        call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Weapons\\AvengerMissile\\AvengerMissile.mdl", u, "chest" ) )
                        call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Spells\\Other\\Stampede\\StampedeMissileDeath.mdl", u, "chest" ) )
                        
                        set S.speed = S.v.length( )
                        set S.z = 60.00
                        
                        if S.speed > 475 then
                            set S.speed = 475.00
                        endif
                        
                        call S.v.normalize( )
                        
                        set S.v.z = 2.00 * ( 1.00 - S.speed / 475.00 )
                        
                        set S.speed = 2.00 + ( 475.00 - S.speed ) * 0.01
                    else
                        call UnitDamageTarget( A.caster, u, A.damage * ( 1.00 - A.time / 1.50 ) / 2.00, false, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_SONIC, null )
                        
                        call S.v.normalize( )
                        set S.z = 100.00
                        
                        set S.v.z = -0.50
                        
                        set S.speed = 2.00
                    endif
                    
                    call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Weapons\\AncientProtectorMissile\\AncientProtectorMissile.mdl", u, "chest" ) )
                    
                    call SetUnitHeight( u, S.z )
                        
                    call SetUnitStunned( u, true )
                    
                    call SaveInteger( H, GetHandleId( t ), 0, S )
                    call TimerStart( t, 0.01, true, function Discarding )
                endif
            endif
        endloop
        
        call Sound.playPoint( "Sound\\Buildings\\Death\\BuildingDeathLargeOrc.wav", x, y, 600.00, 3000.00, 100 )
        
        set bj_lastCreatedEffect = AddSpecialEffect( "rb7.mdl", x, y )
        call SetSpecialEffectFacing( bj_lastCreatedEffect, A.angle )
        call SetSpecialEffectZ( bj_lastCreatedEffect, GetSpecialEffectZ( bj_lastCreatedEffect ) + 65.00 )
        call SetSpecialEffectScale( bj_lastCreatedEffect, 7.00 - 2.00 * ( A.time / 1.50 ) )
        call SetSpecialEffectTimeScale( bj_lastCreatedEffect, 0.80 - 0.30 * ( A.time / 1.50 ) )
        call FadeEffect( bj_lastCreatedEffect, 0.0029 + 0.001 * ( A.time / 1.50 ) )
        
        set bj_lastCreatedEffect = AddSpecialEffect( "animeslashfinal.mdl", x, y )
        call SetSpecialEffectFacing( bj_lastCreatedEffect, A.angle )
        call SetSpecialEffectZ( bj_lastCreatedEffect, GetSpecialEffectZ( bj_lastCreatedEffect ) + 65.00 )
        call SetSpecialEffectScale( bj_lastCreatedEffect, 4.00 - 2.00 * ( A.time / 1.50 ) )
        call SetSpecialEffectTimeScale( bj_lastCreatedEffect, 1.00 - 0.50 * ( A.time / 1.50 ) )
        call SetSpecialEffectVertexColour( bj_lastCreatedEffect, 100, 100, 100, 255 )
        call DestroyEffect( bj_lastCreatedEffect )
        
        set bj_lastCreatedEffect = AddSpecialEffect( "rb3.mdl", x, y )
        call SetSpecialEffectFacing( bj_lastCreatedEffect, A.angle )
        call SetSpecialEffectZ( bj_lastCreatedEffect, GetSpecialEffectZ( bj_lastCreatedEffect ) + 65.00 )
        call SetSpecialEffectScale( bj_lastCreatedEffect, 6.00 - 2.00 * ( A.time / 1.50 ) )
        call SetSpecialEffectTimeScale( bj_lastCreatedEffect, 0.80 - 0.30 * ( A.time / 1.50 ) )
        call FadeEffect( bj_lastCreatedEffect, 0.0029 + 0.001 * ( A.time / 1.50 ) )
        
        set bj_lastCreatedEffect = AddSpecialEffect( "WindWeak(Thicker).mdl", x, y )
        call SetSpecialEffectFacing( bj_lastCreatedEffect, A.angle )
        call SetSpecialEffectScale( bj_lastCreatedEffect, 1.50 - 0.50 * ( A.time / 1.50 ) )
        call SetSpecialEffectTimeScale( bj_lastCreatedEffect, 0.50 + 0.50 * ( A.time / 1.50 ) )
        call DestroyEffect( bj_lastCreatedEffect )
        
        set bj_lastCreatedEffect = AddSpecialEffect( "WindCirclefaster.mdl", x, y )
        call SetSpecialEffectFacing( bj_lastCreatedEffect, A.angle )
        call SetSpecialEffectScale( bj_lastCreatedEffect, 1.00 - 0.50 * ( A.time / 1.50 ) )
        call SetSpecialEffectTimeScale( bj_lastCreatedEffect, 0.50 + 0.50 * ( A.time / 1.50 ) )
        call DestroyEffect( bj_lastCreatedEffect )
        
        set bj_lastCreatedEffect = AddSpecialEffect( "[tx][jn]dadizhiji-purple.mdl", x, y )
        call SetSpecialEffectFacing( bj_lastCreatedEffect, A.angle )
        call SetSpecialEffectScale( bj_lastCreatedEffect, 4.00 - 2.00 * ( A.time / 1.50 ) )
        call SetSpecialEffectTimeScale( bj_lastCreatedEffect, 0.50 + 0.50 * ( A.time / 1.50 ) )
        call DestroyEffect( bj_lastCreatedEffect )
        
        call DestroyEffect( A.e )
        call SetSpecialEffectVisible( A.e, false )
        
        call DestroyEffect( A.e1 )
        call SetSpecialEffectVisible( A.e1, false )
        
        set A.e = null
        set A.e1 = null
        
        if GetLocalPlayer( ) == A.p then
            call ShowFrame( CastBarBackdrop, false )
        endif
        
        set t = GetExpiredTimer( )
        
        call PauseTimer( t )
        call FlushChildHashtable( H, GetHandleId( t ) )
        call DestroyTimer( t )
        
        set t = null
        
        set A.caster = null
        call A.v.destroy( )
        call A.destroy( )
    endif
endfunction

private function SetAnim takes nothing returns nothing
    local timer t = GetExpiredTimer( )
    local RuinousReverieS A = LoadInteger( H, GetHandleId( t ), 0 )
    
    call SetUnitStunned( A.caster, true )
    call SetUnitTimeScale( A.caster, 0.10 )
    call SetUnitAnimationByIndex( A.caster, 3 )
    call QueueUnitAnimation( A.caster, "stand" )
    call SetSpecialEffectTimeScale( A.e, 0.10 )
    call SetSpecialEffectAnimationByIndex( A.e, 3 )
    
    call TimerStart( t, 0.01, true, function CheckTimeKey )
    
    set t = null
endfunction

function RuinousReverie_Actions takes nothing returns nothing
    local timer t = CreateTimer( )
    local RuinousReverieS A = RuinousReverieS.create( )
    local integer i
    
    set A.caster = GetTriggerUnit( )
    set A.p = GetOwningPlayer( A.caster )
    set A.time = 1.50
    set A.radius = 475.00
    set A.damage = ( GetUnitWeaponIntegerField( A.caster, UNIT_WEAPON_IF_ATTACK_DAMAGE_BASE, 0 ) + GetUnitWeaponIntegerField( A.caster, UNIT_WEAPON_IF_ATTACK_DAMAGE_BONUS, 0 ) ) * 15.00
    set A.e = AddSpecialEffect( "Bahisa.mdl", GetUnitX( A.caster ), GetUnitY( A.caster ) )
    
    call SetSpecialEffectAlpha( A.e, 0 )
    call SetSpecialEffectScale( A.e, 0.50 )
    
    set A.e1 = AddSpecialEffect( "Abilities\\Spells\\Human\\FlameStrike\\FlameStrikeTarget.mdl", GetUnitX( A.caster ), GetUnitY( A.caster ) )
    call SetSpecialEffectTimeScale( A.e1, 5.00 )
    
    if GetLocalPlayer( ) == A.p then
        call SetFrameText( CastBarText, "0%" )
        call SetFrameTextColour( CastBarText, ConvertColour( 255, 55, 255, 255 ) )
        call SetFrameSize( CastBar, 0.001, 0.02 )
        call ShowFrame( CastBarBackdrop, true )
    endif
    
    set i = GetPlayerId( A.p )
    
    set RuinousReverieKeyPressed[i] = true
    
    set A.v = vector.create( PlayerMouseWorldX[i] - GetUnitX( A.caster ), PlayerMouseWorldY[i] - GetUnitY( A.caster ), 1.00 )
    call A.v.normalize( )
    
    set A.angle = Atan2( A.v.y, A.v.x ) * bj_RADTODEG
    
    call SetUnitFacing( A.caster, A.angle )
    call SetSpecialEffectFacing( A.e, A.angle )
    
    call SaveInteger( H, GetHandleId( t ), 0, A )
    call TimerStart( t, 0.00, false, function SetAnim )
    
    set t = null
endfunction

private function OnInit takes nothing returns nothing
    set CastBarBackdrop = CreateFrameByType( "BACKDROP", "CastBarBackdrop", GetOriginFrame( ORIGIN_FRAME_GAME_UI, 0 ), "", 0 )
    
    call SetFrameSize( CastBarBackdrop, 0.20, 0.02 )
    call SetFrameTexture( CastBarBackdrop, "UI\\Feedback\\Cooldown\\cooldown.blp", 0, false )
    call SetFrameAbsolutePoint( CastBarBackdrop, FRAMEPOINT_CENTER, 0.40, 0.17 )
    
    set CastBar = CreateFrameByType( "BACKDROP", "CastBar", CastBarBackdrop, "", 0 )
    
    call SetFrameTexture( CastBar, "UI\\Feedback\\HPBarConsole\\human-statbar-color2.blp", 0, false )
    call SetFrameRelativePoint( CastBar, FRAMEPOINT_LEFT, CastBarBackdrop, FRAMEPOINT_LEFT, 0.00, 0.00 )
    
    set CastBarText = CreateFrameByType( "TEXT", "CastBarText", CastBarBackdrop, "", 0 )
    
    call SetFrameRelativePoint( CastBarText, FRAMEPOINT_CENTER, CastBarBackdrop, FRAMEPOINT_CENTER, 0.00, 0.00 )
    
    set CastBarBorder = CreateFrameByType( "BACKDROP", "CastBarBorder", CastBar, "", 0 )
    
    call SetFrameTexture( CastBarBorder, "UI\\Feedback\\XpBar\\human-xpbar-border.blp", 0, false )
    call SetFrameRelativePoint( CastBarBorder, FRAMEPOINT_TOPLEFT, CastBarBackdrop, FRAMEPOINT_TOPLEFT, 0.00, 0.00 )
    call SetFrameRelativePoint( CastBarBorder, FRAMEPOINT_BOTTOMRIGHT, CastBarBackdrop, FRAMEPOINT_BOTTOMRIGHT, 0.00, 0.00 )

    call ShowFrame( CastBarBackdrop, false )
endfunction

//===========================================================================
function InitTrig_RuinousReverie takes nothing returns nothing
    local integer i = 0
    set gg_trg_RuinousReverie = CreateTrigger(  )
    
    loop
        call TriggerRegisterPlayerKeyEvent( gg_trg_RuinousReverie, Player( i ), ConvertOsKeyType( GetAbilityBaseIntegerFieldById( 'A003', ABILITY_IF_BUTTON_HOTKEY_NORMAL ) ), META_KEY_NONE, false )
        
        set i = i + 1
        exitwhen i >= bj_MAX_PLAYER_SLOTS
    endloop
    
    call TriggerAddAction( gg_trg_RuinousReverie, function RuinousReverie_Actions_2 )
endfunction
endlibrary

Demise
library DreamlessStepLib requires SoundLib
globals
    private constant group TempGroup = CreateGroup( )
endglobals

struct DemiseS
    unit caster
    player p
    
    effect array e[6]
    effect array target[100]
    
    vector array targetV[100]
    vector array v[6]
    vector last
    
    integer targetC
    
    real damage
    real time
    real angle
endstruct

private function Damage takes nothing returns nothing
    local DemiseS A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
    local unit u
    
    set A.last.x = A.last.x + 11.00 * Cos( A.angle )
    set A.last.y = A.last.y + 11.00 * Sin( A.angle )
    
    call GroupEnumUnitsInRange( TempGroup, A.last.x, A.last.y, 475.00 * ( 1.00 - A.time / 1.00 ) + 200.00, null )
        
    loop
        set u = FirstOfGroup( TempGroup )
        exitwhen u == null
        call GroupRemoveUnit( TempGroup, u )
            
        if IsUnitInRangeXY( u, A.last.x, A.last.y, 475.00 * ( 1.00 - A.time / 1.00 ) ) then
            if UnitAlive( u ) and IsUnitEnemy( u, A.p ) then
                call UnitDamageTarget( A.caster, u, A.damage, false, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_FIRE, null )
            endif
        endif
    endloop
    
    set A.time = A.time - 0.01
        
    if A.time <= 0.50 then
        call PauseTimer( GetExpiredTimer( ) )
        call FlushChildHashtable( H, GetHandleId( GetExpiredTimer( ) ) )
        call DestroyTimer( GetExpiredTimer( ) )
        
        call A.last.destroy( )
        
        set A.caster = null
        call A.destroy( )
    endif
endfunction

private function Move takes nothing returns nothing
    local DemiseS A = LoadInteger( H, GetHandleId( GetExpiredTimer( ) ), 0 )
    local integer k = 0
    local integer i
    local real array x
    local real array y
    local real array z
    local real a
    local real az
    local unit u
    
    loop
        set x[k] = A.v[k].x
        set y[k] = A.v[k].y
        set z[k] = A.v[k].z
        
        set k = k + 1
        exitwhen k >= 6
    endloop
    
    set k = 0
    
    loop
        set i = 0
        
        loop
            set x[i] = ( 1.00 - A.time ) * x[i] + A.time * x[i + 1]
            set y[i] = ( 1.00 - A.time ) * y[i] + A.time * y[i + 1]
            set z[i] = ( 1.00 - A.time ) * z[i] + A.time * z[i + 1]
            
            set i = i + 1
            exitwhen i > 6 - k
        endloop
        
        set k = k + 1
        exitwhen k >= 6 - 1
    endloop
    
    set i = A.targetC
    
    loop
        exitwhen i <= 0
        
        set a = SquareRoot( ( x[0] - A.targetV[i].x ) * ( x[0] - A.targetV[i].x ) + ( y[0] - A.targetV[i].y ) * ( y[0] - A.targetV[i].y ) + ( z[0] - A.targetV[i].z ) * ( z[0] - A.targetV[i].z ) ) //Atan2( y[0] - A.targetV[i].y, x[0] - A.targetV[i].x )
        //set az = Atan2( z[0] - A.targetV[i].z, MathDistanceBetweenPoints( x[0], A.targetV[i].x, y[0], A.targetV[i].y ) )
        if a == 0.00 then
            set a = 1.00
        endif
        
        set A.targetV[i].x = A.targetV[i].x + 10.00 * ( ( x[0] - A.targetV[i].x ) / a )//Cos( a ) * Cos( az )
        set A.targetV[i].y = A.targetV[i].y + 10.00 * ( ( y[0] - A.targetV[i].y ) / a )//Sin( a ) * Cos( az )
        set A.targetV[i].z = A.targetV[i].z + 10.00 * ( ( z[0] - A.targetV[i].z ) / a )// az
        
        call SetSpecialEffectPositionWithZ( A.target[i], A.targetV[i].x, A.targetV[i].y, A.targetV[i].z )
        //call SetSpecialEffectOrientation( A.target[i], a * bj_RADTODEG, az * bj_RADTODEG, 0.00 )
        
        set i = i - 1
    endloop
    
    set a = Atan2( y[0] - A.last.y, x[0] - A.last.x ) * bj_RADTODEG
    set az = Atan2( z[0] - A.last.z, MathDistanceBetweenPoints( x[0], A.last.x, y[0], A.last.y ) ) * bj_RADTODEG
    
    set i = 0
    
    loop
        call SetSpecialEffectPositionWithZ( A.e[i], x[0], y[0], z[0] )
        call SetSpecialEffectOrientation( A.e[i], a, az, 0.00 )
    
        set i = i + 1
        exitwhen i >= 6
    endloop
        
    set A.last.x = x[0]
    set A.last.y = y[0]
    set A.last.z = z[0]
    
    set A.time = A.time + 0.01 / 0.75
    
    if A.time >= 1.00 then
        call SetUnitTimeScale( A.caster, 1.00 )
        call SetUnitStunned( A.caster, false )
        
        set bj_lastCreatedEffect = AddSpecialEffect( "[tx][jn]dadizhiji-purple.mdl", x[0], y[0] )
        call SetSpecialEffectScale( bj_lastCreatedEffect, 2.00 )
        call DestroyEffect( bj_lastCreatedEffect )
        
        set bj_lastCreatedEffect = AddSpecialEffect( "WindWeak(Thicker).mdl", x[0], y[0] )
        call SetSpecialEffectFacing( bj_lastCreatedEffect, a )
        call SetSpecialEffectVertexColour( bj_lastCreatedEffect, 255, 100, 255, 200 )
        call DestroyEffect( bj_lastCreatedEffect )
        
        set bj_lastCreatedEffect = AddSpecialEffect( "WindCirclefaster.mdl", x[0], y[0] )
        call SetSpecialEffectFacing( bj_lastCreatedEffect, a )
        call SetSpecialEffectVertexColour( bj_lastCreatedEffect, 255, 100, 255, 200 )
        call DestroyEffect( bj_lastCreatedEffect )
        
        set bj_lastCreatedEffect = AddSpecialEffect( "Abilities\\Spells\\Undead\\DeathPact\\DeathPactTarget.mdl", x[0], y[0] )
        call SetSpecialEffectZ( bj_lastCreatedEffect, GetSpecialEffectZ( bj_lastCreatedEffect ) + 50.00 )
        call SetSpecialEffectTimeScale( bj_lastCreatedEffect, 5.00 )
        call SetSpecialEffectScale( bj_lastCreatedEffect, 2.00 )
        call SetSpecialEffectOrientation( bj_lastCreatedEffect, a, -90.00, 0.00 )
        call DestroyEffect( bj_lastCreatedEffect )
        
        set bj_lastCreatedEffect = AddSpecialEffect( "model (79).mdl", x[0], y[0] )
        call SetSpecialEffectFacing( bj_lastCreatedEffect, A.angle * bj_RADTODEG )
        call DestroyEffect( bj_lastCreatedEffect )
        
        call Sound.playPoint( "Abilities\\Spells\\Orc\\Shockwave\\Shockwave.wav", A.last.x, A.last.y, 600.00, 3000.00, 100 )
        
        call GroupEnumUnitsInRange( TempGroup, A.last.x, A.last.y, 400.00, null )
            
        loop
            set u = FirstOfGroup( TempGroup )
            exitwhen u == null
            call GroupRemoveUnit( TempGroup, u )
                
            if IsUnitInRangeXY( u, A.last.x, A.last.y, 200.00 ) then
                if UnitAlive( u ) and IsUnitEnemy( u, A.p ) then
                    call UnitDamageTarget( A.caster, u, A.damage * 10.00, false, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_FIRE, null )
                    call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Spells\\Undead\\OrbOfDeath\\OrbOfDeathMissile.mdl", u, "chest" ) )
                    call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Spells\\Undead\\OrbOfDeath\\AnnihilationMissile.mdl", u, "chest" ) )
                endif
            endif
        endloop
        
        set i = A.targetC
        
        loop
            exitwhen i <= 0
            
            call DestroyEffect( A.target[i] )
            set A.target[i] = null
            call A.targetV[i].destroy( )
            
            set i = i - 1
        endloop
        
        set k = 0
        
        loop
            call DestroyEffect( A.e[k] )
            set A.e[k] = null
            call A.v[k].destroy( )
            
            set k = k + 1
            exitwhen k >= 6
        endloop
        
        call TimerStart( GetExpiredTimer( ), 0.01, true, function Damage )
    endif
endfunction

private function SetAnim takes nothing returns nothing
    local timer t = GetExpiredTimer( )
    local DemiseS A = LoadInteger( H, GetHandleId( t ), 0 )
    
    call SetUnitStunned( A.caster, true )
    call SetUnitTimeScale( A.caster, 0.50 )
    call SetUnitAnimation( A.caster, "spell two" )
    call QueueUnitAnimation( A.caster, "stand" )
    
    call TimerStart( t, 0.01, true, function Move )
    
    set t = null
endfunction

function Demise_Actions takes nothing returns nothing
    local timer t = CreateTimer( )
    local DemiseS A = DemiseS.create( )
    local integer i
    local unit u
    
    set A.caster = GetTriggerUnit( )
    set A.p = GetOwningPlayer( A.caster )
    set A.time = 0.00
    
    set i = GetPlayerId( A.p )
    
    set A.v[0] = vector.create( GetUnitX( A.caster ), GetUnitY( A.caster ), 0.00 )
    set A.v[0].z = GetAxisZ( A.v[0].x, A.v[0].y )
    
    set A.damage = ( GetUnitWeaponIntegerField( A.caster, UNIT_WEAPON_IF_ATTACK_DAMAGE_BASE, 0 ) + GetUnitWeaponIntegerField( A.caster, UNIT_WEAPON_IF_ATTACK_DAMAGE_BONUS, 0 ) ) * 0.25
    set A.angle = Atan2( PlayerMouseWorldY[i] - A.v[0].y, PlayerMouseWorldX[i] - A.v[0].x )
    
    call SetUnitFacing( A.caster, A.angle * bj_RADTODEG )
    
    set A.v[1] = vector.create( A.v[0].x + 500.00 * Cos( A.angle - bj_PI * 0.50 ), A.v[0].y + 500.00 * Sin( A.angle - bj_PI * 0.50 ), A.v[0].z + 100.00 )
    set A.v[2] = vector.create( A.v[0].x + 800.00 * Cos( A.angle ), A.v[0].y + 800.00 * Sin( A.angle ), A.v[0].z + 200.00 )
    set A.v[3] = vector.create( A.v[0].x + 500.00 * Cos( A.angle + bj_PI * 0.50 ), A.v[0].y + 500.00 * Sin( A.angle + bj_PI * 0.50 ), A.v[0].z + 300.00 )
    set A.v[4] = vector.create( A.v[0].x - 200.00 * Cos( A.angle ), A.v[0].y - 200.00 * Sin( A.angle ), A.v[0].z + 800.00 )
    set A.v[5] = vector.create( A.v[0].x + 100.00 * Cos( A.angle ), A.v[0].y + 100.00 * Sin( A.angle ), 1.00 )
    
    set A.v[5].z = GetAxisZ( A.v[5].x, A.v[5].y )
    
    set A.last = vector.create( A.v[0].x, A.v[0].y, A.v[0].z )
    
    set A.e[0] = AddSpecialEffect( "Abilities\\Spells\\Undead\\OrbOfDeath\\OrbOfDeathMissile.mdl", A.last.x, A.last.y )
    set A.e[1] = AddSpecialEffect( "Abilities\\Spells\\Undead\\OrbOfDeath\\AnnihilationMissile.mdl", A.last.x, A.last.y )
    set A.e[2] = AddSpecialEffect( "Abilities\\Weapons\\AvengerMissile\\AvengerMissile.mdl", A.last.x, A.last.y )
    set A.e[3] = AddSpecialEffect( "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile.mdl", A.last.x, A.last.y )
    set A.e[4] = AddSpecialEffect( "Astral_Fire.mdl", A.last.x, A.last.y )
    set A.e[5] = AddSpecialEffect( "Astral_Black_Bolt.mdl", A.last.x, A.last.y )
    
    set A.targetC = 0
    
    call GroupEnumUnitsInRange( TempGroup, A.v[0].x, A.v[0].y, 700.00, null )
        
    loop
        set u = FirstOfGroup( TempGroup )
        exitwhen u == null
        call GroupRemoveUnit( TempGroup, u )
            
        if IsUnitInRangeXY( u, A.v[0].x, A.v[0].y, 500.00 ) then
            if UnitAlive( u ) and IsUnitEnemy( u, A.p ) then
                set A.targetC = A.targetC + 1
                set A.targetV[A.targetC] = vector.create( GetUnitX( u ), GetUnitY( u ), 1.00 )
                
                set A.targetV[A.targetC].z = GetAxisZ( A.targetV[A.targetC].x, A.targetV[A.targetC].y ) + GetUnitFlyHeight( u )
                
                set A.target[A.targetC] = AddSpecialEffect( "Abilities\\Spells\\Undead\\DevourMagic\\DevourMagicBirthMissile.mdl", A.targetV[A.targetC].x, A.targetV[A.targetC].y )
                call SetSpecialEffectZ( A.target[A.targetC], A.targetV[A.targetC].z )
                
                if A.targetC >= 99 then
                    call GroupClear( TempGroup )
                endif
            endif
        endif
    endloop
    
    set A.damage = A.damage + 0.50 * A.targetC
    
    call SaveInteger( H, GetHandleId( t ), 0, A )
    call TimerStart( t, 0.00, false, function SetAnim )
    
    set t = null
endfunction
endlibrary

//===========================================================================
//function InitTrig_Demise takes nothing returns nothing
    //set gg_trg_Demise = CreateTrigger(  )
//endfunction


На спеллпак вдохновила модель от Anime Chan, используемая в качестве героя. Все способности сделаны через QuickCast (активация без использования ЛКМ)
`
ОЖИДАНИЕ РЕКЛАМЫ...
28
На вешку хотелось бы ещё накинуть вампиризма, потому что я этого героя более как воина/танка позиционирую
Ну и в рассекающем вихре вместо TriggerSleepAction таймер надо было бы тыкнуть, мне в принципе это пришлось заюзать из-за проблем с BackSwing (и какой там ещё один второй параметр времени каста абилок). Типа если 0.000 стоит, то всё работает как надо, но другие спеллы рискуют попасть под двойной каст внутри друг друга, если выставить 0.001, то недочёта с другими спеллами не будет, но отпускание клавиши некорректно срабатывает. Возможно стоило поиграться с другими событиями каста для решения проблемы
37
Forever 7th Capital - Eternal City
Годно
Ответы (1)
28
Anime Chan, о, точно, спасибо за название, надо будет его тыкнуть при следующем редактировании ресурса
Заодно пойду посмотрю какие в игре у нее способности и что это вообще за игра)
Этот комментарий удален
22
Это просто афигенно. Не думал сделать полноценную Аниме Арену на UjApi?
Загруженные файлы
Ответы (1)
28
Таренас, конечно думал и хотел, в особенности орпг, но у меня попросту нет комплектации для создания аниме карты, поэтому балую своё желание такими спеллпаками
Многих индивидуумов, к сожалению, очень триггерит совмещение стандарта и аниме, что напрочь убивает желание что-то делать (мне в своё время нравилась The World RPG). Иногда я просто мечтаю, чтобы мне было пофиг на их мнение, ибо я играл во всё подряд и меня не парило что тут откуда-то аниме модель. Хотя и таких людей понять могу, ибо видеть губку боба в любой не рофельной карте было бы не комильфо
Этот комментарий удален
Чтобы оставить комментарий, пожалуйста, войдите на сайт.