Сделал скилл на лучку
Посмотрите на предмет утечек =3
Можете брать, если понадобится
раскрыть
scope RedArcher initializer InitRedArcher

globals
trigger RedArcher
endglobals

function Q takes nothing returns nothing


endfunction

function WWW takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer h1 = GetHandleId(t)
    call PureDamageWithCrit(LoadUnitHandle(udg_GHT,h1,1),LoadUnitHandle(udg_GHT,h1,2),LoadReal(udg_GHT,h1,3), LoadReal(udg_GHT,h1,4),LoadReal(udg_GHT,h1,5), LoadReal(udg_GHT,h1,6), "|cFF8F42B2")
    call DestroyEffect(AddSpecialEffectTarget("Abilities\\Spells\\Human\\ManaFlare\\ManaFlareTarget.mdl",LoadUnitHandle(udg_GHT,h1,2),"overhead"))
    call FlushChildHashtable(udg_GHT,h1)
    call DestroyTimer(t)
    set t = null
endfunction

function WW takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer h = GetHandleId(t)
    local group G = LoadGroupHandle(udg_GHT,h,10)
    call BJDebugMsg("Units: "+I2S(CountUnitsInGroup(G)))
    local timer t1 = CreateTimer()
    local integer h1 = GetHandleId(t1)
    local unit c = LoadUnitHandle(udg_GHT,h,1)
    local unit u
    local real agi = I2R(GetHeroAgi(c,true))
    local real sd = GetSpellDamage(c)
    local real cc = GetCritChance(c)
    local unit dummy = CreateDummy(c)
    local real dist 
    if CountUnitsInGroup(G) > 0 then
    set u=FirstOfGroup(G)
    call GroupRemoveUnit(G,u)
    set dist = DistanceBetweenWidgets(c,u)
    call BJDebugMsg("Dist: "+R2S(dist))
    call SetUnitFacingToFaceUnitTimed(c,u,0)
        call SetUnitAnimation(c,"Attack - 2")
        if MissCalculator(u,0)==false then
        else
        call UnitAddAbility(dummy,'A037')
        call IssueTargetOrder(dummy,"thunderbolt",u)
        call TimerStart(t1,dist/2000,false,function WWW)
        call SaveUnitHandle(udg_GHT,h1,1,c)
        call SaveUnitHandle(udg_GHT,h1,2,u)
        call SaveReal(udg_GHT,h1,3,agi*10)
        call SaveReal(udg_GHT,h1,4,sd)
        call SaveReal(udg_GHT,h1,5,cc)
        call SaveReal(udg_GHT,h1,6,2)
        endif
    set u = null
    set c = null
    set t1 = null
    set dummy = null
    else
    call FlushChildHashtable(udg_GHT,h)
    call DestroyGroup(G)
    set G = null
    call DestroyTimer(t)
    call PauseUnit(c,false)
    set dummy = null
    set t1 = null
    set u = null
    set c = null
    set t = null
    endif
endfunction


//===========================================================================

function W takes nothing returns nothing
    call BJDebugMsg("SearchStart")
    local integer h = GetHandleId(GetExpiredTimer())
    local unit c = LoadUnitHandle(udg_GHT,h,1)
    local timer t = CreateTimer()
    local integer h1 = GetHandleId(t)
    local integer range = 0
    local unit u 
    local group g = CreateGroup()
    local group G = CreateGroup()
    call FlushChildHashtable(udg_GHT,h)
    call SaveUnitHandle(udg_GHT,h1,1,c)
    loop
    set range = range + 50
    exitwhen range >= 1000
    call GroupEnumUnitsInRange(g,GetUnitX(c),GetUnitY(c),range+75,null)
    endloop
    loop
    set u = FirstOfGroup(g)
    call GroupRemoveUnit(g,u)
    exitwhen u == null
     if not IsUnitAliveAndAlly(c,u) then
            call GroupAddUnit(G,u)
        endif
    endloop
    call DestroyGroup(g)
    set g = null
    call SaveGroupHandle(udg_GHT,h1,10,G)
    call GroupRemoveUnit(G,c)
    call PauseUnit(c,true)
    set G = null
    call TimerStart(t,0.50,true,function WW)
endfunction

function RedArcherActions takes nothing returns nothing
    local unit c = GetSpellAbilityUnit()
    local timer t = CreateTimer()
    local integer h = GetHandleId(t)
    call SaveUnitHandle(udg_GHT,h,1,c)
    if GetAbilityName(GetSpellAbilityId()) == "Скоп" then
    call TimerStart(t,0.05,false,function W)
    set t = null
    call SetUnitAnimation(c, "Stand Channel")
    call BJDebugMsg("Скоп")
    endif
    set c = null
endfunction

private function InitRedArcher takes nothing returns nothing
    set RedArcher = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( RedArcher, EVENT_PLAYER_UNIT_SPELL_FINISH)
    call TriggerAddAction( RedArcher, function RedArcherActions )
endfunction

endscope
//===========================================================================
function InitTrig_ArcherRed takes nothing returns nothing
endfunction

Принятый ответ

Если коротко: имена функций - жуть, не вижу определения PureDamageWithCrit, некоторые вызовы будут чуть медленнее из-за экономии места, ну и без хештаблицы можно, обойтись структурами + TimerExploit.
Блин, два раза кодировка сбивается в комменте, теперь вообще текста не видно, что за...
`
ОЖИДАНИЕ РЕКЛАМЫ...
0
21
6 лет назад
0
не по теме, но интересная идея скилл триггерить по проверке имени, мной впервые такая увидена...
а тогда, может, и в текстовом сообщении прямо с имени и считывать? и не в каждом скилле, а где-то отдельно в системе?
я про call BJDebugMsg("Скоп") - мб вместо "Скоп" делать гетабилитинейм и где-нибудь глобально, а не в каждом скилле
0
17
6 лет назад
0
ClotPh, По идее, GetAbilityName(GetSpellAbilityId()) берёт строку из поля Name .
Поле Tip - использующееся в игре как название способности - остаётся нетронутым.
Так что в теории можно просто именовать абилки как Q,W,E,R и так далее (по хоткею например), а доп проверкой делать имя юнита.
0
26
6 лет назад
0
А что скилл делает?
0
8
6 лет назад
Отредактирован uranus
0
Если коротко: имена функций - жуть, не вижу определения PureDamageWithCrit, некоторые вызовы будут чуть медленнее из-за экономии места, ну и без хештаблицы можно, обойтись структурами + TimerExploit.
Блин, два раза кодировка сбивается в комменте, теперь вообще текста не видно, что за...
Принятый ответ
0
13
6 лет назад
0
Лучше бы картой его скинуть - так тестить легче. Вкручу туда мониторинг хэш-таблицы и Object Counter и все дела:)
0
17
6 лет назад
0
Пушистый, Ну вы что, думаете так легко я отдам вам свой план захвата мира, используя милых котиков?
Сама карта и есть полигон со всеми системами, но делиться ими я пока не готов
0
8
6 лет назад
0
PyCCKuu_4eJl, кстати, периодический таймер - очень плохая идея, лучше запускать истекший таймер снова. Я сам не верил, пока лично не столкнулся. Да и TimerExploit на нем не будет работать. В остальном все грамотно, ИМХО. Полностью оценить не могу, т.к. глаза воспринимают только cJASS.
0
28
6 лет назад
Отредактирован PT153
0
Я сам не верил, пока лично не столкнулся.
А что с периодическим таймером не так?
Кроме бага с ResumeTimer().
0
8
6 лет назад
Отредактирован uranus
0
PT153, учитывая, что все настоятельно не советуют создавать больше одного такого таймера, предполагаю, что жрет ресурсы.
Из статьи про оптимизацию:
Правда некоторые объекты не удаляются... т.е. DestroyTrigger не полностью удаляет триггер... перед этим еще нужно удалить все его действия выключить подождать секунду и потом удалить.. и обнулить
Но даже это может не спасти от утечек.. потому между выбором - таймер или периодический триггер - выбирайте таймер.
И Скорп:
периодический таймер обычно один для всего, он просто гуляет по массиву и "толкает" рычаги
0
28
6 лет назад
Отредактирован PT153
0
Вот только DracoL1ch наоборот говорил, что лучше куча таймеров, чем 1 таймер с if-ами внутри его функции.
В цитате говорится, что периодический таймер лучше, чем периодический триггер, но не говорится, что периодический таймер хуже, чем непериодический.

Из всех проблем с периодическими таймерами я знаю только баг с ResumeTimer(). А ещё вроде бы периодический таймер будет точнее, чем перезапуск непериодического.
0
8
6 лет назад
0
PT153, хороший вопрос, на самом деле, в цитате Скорпа видно только, что он должен быть всего один, а про эффективность непонятно. Хотелось бы услышать мнение Адика на этот счет.
0
28
6 лет назад
0
должен быть
Не должен быть, а обычно.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.