Добавлен , не публикуется
Способность guardian wisp'a Spirits из DotA в том виде в котором её реализовал IceFrog P.S выглядит как будто это делал не фрог...

Код способности

spirits jass code

function DamageAroundSpirit takes unit Source, unit Spirit returns nothing // Наносит урон вокруг дамми юнита, уничтожая последнего и создавая спецэффект.
    local group grp = CreateGroup( )
    
    set udg_TempUnit = Source
    set udg_TempReal = 25 * udg_TempInt
    set udg_TempUnit = Source
    set udg_TempDummy = CreateUnit( GetOwningPlayer( Source ), 'e00E', GetUnitX( Spirit ), GetUnitY( Spirit ), 0 )
    
    call GroupEnumUnitsInRange( grp, GetUnitX( Spirit ), GetUnitY( Spirit ), 325, Condition( function CJ1 ) )
    call UnitAddPermanentAbility( udg_TempDummy, 'A1TO' )
    
    call ForGroup( grp, function DamageNoMecEnumUnit )
    
    call DestroyEffect( AddSpecialEffect( "Abilities\\Spells\\Undead\\FreezingBreath\\FreezingBreathMissile.mdl", GetUnitX( Spirit ), GetUnitY( Spirit ) ) )
    call KillUnit( loc_unit02 )
    call DestroyGroup( grp ) // в оригинале используется отдельная функция из системы создания и удаления груп.
    
    call UnitApplyTimedLife( CreateUnit( GetOwningPlayer( Source ), 'o00Q', GetUnitX( Spirit), GetUnitY( Spirit ), 0 ), 'BTLF', 2 )
    
    set grp = null
endfunction

function DamageToCreeps takes nothing returns nothing // наносит небольшой урон крипам, не взрывая духов.
    local integer id = udg_CountInteger
    local unit Enemy = GetEnumUnit( )
    local integer key = 662 - 1 + id
    local real Remaning = ( LoadReal( udg__htb_data, ( GetHandleId( Enemy ) ), ( key ) ) )
    local real Elapsed = ( TimerGetElapsed( timer001 ) )
    
    if Remaning < Elapsed then
        call SaveReal( udg__htb_data, ( GetHandleId( Enemy ) ), ( key ), ( ( Elapsed + 2 ) * 1.0 ) )
        
        if IsUnitType( GetEnumUnit( ), UNIT_TYPE_STRUCTURE ) == false then
            call P6I( udg_TempUnit, Enemy, 1, 2 + 6 * udg_TempInt ) // функция нанесения урона
        else
        endif
    endif
    
    set Enemy = null
endfunction

function Timer_Spiris_Movement_Expires takes nothing returns boolean // перемещяет духов вокруг.
    // 'A24B' Oscillate Out - Основан на 'Aroa' Roar RU Рев( не сбивает текущий приказ )
    // 'A24A' Oscillate In - Основан на 'ANbr' Battle Roar RU Рев( не сбивает текущий приказ )
    local trigger TempTrigger = GetTriggeringTrigger( )
    local integer id = GetHandleId( TempTrigger )
    local unit CasterWisp = ( LoadUnitHandle( udg__htb_data, ( id ), ( 2 ) ) )
    local unit MiniWispA = ( LoadUnitHandle( udg__htb_data, ( id ), ( 393 ) ) )
    local unit MiniWispB = ( LoadUnitHandle( udg__htb_data, ( id ), ( 394 ) ) )
    local unit MiniWispC = ( LoadUnitHandle( udg__htb_data, ( id ), ( 395 ) ) )
    local unit MiniWispD = ( LoadUnitHandle( udg__htb_data, ( id ), ( 396 ) ) )
    local unit MiniWispE = ( LoadUnitHandle( udg__htb_data, ( id ), ( 397 ) ) )
    local real SpiritX
    local real SpiritY
    local real Ang
    local real Dist= ( LoadReal( udg__htb_data, ( id ), ( 138 ) ) )
    local real WispX = GetUnitX( CasterWisp )
    local real WispY = GetUnitY( CasterWisp )
    local real Turn
    local integer loc_integer02 = GetTriggerEvalCount( TempTrigger )
    local real Position
    local group grp
    local integer SpiritCount = 0
    local real TurnRate = 2.25
    local real PositionRate
  
    if IsUnitDead( MiniWispA ) == false then
        set SpiritCount = SpiritCount + 1
    endif
    if IsUnitDead( MiniWispB ) == false then
        set SpiritCount = SpiritCount + 1
    endif
    if IsUnitDead( MiniWispC ) == false then
        set SpiritCount = SpiritCount + 1
    endif
    if IsUnitDead( MiniWispD ) == false then
        set SpiritCount = SpiritCount + 1
    endif
    if IsUnitDead( MiniWispE ) == false then
        set SpiritCount = SpiritCount + 1
    endif
    
    if SpiritCount == 5 then
        set TurnRate = 2.25
    elseif SpiritCount == 4 then
        set TurnRate = 2.1
    elseif SpiritCount == 3 then
        set TurnRate = 1.95
    elseif SpiritCount == 2 then
        set TurnRate = 1.8
    elseif SpiritCount == 1 then
        set TurnRate = 1.65
    endif
    
    set Turn = -1 * 360 * 0.02 / TurnRate
    set PositionRate = ( LoadReal( udg__htb_data, ( id ), ( 137 ) ) ) + Turn
    call SaveReal( udg__htb_data, ( id ), ( 137 ), ( ( PositionRate ) * 1.0 ) )
    set udg_TempInt = GetUnitAbilityLevel( CasterWisp, 'A1T8' )
    set udg_TempUnit = CasterWisp
    
    if loc_integer02 == 50 then
        call ShowUnit( MiniWispB, true )
        call SaveBoolean( udg__htb_data, ( id ), ( 512 ), ( true ) )
        call UnitAddPermanentAbility( MiniWispB, 'Aloc' )
    endif
    if loc_integer02 == 100 then
        call ShowUnit( MiniWispC, true )
        call SaveBoolean( udg__htb_data, ( id ), ( 513 ), ( true ) )
        call UnitAddPermanentAbility( MiniWispC, 'Aloc' )
    endif
    if loc_integer02 == 150 then
        call ShowUnit( MiniWispD, true )
        call SaveBoolean( udg__htb_data, ( id ), ( 514 ), ( true ) )
        call UnitAddPermanentAbility( MiniWispD, 'Aloc' )
    endif
    if loc_integer02 == 200 then
        call ShowUnit( MiniWispE, true )
        call SaveBoolean( udg__htb_data, ( id ), ( 515 ), ( true ) )
        call UnitAddPermanentAbility( MiniWispE, 'Aloc' )
    endif
    
    if GetTriggerEventId( ) == EVENT_UNIT_SPELL_EFFECT then
        if GetSpellAbilityId( ) == 'A24A' then
            if ( LoadBoolean( udg__htb_data, ( id ), ( 655 ) ) ) == true then
                call SaveBoolean( udg__htb_data, ( id ), ( 655 ), ( false ) )
                call SaveBoolean( udg__htb_data, ( id ), ( 656 ), ( false ) )
            else
                call SaveBoolean( udg__htb_data, ( id ), ( 655 ), ( true ) )
                call SaveBoolean( udg__htb_data, ( id ), ( 656 ), ( false ) )
            endif
        elseif GetSpellAbilityId( ) == 'A24B' then
            if ( LoadBoolean( udg__htb_data, ( id ), ( 656 ) ) ) == true then
                call SaveBoolean( udg__htb_data, ( id ), ( 655 ), ( false ) )
                call SaveBoolean( udg__htb_data, ( id ), ( 656 ), ( false ) )
            else
                call SaveBoolean( udg__htb_data, ( id ), ( 655 ), ( false ) )
                call SaveBoolean( udg__htb_data, ( id ), ( 656 ), ( true ) )
            endif
        endif
    endif
    
    if ( LoadBoolean( udg__htb_data, ( id ), ( 655 ) ) ) then
        set Dist= RMaxBJ( Dist- 5, 100 )
        call SaveReal( udg__htb_data, ( id ), ( 138 ), ( ( Dist) * 1.0 ) )
    elseif ( LoadBoolean( udg__htb_data, ( id ), ( 656 ) ) ) then
        set Dist= RMinBJ( Dist+ 5, 875 )
        call SaveReal( udg__htb_data, ( id ), ( 138 ), ( ( Dist) * 1.0 ) )
    endif
    
    if GetTriggerEventId( ) == EVENT_UNIT_DEATH or loc_integer02 == 950 or( IsUnitDead( MiniWispA )and IsUnitDead( MiniWispB )and IsUnitDead( MiniWispC )and IsUnitDead( MiniWispD )and IsUnitDead( MiniWispE ) )or( loc_integer02 > 1 and GetTriggerEventId( ) == EVENT_UNIT_SPELL_EFFECT and GetSpellAbilityId( ) == 'A1T8' ) then
        if GetTriggerEventId( ) != EVENT_UNIT_SPELL_EFFECT then
            call UnitRemoveAbility( CasterWisp, 'A24A' )
            call UnitRemoveAbility( CasterWisp, 'A24B' )
        endif
        
        call FlushChildHashtable( udg__htb_data, ( id ) )
        call DestroyTrigger( TempTrigger )
        
        if IsUnitDead( MiniWispA ) == false then
            call DamageAroundSpirit( CasterWisp, MiniWispA )
        endif
        if IsUnitDead( MiniWispB ) == false then
            call DamageAroundSpirit( CasterWisp, MiniWispB )
        endif
        if IsUnitDead( MiniWispC ) == false then
            call DamageAroundSpirit( CasterWisp, MiniWispC )
        endif
        if IsUnitDead( MiniWispD ) == false then
            call DamageAroundSpirit( CasterWisp, MiniWispD )
        endif
        if IsUnitDead( MiniWispE ) == false then
            call DamageAroundSpirit( CasterWisp, MiniWispE )
        endif
    else
        set grp = CreateGroup( )
        
        if IsUnitDead( MiniWispA ) == false and( LoadBoolean( udg__htb_data, ( id ), ( 511 ) ) ) then
            set Position = 360 * 5 / 5.0
            set Ang = Position + PositionRate
            set SpiritX = CheckBoundX( WispX + Dist* Cos( Ang * bj_DEGTORAD ) )
            set SpiritY = CheckBoundY( WispY + Dist* Sin( Ang * bj_DEGTORAD ) )
            call SetUnitX( MiniWispA, SpiritX )
            call SetUnitY( MiniWispA, SpiritY )
            set udg_TempUnit = CasterWisp
            call GroupEnumUnitsInRange( grp, SpiritX, SpiritY, 95, Condition( function D21 ) )
            
            if FirstOfGroup( grp ) != null then
                call DamageAroundSpirit( CasterWisp, MiniWispA )
            endif
            
            call GroupClear( grp )
            set udg_TempDummy = MiniWispA
            set udg_CountInteger = 1
            set udg_TempUnit = CasterWisp
            call GroupEnumUnitsInRange( grp, SpiritX, SpiritY, 175, Condition( function CY1 ) )
            call ForGroup( grp, function DamageToCreeps )
            call GroupClear( grp )
        endif
        
        if IsUnitDead( MiniWispB ) == false and( LoadBoolean( udg__htb_data, ( id ), ( 512 ) ) ) then
            set Position = 360 * 4 / 5.0
            set Ang = Position + PositionRate
            set SpiritX = CheckBoundX( WispX + Dist* Cos( Ang * bj_DEGTORAD ) )
            set SpiritY = CheckBoundY( WispY + Dist* Sin( Ang * bj_DEGTORAD ) )
            call SetUnitX( MiniWispB, SpiritX )
            call SetUnitY( MiniWispB, SpiritY )
            set udg_TempUnit = CasterWisp
            call GroupEnumUnitsInRange( grp, SpiritX, SpiritY, 95, Condition( function D21 ) )
            
            if FirstOfGroup( grp ) != null then
                call DamageAroundSpirit( CasterWisp, MiniWispB )
            endif
            
            call GroupClear( grp )
            set udg_TempDummy = MiniWispB
            set udg_CountInteger = 2
            set udg_TempUnit = CasterWisp
            call GroupEnumUnitsInRange( grp, SpiritX, SpiritY, 175, Condition( function CY1 ) )
            call ForGroup( grp, function DamageToCreeps )
            call GroupClear( grp )
        endif
        
        if IsUnitDead( MiniWispC ) == false and( LoadBoolean( udg__htb_data, ( id ), ( 513 ) ) ) then
            set Position = 360 * 3 / 5.0
            set Ang = Position + PositionRate
            set SpiritX = CheckBoundX( WispX + Dist* Cos( Ang * bj_DEGTORAD ) )
            set SpiritY = CheckBoundY( WispY + Dist* Sin( Ang * bj_DEGTORAD ) )
            call SetUnitX( MiniWispC, SpiritX )
            call SetUnitY( MiniWispC, SpiritY )
            set udg_TempUnit = CasterWisp
            call GroupEnumUnitsInRange( grp, SpiritX, SpiritY, 95, Condition( function D21 ) )
            
            if FirstOfGroup( grp ) != null then
                call DamageAroundSpirit( CasterWisp, MiniWispC )
            endif
            
            call GroupClear( grp )
            set udg_TempDummy = MiniWispC
            set udg_CountInteger = 3
            set udg_TempUnit = CasterWisp
            call GroupEnumUnitsInRange( grp, SpiritX, SpiritY, 175, Condition( function CY1 ) )
            call ForGroup( grp, function DamageToCreeps )
            call GroupClear( grp )
        endif
        if IsUnitDead( MiniWispD ) == false and( LoadBoolean( udg__htb_data, ( id ), ( 514 ) ) ) then
            set Position = 360 * 2 / 5.0
            set Ang = Position + PositionRate
            set SpiritX = CheckBoundX( WispX + Dist* Cos( Ang * bj_DEGTORAD ) )
            set SpiritY = CheckBoundY( WispY + Dist* Sin( Ang * bj_DEGTORAD ) )
            call SetUnitX( MiniWispD, SpiritX )
            call SetUnitY( MiniWispD, SpiritY )
            set udg_TempUnit = CasterWisp
            call GroupEnumUnitsInRange( grp, SpiritX, SpiritY, 95, Condition( function D21 ) )
            
            if FirstOfGroup( grp ) != null then
                call DamageAroundSpirit( CasterWisp, MiniWispD )
            endif
            
            call GroupClear( grp )
            set udg_TempDummy = MiniWispD
            set udg_CountInteger = 4
            set udg_TempUnit = CasterWisp
            call GroupEnumUnitsInRange( grp, SpiritX, SpiritY, 175, Condition( function CY1 ) )
            call ForGroup( grp, function DamageToCreeps )
            call GroupClear( grp )
        endif
        
        if IsUnitDead( MiniWispE ) == false and( LoadBoolean( udg__htb_data, ( id ), ( 515 ) ) ) then
            set Position = 360 * 1 / 5.0
            set Ang = Position + PositionRate
            set SpiritX = CheckBoundX( WispX + Dist* Cos( Ang * bj_DEGTORAD ) )
            set SpiritY = CheckBoundY( WispY + Dist* Sin( Ang * bj_DEGTORAD ) )
            call SetUnitX( MiniWispE, SpiritX )
            call SetUnitY( MiniWispE, SpiritY )
            set udg_TempUnit = CasterWisp
            call GroupEnumUnitsInRange( grp, SpiritX, SpiritY, 95, Condition( function D21 ) )
            
            if FirstOfGroup( grp ) != null then
                call DamageAroundSpirit( CasterWisp, MiniWispE )
            endif
            
            call GroupClear( grp )
            set udg_TempDummy = MiniWispE
            set udg_CountInteger = 5
            set udg_TempUnit = CasterWisp
            call GroupEnumUnitsInRange( grp, SpiritX, SpiritY, 175, Condition( function CY1 ) )
            call ForGroup( grp, function DamageToCreeps )
            call GroupClear( grp )
        endif
        
        call NSI( grp )
    endif
  
    set TempTrigger = null
    set CasterWisp = null
    set MiniWispA = null
    set MiniWispB = null
    set MiniWispC = null
    set MiniWispD = null
    set MiniWispE = null
  
    return false
endfunction

function Trig_Wisp_Spirits_Actions takes nothing returns nothing // создает духов вокруг кастера
    // 'A24B' Oscillate Out - Основан на 'Aroa' Roar RU Рев( не сбивает текущий приказ )
    // 'A24A' Oscillate In - Основан на 'ANbr' Battle Roar RU Рев( не сбивает текущий приказ )
    local unit CasterWisp = GetTriggerUnit( )
    local trigger TempTrigger = CreateTrigger( )
    local integer id = GetHandleId( TempTrigger )
    local unit MiniWispA
    local unit MiniWispB
    local unit MiniWispC
    local unit MiniWispD
    local unit MiniWispE
    local real WispX
    local real WispY
  
    set WispX = GetUnitX( CasterWisp ) + 250 * Cos( bj_DEGTORAD * 360 * 5 / 5.0 * - 1.0 )
    set WispY = GetUnitY( CasterWisp ) + 250 * Sin( bj_DEGTORAD * 360 * 5 / 5.0 * - 1.0 )
    set MiniWispA = CreateUnit( GetOwningPlayer( CasterWisp ), 'h0CJ', WispX, WispY, 360 * 5 / 5.0 * - 1.0 )
  
    call UnitAddPermanentAbility( MiniWispA, 'Aloc' )
    set WispX = GetUnitX( CasterWisp ) + 250 * Cos( bj_DEGTORAD * 360 * 4 / 5.0 * - 1.0 )
    set WispY = GetUnitY( CasterWisp ) + 250 * Sin( bj_DEGTORAD * 360 * 4 / 5.0 * - 1.0 )
    set MiniWispB = CreateUnit( GetOwningPlayer( CasterWisp ), 'h0CJ', WispX, WispY, 360 * 4 / 5.0 * - 1.0 )
  
    call ShowUnit( MiniWispB, false )
    call SetUnitInvulnerable( MiniWispB, true )
    set WispX = GetUnitX( CasterWisp ) + 250 * Cos( bj_DEGTORAD * 360 * 3 / 5.0 * - 1.0 )
    set WispY = GetUnitY( CasterWisp ) + 250 * Sin( bj_DEGTORAD * 360 * 3 / 5.0 * - 1.0 )
    set MiniWispC = CreateUnit( GetOwningPlayer( CasterWisp ), 'h0CJ', WispX, WispY, 360 * 3 / 5.0 * - 1.0 )
  
    call ShowUnit( MiniWispC, false )
    call SetUnitInvulnerable( MiniWispB, true )
    set WispX = GetUnitX( CasterWisp ) + 250 * Cos( bj_DEGTORAD * 360 * 2 / 5.0 * - 1.0 )
    set WispY = GetUnitY( CasterWisp ) + 250 * Sin( bj_DEGTORAD * 360 * 2 / 5.0 * - 1.0 )
    set MiniWispD = CreateUnit( GetOwningPlayer( CasterWisp ), 'h0CJ', WispX, WispY, 360 * 2 / 5.0 * - 1.0 )
  
    call ShowUnit( MiniWispD, false )
    call SetUnitInvulnerable( MiniWispD, true )
    set WispX = GetUnitX( CasterWisp ) + 250 * Cos( bj_DEGTORAD * 360 * 1 / 5.0 * - 1.0 )
    set WispY = GetUnitY( CasterWisp ) + 250 * Sin( bj_DEGTORAD * 360 * 1 / 5.0 * - 1.0 )
    set MiniWispE = CreateUnit( GetOwningPlayer( CasterWisp ), 'h0CJ', WispX, WispY, 360 * 1 / 5.0 * - 1.0 )
    call ShowUnit( MiniWispE, false )
    call SetUnitInvulnerable( MiniWispE, true )
  
    call SaveUnitHandle( udg__htb_data, ( id ), ( 2 ), ( CasterWisp ) )
    call SaveUnitHandle( udg__htb_data, ( id ), ( 393 ), ( MiniWispA ) )
    call SaveUnitHandle( udg__htb_data, ( id ), ( 394 ), ( MiniWispB ) )
    call SaveUnitHandle( udg__htb_data, ( id ), ( 395 ), ( MiniWispC ) )
    call SaveUnitHandle( udg__htb_data, ( id ), ( 396 ), ( MiniWispD ) )
    call SaveUnitHandle( udg__htb_data, ( id ), ( 397 ), ( MiniWispE ) )
  
    call SaveBoolean( udg__htb_data, ( id ), ( 511 ), ( true ) )
    call SaveBoolean( udg__htb_data, ( id ), ( 512 ), ( false ) )
    call SaveBoolean( udg__htb_data, ( id ), ( 513 ), ( false ) )
    call SaveBoolean( udg__htb_data, ( id ), ( 514 ), ( false ) )
    call SaveBoolean( udg__htb_data, ( id ), ( 515 ), ( false ) )
    call SaveBoolean( udg__htb_data, ( id ), ( 655 ), ( false ) )
    call SaveBoolean( udg__htb_data, ( id ), ( 656 ), ( false ) )
  
    call SaveReal( udg__htb_data, ( id ), ( 138 ), ( ( 150 ) * 1.0 ) )
  
    call UnitAddPermanentAbility( CasterWisp, 'A24B' )
    call UnitAddPermanentAbility( CasterWisp, 'A24A' )
  
    call TriggerRegisterTimerEvent( TempTrigger, 0.02, true )
    call TriggerRegisterUnitEvent( TempTrigger, CasterWisp, EVENT_UNIT_DEATH )
    call TriggerRegisterUnitEvent( TempTrigger, CasterWisp, EVENT_UNIT_SPELL_EFFECT )
  
    call TriggerAddCondition( TempTrigger, Condition( function Timer_Spiris_Movement_Expires ) )
  
    set CasterWisp = null
    set TempTrigger = null
    set MiniWispA = null
    set MiniWispB = null
    set MiniWispC = null
    set MiniWispD = null
    set MiniWispE = null
endfunction

function Trig_Wisp_Spirits_Conditions takes nothing returns boolean // Проверка применена ли способность - 'A1T8'
    // 'A1T8' - Spirits (основано на 'AEfk' Fan of knifes - RU Веерный бросок)
    if GetSpellAbilityId( ) == 'A1T8' then
        call Trig_Wisp_Spirits_Actions( )
    endif
  
    return false
endfunction

function InitTrig_Wisp_Spirits takes nothing returns nothing // инициализация триггера, эта функция будет вызвана после старта карты
    local trigger TempTrigger = CreateTrigger( )
  
    call TriggerRegisterAnyUnitEventBJ( TempTrigger, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( TempTrigger, Condition( function Trig_Wisp_Spirits_Conditions ) )
  
    set TempTrigger = null
endfunction
Всякий мусор и вспомогательные функции

function CheckBoundX takes real BoundX returns real // проверка координаты Х, защита от перемещение за границы карты
  local real MaxBoundX=GetRectMinX(bj_mapInitialPlayableArea)+50
  if(BoundX<MaxBoundX)then
    return MaxBoundX
  endif
  set MaxBoundX=GetRectMaxX(bj_mapInitialPlayableArea)-50
  if(BoundX>MaxBoundX)then
    return MaxBoundX
  endif
  return BoundX
endfunction

function CheckBoundY takes real BoundY returns real // проверка координаты Y, защита от перемещение за границы карты
  local real MaxBoundY=GetRectMinY(bj_mapInitialPlayableArea)+50
  if(BoundY<MaxBoundY)then
    return MaxBoundY
  endif
  set MaxBoundY=GetRectMaxY(bj_mapInitialPlayableArea)-50
  if(BoundY>MaxBoundY)then
    return MaxBoundY
  endif
  return BoundY
endfunction

function IsUnitDead takes unit u returns boolean
    return IsUnitType( u, UNIT_TYPE_DEAD ) or GetUnitTypeId( u ) < 1
endfunction

function RKI takes unit loc_unit01 returns boolean // фильтр у фрога их как грязи
  return GetUnitAbilityLevel(loc_unit01,'A0S6')>0 or GetUnitAbilityLevel(loc_unit01,'A179')>0 or GetUnitAbilityLevel(loc_unit01,'ACmi')>0 or GetUnitAbilityLevel(loc_unit01,'A0SU')>0 or GetUnitAbilityLevel(loc_unit01,'B014')>0 or GetUnitAbilityLevel(loc_unit01,'A0H3')>0 or((LoadInteger(hashtable001,(GetHandleId(((loc_unit01)))),((4252))))==1)
endfunction

function D21 takes nothing returns boolean // фильтр у фрога их как грязи
  return RKI(GetFilterUnit())==false and(IsUnitType(GetFilterUnit(),UNIT_TYPE_HERO)==true and IsUnitEnemy(udg_TempUnit,GetOwningPlayer(GetFilterUnit()))==true and(GetUnitAbilityLevel(GetFilterUnit(),'A04R')==0 and IsUnitType(GetFilterUnit(),UNIT_TYPE_STRUCTURE)==false and IsUnitDead(GetFilterUnit())==false)and(IsUnitType(GetFilterUnit(),UNIT_TYPE_ANCIENT)==false or CI1(GetFilterUnit())))
endfunction

function CY1 takes nothing returns boolean // фильтр у фрога их как грязи
  return(IsUnitEnemy(udg_TempUnit,GetOwningPlayer(GetFilterUnit()))and(GetUnitAbilityLevel(GetFilterUnit(),'A04R')==0 and IsUnitDead(GetFilterUnit())==false)and(IsUnitType(GetFilterUnit(),UNIT_TYPE_ANCIENT)==false or IsUnitDead(GetFilterUnit())))and IsUnitType(GetFilterUnit(),UNIT_TYPE_HERO)==false
endfunction

function DamageNoMecEnumUnit takes nothing returns nothing // Почему фрог не внес эту проверку в фильтр нам неведомо, функция нанесения урона для групп
  if IsUnitType(GetEnumUnit(),UNIT_TYPE_STRUCTURE)==false then
    call P6I(unit390,GetEnumUnit(),1,udg_TempReal)
  else
  endif
endfunction

function UnitAddPermanentAbility takes unit whichUnit, integer abilityId returns nothing // не дает способностям пропадать при преобразованиях.
    call UnitAddAbility( whichUnit, abilityId )
    call UnitMakeAbilityPermanent( whichUnit, true, abilityId )
endfunction

Примечания

В этот раз без тест мапа , ну если кому дофига нужен сделайте сами, или хостаните доту в сингле.
Boolexpr я решил не восстанавливать имена фильтров, ибо их там для каждого ForGroup но с почти идеинтичным содержанием, если это так важно для вас пишите в коментариях.
В коде встречаются ошибки и недоработки, имейте это в виду если собираетесь использовать этот код!
Все претензии по качеству кода прошу писать IceFrog
Чтобы оставить комментарий, пожалуйста, войдите на сайт.