Добавлен , опубликован
Способ реализации:
Версия Warcraft:

Описание

Способность цепной молнии с плавным сгасанием эффекта молнии.
Используется vJass (только ради удобного scope).
Если где-то обнаружена ошибка / лишний код / недостающий код / не правильный код - просьба доложить в комментарии об этом!
MUI

Видео

Код

// Шапка карты (нестандартный код карты)
globals
    hashtable HT = InitHashtable( )
    key k_caster
    key k_target
    key k_group
    key k_lightning
    key k_alpha
endglobals

native UnitAlive takes unit id returns boolean
// Конец шапки карты (нестандартного кода карты)

scope ChainLightning initializer Init
    globals
        private constant integer ID = 'A001' // Айди способности
        private constant real PERIOD = 0.1 // Период поиска
        
        private constant real RADIUS = 600.0 // Радиус поиска
        private constant real DAMAGE = 30.0 // Урон
        
        private constant real LIFE_TIME = 0.3 // Время жизни молнии
        private constant real EXTINCTION_TIME = 0.3 // Время сгасания молнии
    endglobals
    
    private function Extinction takes nothing returns nothing
        local timer tmr = GetExpiredTimer( )
        local integer id = GetHandleId( tmr )
        local real alpha = LoadReal( HT, id, k_alpha ) - 1.0 / ( EXTINCTION_TIME / 0.02 )
        
        call SaveReal( HT, id, k_alpha, alpha )
        call SetLightningColor( LoadLightningHandle( HT, id, k_lightning ), 1.0, 1.0, 1.0, alpha )
        
        if alpha <= 0 then
            call DestroyLightning( LoadLightningHandle( HT, id, k_lightning ) )
            call FlushChildHashtable( HT, id )
            
            call PauseTimer( tmr )
            call DestroyTimer( tmr )
        endif
        
        set tmr = null
    endfunction
    
    private function Remove takes nothing returns nothing
        local timer tmr = GetExpiredTimer( )
        local integer id = GetHandleId( tmr )
        
        call SaveReal( HT, id, k_alpha, 1.0 )
        call TimerStart( tmr, 0.02, true, function Extinction )
        
        set tmr = null
    endfunction

    private function Timer takes nothing returns nothing
        local timer tmr = GetExpiredTimer( )
        local integer id = GetHandleId( tmr )
        
        local unit caster = LoadUnitHandle( HT, id, k_caster )
        local unit target = LoadUnitHandle( HT, id, k_target )
        local group hittedGroup = LoadGroupHandle( HT, id, k_group )
        
        local real targetX = GetUnitX( target )
        local real targetY = GetUnitY( target )
        
        local group g = CreateGroup( )
        local unit u = null
        local timer t = null
        
        call GroupEnumUnitsInRange( g, targetX, targetY, RADIUS + 200., null )
        
        loop
            set u = NearestUnitInGroup( g, targetX, targetY )
            exitwhen u == null
            
            if IsUnitInRangeXY( u, targetX, targetY, RADIUS ) and not IsUnitInGroup( u, hittedGroup ) then
                if UnitAlive( u ) and IsUnitEnemy( u, GetOwningPlayer( caster ) ) and not IsUnitType( u, UNIT_TYPE_STRUCTURE ) then
                    call UnitDamageTarget( caster, u, DAMAGE, true, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_LIGHTNING, WEAPON_TYPE_WHOKNOWS )
                    call DestroyEffect( AddSpecialEffectTarget( "Abilities\\Weapons\\Bolt\\BoltImpact.mdl", u, "chest" ) )
                    
                    call GroupAddUnit( hittedGroup, u )
                    call SaveUnitHandle( HT, id, k_target, u )
                    
                    set t = CreateTimer( )
                    call SaveLightningHandle( HT, GetHandleId( t ), k_lightning, AddLightningEx( "CLSB", false, targetX, targetY, GetUnitFlyHeight( target ) + 70., GetUnitX( u ), GetUnitY( u ), GetUnitFlyHeight( u ) + 70. ) )
                    call TimerStart( t, LIFE_TIME, false, function Remove )
                    set t = null
                    
                    exitwhen true
                endif
            endif
            
            call GroupRemoveUnit( g, u )
        endloop
        
        if u == null then
            call GroupClear( hittedGroup )
            call DestroyGroup( hittedGroup )
            
            call PauseTimer( tmr )
            call DestroyTimer( tmr )
        else
            set u = null
        endif
        
        call GroupClear( g )
        call DestroyGroup( g )
        
        set tmr = null
        set caster = null
        set target = null
        set hittedGroup = null
        set g = null
    endfunction

    private function Actions takes nothing returns nothing
        local unit caster = GetSpellAbilityUnit( )
        local unit target = GetSpellTargetUnit( )
        
        local timer tmr = CreateTimer( )
        local integer id = GetHandleId( tmr )
        
        call SaveUnitHandle( HT, id, k_caster, caster )
        call SaveUnitHandle( HT, id, k_target, target )
        call SaveGroupHandle( HT, id, k_group, CreateGroup( ) )
        call TimerStart( tmr, PERIOD, true, function Timer )
        
        set tmr = CreateTimer( )
        call SaveLightningHandle( HT, GetHandleId( tmr ), k_lightning, AddLightningEx( "CLSB", false, GetUnitX( target ), GetUnitY( target ), GetUnitFlyHeight( target ) + 70., GetUnitX( caster ), GetUnitY( caster ), GetUnitFlyHeight( caster ) + 70. ) )
        call TimerStart( tmr, LIFE_TIME, false, function Remove )

        set caster = null
        set target = null
        set tmr = null
    endfunction

    private function Conditions takes nothing returns nothing
        if GetSpellAbilityId( ) == ID then
            call Actions( )
        endif
    endfunction

    private function Init takes nothing returns nothing
        local trigger t = CreateTrigger( )
        local integer i = 0

        loop
            call TriggerRegisterPlayerUnitEvent( t, Player( i ), EVENT_PLAYER_UNIT_SPELL_EFFECT, null )
            set i = i + 1
            exitwhen i >= 16
        endloop
        
        call TriggerAddAction( t, function Conditions )
        set t = null
        
        call FogEnable( false )
        call FogMaskEnable( false )
    endfunction
endscope

Требования

`
ОЖИДАНИЕ РЕКЛАМЫ...
30
Если ты используешь VJASS, то не нужно выносить код в шапку карты. Компилятор сам это сделает. И я не вижу в коде ресурса реализации NearestUnitInGroup.
10
Я чтото подобное через ГПТ делал на удивление работает...
26
А в старкрафте такое легко можно сделать только используя данные)))
И более настраиваемо
В данном примере она по мимо цепной молнии ещё и раздваивается от каждой цели на две
Чтобы оставить комментарий, пожалуйста, войдите на сайт.