Добавлен , опубликован
Решил перенести способность Исазама тёмная стая на Wurst, чтобы продемонстрировать насколько проще и короче можно сделать. Скорее всего, можно было упростить ещё больше, но даже в таком варианте разница в 82 строки достаточно внушительна.
Оригинальный код
function CarroinSwarm_Move takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer id = GetHandleId(t)
    local real time = LoadReal(H, id, 'time') - 0.02
    local integer stop = LoadInteger(H, id, 'stop')
    local unit caster = LoadUnitHandle(H, id, 'cast')
    local unit casw = LoadUnitHandle(H, id, 'CaSw')
    local real x0 = GetUnitX(casw)
    local real y0 = GetUnitY(casw)
    local real x1 = LoadReal(H, id, 'EndX')
    local real y1 = LoadReal(H, id, 'EndY')
    local real d = SquareRoot( (x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0) )
    local real a = bj_RADTODEG * Atan2(y1 - y0, x1 - x0)
    local group g = CreateGroup()
    local unit target
    local item test
    
    if GetUnitCurrentOrder(caster) != OrderId("AImove") and time > 0.0 then
        call PauseTimer(t)
        call DestroyTimer(t)
        call FlushChildHashtable(H, id)
        call RemoveUnit(casw)
    endif
    
    call SaveReal(H, id, 'time', time)
    
    if time == 0.0 then
        call ShowUnit(casw, true)
        call ShowUnit(caster, false)
        call PauseUnit(caster, true)
        call UnitRemoveAbility(casw, 'Aloc')
        call UnitAddAbility(casw, 'Aloc')
    endif
    
    if time < 0.0 then
        if d < 11.0 then
            call PauseTimer(t)
            call DestroyTimer(t)
            call FlushChildHashtable(H, id)
            call RemoveUnit(casw)
            call ShowUnit(caster, true)
            call PauseUnit(caster, false)
            call SetUnitPosition(caster, x0, y0)
            call SelectUnit(caster, true)
            set IsazamHorror = IsazamHorror + 5
            call AddHorrorEffect()
        else
            if stop == 0 then
                call SetUnitX(casw, x0 + 10.0 * Cos(bj_DEGTORAD * a))
                call SetUnitY(casw, y0 + 10.0 * Sin(bj_DEGTORAD * a))
                call SetUnitFacing(casw, a)
            else
                set test = CreateItem('spsh', x0 + 10.0 * Cos(bj_DEGTORAD * a), y0 + 10.0 * Sin(bj_DEGTORAD * a))
                call SetItemPosition(test, x0 + 10.0 * Cos(bj_DEGTORAD * a), y0 + 10.0 * Sin(bj_DEGTORAD * a))
                
                if GetItemX(test) == x0 + 10.0 * Cos(bj_DEGTORAD * a) and GetItemY(test) == y0 + 10.0 * Sin(bj_DEGTORAD * a) then
                    call SetUnitX(casw, x0 + 10.0 * Cos(bj_DEGTORAD * a))
                    call SetUnitY(casw, y0 + 10.0 * Sin(bj_DEGTORAD * a))
                    call SetUnitFacing(casw, a)
                else
                    call PauseTimer(t)
                    call DestroyTimer(t)
                    call FlushChildHashtable(H, id)
                    call RemoveUnit(casw)
                    call ShowUnit(caster, true)
                    call PauseUnit(caster, false)
                    call SetUnitPosition(caster, x0, y0)
                    call SelectUnit(caster, true)
                    set IsazamHorror = IsazamHorror + 5
                    call AddHorrorEffect()
                endif
                
                call RemoveItem(test)
            endif
        endif
    endif
    
    call SaveUnitHandle(H, 'Unit', 'Unit', caster)
    call GroupEnumUnitsInRange(g, x0, y0, 100.0, function Enemy)
    
        loop
            set target = FirstOfGroup(g)
        exitwhen target == null
            call UnitDamageTarget(caster, target, 5.0 * GetUnitAbilityLevel(caster, 'A00B'), true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS )
            call GroupRemoveUnit(g, target)
        endloop
        
    call GroupClear(g)
    call DestroyGroup(g)
    
    set t = null
    set caster = null
    set casw = null
    set g = null
    set target = null
    set test = null
endfunction

function Trig_CarroinSwarm_Actions takes nothing returns nothing
    local unit Caster = GetTriggerUnit()
    local real x0 = GetUnitX(Caster)
    local real y0 = GetUnitY(Caster)
    local real x1 = GetSpellTargetX()
    local real y1 = GetSpellTargetY()
    local item test = CreateItem('spsh', x1, y1)
    local unit CaSw = CreateUnit(GetOwningPlayer(Caster), 'u007', x0, y0, GetUnitFacing(Caster))
    local timer t = CreateTimer()
    local integer id = GetHandleId(t)
    
    call SetItemPosition(test, x1, y1)
    
    if GetItemX(test) == x1 and GetItemY(test) == y1 then
        call SaveInteger(H, id, 'stop', 0)
    else
        call SaveInteger(H, id, 'stop', 1)
    endif
    
    if IsTerrainPathable(x1, y1, PATHING_TYPE_WALKABILITY) == true then
        call SaveInteger(H, id, 'stop', 1)
    endif
    
    call ShowUnit(CaSw, false)
    
    call TimerStart(t, 0.02, true, function CarroinSwarm_Move)
    call SaveReal(H, id, 'time', 1.0)
    call SaveUnitHandle(H, id, 'cast', Caster)
    call SaveUnitHandle(H, id, 'CaSw', CaSw)
    call SaveReal(H, id, 'EndX', x1)
    call SaveReal(H, id, 'EndY', y1)
    
    call RemoveItem(test)
    
    set IsazamHorror = IsazamHorror + 5
    
    set Caster = null
    set test = null
    set CaSw = null
    set t = null
endfunction

function Trig_CarroinSwarm_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A00B'
endfunction

//===========================================================================
function InitTrig_CarroinSwarm takes nothing returns nothing
    set gg_trg_CarroinSwarm = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_CarroinSwarm, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_CarroinSwarm, Condition( function Trig_CarroinSwarm_Conditions ) )
    call TriggerAddAction( gg_trg_CarroinSwarm, function Trig_CarroinSwarm_Actions )
endfunction
Код на Wurst Script
init
    registerPlayerUnitEvent(EVENT_PLAYER_UNIT_SPELL_EFFECT) ->
        let caster = GetTriggerUnit()
        if caster.getTypeId() == ISAZAM_ID and GetSpellAbilityId() == CARRION_SWARM_ID
            let x1 = GetSpellTargetX()
            let y1 = GetSpellTargetY()
            let t0 = CreateItem('spsh', x1, y1)
            let _cs_ = createUnit(caster.getOwner(), CARRION_SWARM_DUMMY_ID, caster.getPos(), caster.getFacingAngle())

            bool _stop_
            real _time_ = 1.

            t0.setPos( vec2(x1, y1) )

            if t0.getX() == x1 and t0.getY() == y1
                _stop_ = false
            else
                _stop_ = true

            t0.remove()

            if IsTerrainPathable(x1, y1, PATHING_TYPE_WALKABILITY) == true
                _stop_ = true

            _cs_.hide()

            doPeriodically(0.02) cb ->
                _time_ -= .02

                if caster.getCurrentOrder() != OrderId("AImove")
                    destroy cb
                    _cs_.remove()

                if _time_ == 0
                    _cs_.show()
                    caster.hide()
                    caster.pause()
                    _cs_.removeAbility('Aloc')
                    _cs_.addAbility('Aloc')

                if _time_ < 0.
                    let x0 = _cs_.getX()
                    let y0 = _cs_.getY()
                    let d = SquareRoot( (x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0) )
                    let a = bj_RADTODEG * Atan2(y1 - y0, x1 - x0)

                    if d < 11.
                        destroy cb
                        _cs_.remove()
                        caster.unpause()
                        caster.show()
                        caster.setPos(_cs_.getPos())
                        SelectUnit(caster, true)
                    else
                        if _stop_ == false
                            _cs_.setPos( vec2( x0 + 10.0 * Cos(bj_DEGTORAD * a), y0 + 10.0 * Sin(bj_DEGTORAD * a) ) )
                            SetUnitFacing(_cs_, a)
                        else
                            let t1 = CreateItem('spsh', x0 + 10.0 * Cos(bj_DEGTORAD * a), y0 + 10.0 * Sin(bj_DEGTORAD * a))
                            t1.setPos( vec2( x0 + 10.0 * Cos(bj_DEGTORAD * a), y0 + 10.0 * Sin(bj_DEGTORAD * a) ) )

                            if t1.getX() == x0 + 10.0 * Cos(bj_DEGTORAD * a) and t1.getY() == y0 + 10.0 * Sin(bj_DEGTORAD * a)
                                _cs_.setPos( vec2( x0 + 10.0 * Cos(bj_DEGTORAD * a), y0 + 10.0 * Sin(bj_DEGTORAD * a) ) )
                                SetUnitFacing(_cs_, a)
                            else
                                destroy cb
                                _cs_.remove()
                                caster.unpause()
                                caster.show()
                                caster.setPos(_cs_.getPos())
                                SelectUnit(caster, true)

                            t1.remove()

                            let g = CreateGroup()
                            g.enumUnitsInRange(_cs_.getPos(), 100.)

                            for u from g
                                if u.isEnemyNew(_cs_.getOwner())
                                    caster.damageTarget(u, 5. * caster.getAbilityLevel(CARRION_SWARM_ID), true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
                            
                            g.clear()
                            g.destr()
П.С. думаю это видно и так, но замечу, что код на Wurst пишется сверху вниз, в отличии от Jass
П.П.С. забыл сказать, что на Wurst нет "закрытия" функций, что если и прочего, вместо этого используется табуляция
`
ОЖИДАНИЕ РЕКЛАМЫ...