Я больше чем на 70% уверен, что у меня код написан плохо. Так как взаимодействия с отрядами не очень сложилось у меня, прошу помочь оптимизировать код, и убрать лишнее. Наворотил всякого.
Код и карту приложил.
Код:
return GetSpellAbilityId() == 'A001'
endfunction
function FilterR takes nothing returns boolean
local unit z = LoadUnitHandle(udg_Hash,StringHash("x"),1)
local player p = GetOwningPlayer(z)
return  IsPlayerEnemy(p, GetOwningPlayer(GetFilterUnit())) and GetWidgetLife(GetFilterUnit()) > 0.405 and not IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) and not IsUnitType(GetFilterUnit(), UNIT_TYPE_FLYING)
endfunction
function Trig_R_Boom takes unit d returns nothing
local real x = GetUnitX(d)
local real y = GetUnitY(d)
local group g = CreateGroup()
local unit f
call GroupEnumUnitsInRange(g, x, y,500,Condition(function FilterR))
    loop
    set f = FirstOfGroup(g)
    exitwhen f == null
    call UnitDamageTarget(d,f,400, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC, null)
    call GroupRemoveUnit(g,f)
endloop
set g = null
set f = null
call DestroyGroup(g)
endfunction
function Trig_LOCAL_TimerR takes nothing returns nothing
local timer timerer = GetExpiredTimer()
local integer i = GetHandleId(timerer)
local unit Caster = LoadUnitHandle(udg_Hash,i,4)
local unit Dummy = LoadUnitHandle(udg_Hash,i,3)
local real xd = GetUnitX(Dummy)
local real yd = GetUnitY(Dummy)
if (GetWidgetLife(Dummy) < 0.405) then
call Trig_R_Boom (Dummy)
call FlushChildHashtable(udg_Hash,i)
call FlushChildHashtable(udg_Hash,StringHash("x"))
call DestroyTimer(timerer)
set Dummy = CreateUnit(GetOwningPlayer(Caster),'u001',xd,yd,0)
call UnitApplyTimedLife(Dummy,'BTLF', 2)
set Caster = null
set Dummy = null
else
set xd=GetUnitX(Dummy)+10*Cos(GetUnitFacing(Dummy)*bj_DEGTORAD)
set yd=GetUnitY(Dummy)+10*Sin(GetUnitFacing(Dummy)*bj_DEGTORAD)
call SetUnitPosition(Dummy,xd,yd)
endif
set Caster = null
set Dummy = null
endfunction

function Trig_R_Actions takes nothing returns nothing
local unit Caster = GetTriggerUnit()
local location Target = GetSpellTargetLoc()
local real xt = GetLocationX(Target)
local real yt = GetLocationY(Target)
local real xc = GetUnitX(Caster)
local real yc = GetUnitY(Caster)
local real Angle = bj_RADTODEG * Atan2(yt-yc,xt-xc)
local unit Dummy = CreateUnit(GetOwningPlayer(Caster),'u000',xc,yc,Angle)
local timer timerer = CreateTimer()
local integer i = GetHandleId(timerer)
call SetUnitAnimation( Dummy, "Birth" )
call UnitApplyTimedLife(Dummy,'BTLF', 1)
call SaveUnitHandle(udg_Hash,i,3,Dummy)
call SaveUnitHandle(udg_Hash,i,4,Caster)
call SaveUnitHandle(udg_Hash,StringHash("x"),1,Caster)
call TimerStart(timerer, 0.01, true, function Trig_LOCAL_TimerR)
call RemoveLocation(Target)
set Caster = null
set Dummy = null
endfunction
Карта:

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

call SaveInteger(udg_Hash,StringHash("x"),1,GetPlayerId(GetOwningPlayer(Caster)))

function Trig_R_Boom takes unit d, unit c returns nothing

call GroupEnumUnitsInRange(g, x, y,500,Condition(function FilterR))
loop
	set f = FirstOfGroup(g)
    exitwhen f == null
    call UnitDamageTarget(c,f,400, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC, null)
    call GroupRemoveUnit(g,f)
endloop

В конце функции Trig_R_Actions( )не обнулена переменная типа timer.
- Короче, вот:
function Trig_LOCAL_TimerR takes nothing returns nothing
    local  timer   timerer =  GetExpiredTimer( )
    local  integer i       =  GetHandleId( timerer )
    local  unit    Caster  =  LoadUnitHandle( udg_Hash, i, 4 )
    local  unit    Dummy   =  LoadUnitHandle( udg_Hash, i, 3 )
    local  real    xd      =  GetUnitX( Dummy )
    local  real    yd      =  GetUnitY( Dummy )
    local  group   g       =  null
    local  unit    f       =  null

    if ( GetWidgetLife( Dummy ) < 0.405 ) then

        set  g  =  CreateGroup( )

        call GroupEnumUnitsInRange( g, xd, yd, 500.0, null )
        loop
            set  f  =  FirstOfGroup( g )
            exitwhen ( f == null )
            call GroupRemoveUnit( g, f )

            if IsUnitEnemy( f, GetOwningPlayer( Caster ) ) and ( GetWidgetLife( f ) > 0.405 ) and ( not IsUnitType( f, UNIT_TYPE_STRUCTURE ) ) and ( not IsUnitType( f, UNIT_TYPE_FLYING ) ) then
                call UnitDamageTarget( Caster, f, 400.0, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC, null )
            endif

        endloop

        call DestroyGroup( g )
        set  g  =  null

        call FlushChildHashtable( udg_Hash, i )
        call DestroyTimer( timerer )
        set  Dummy  =  CreateUnit( GetOwningPlayer( Caster ), 'u001', xd, yd, 0.0 )
        call UnitApplyTimedLife( Dummy, 'BTLF', 2.0 )

    else
        set  xd = GetUnitX( Dummy ) + 10.0 * Cos( GetUnitFacing( Dummy ) * bj_DEGTORAD )
        set  yd = GetUnitY( Dummy ) + 10.0 * Sin( GetUnitFacing( Dummy ) * bj_DEGTORAD )
        call SetUnitPosition( Dummy, xd, yd )
    endif

    set  timerer  =  null
    set  Caster   =  null
    set  Dummy    =  null
endfunction


function Trig_R_Actions takes nothing returns nothing
    local  unit     Caster   =  GetTriggerUnit( )
    local  real     xt       =  GetSpellTargetX( )
    local  real     yt       =  GetSpellTargetY( )
    local  real     xc       =  GetUnitX( Caster )
    local  real     yc       =  GetUnitY( Caster )
    local  unit     Dummy    =  CreateUnit( GetOwningPlayer( Caster ), 'u000', xc, yc, bj_RADTODEG * Atan2( yt - yc, xt - xc ) )
    local  timer    timerer  =  CreateTimer( )
    local  integer  i        =  GetHandleId( timerer )

    call SetUnitAnimation( Dummy, "Birth" )
    call UnitApplyTimedLife( Dummy, 'BTLF', 1.0 )
    call SaveUnitHandle( udg_Hash, i, 3, Dummy )
    call SaveUnitHandle( udg_Hash, i, 4, Caster )
    call TimerStart( timerer, 0.01, true, function Trig_LOCAL_TimerR )

    set  Caster   =  null
    set  Dummy    =  null
    set  timerer  =  null
endfunction

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
1
20
6 лет назад
1
timerer еще не обнулил в самой нижней функции
0
7
6 лет назад
0
biridius:
timerer еще не обнулил в самой нижней функции
Всё. Спасибо большое.
0
26
6 лет назад
0
А я вот вижу проверку на 0.405 хп, вместо проверки мёртвости юнита
5
21
6 лет назад
Отредактирован scopterectus
5
call SaveInteger(udg_Hash,StringHash("x"),1,GetPlayerId(GetOwningPlayer(Caster)))

function Trig_R_Boom takes unit d, unit c returns nothing

call GroupEnumUnitsInRange(g, x, y,500,Condition(function FilterR))
loop
	set f = FirstOfGroup(g)
    exitwhen f == null
    call UnitDamageTarget(c,f,400, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC, null)
    call GroupRemoveUnit(g,f)
endloop

В конце функции Trig_R_Actions( )не обнулена переменная типа timer.
- Короче, вот:
function Trig_LOCAL_TimerR takes nothing returns nothing
    local  timer   timerer =  GetExpiredTimer( )
    local  integer i       =  GetHandleId( timerer )
    local  unit    Caster  =  LoadUnitHandle( udg_Hash, i, 4 )
    local  unit    Dummy   =  LoadUnitHandle( udg_Hash, i, 3 )
    local  real    xd      =  GetUnitX( Dummy )
    local  real    yd      =  GetUnitY( Dummy )
    local  group   g       =  null
    local  unit    f       =  null

    if ( GetWidgetLife( Dummy ) < 0.405 ) then

        set  g  =  CreateGroup( )

        call GroupEnumUnitsInRange( g, xd, yd, 500.0, null )
        loop
            set  f  =  FirstOfGroup( g )
            exitwhen ( f == null )
            call GroupRemoveUnit( g, f )

            if IsUnitEnemy( f, GetOwningPlayer( Caster ) ) and ( GetWidgetLife( f ) > 0.405 ) and ( not IsUnitType( f, UNIT_TYPE_STRUCTURE ) ) and ( not IsUnitType( f, UNIT_TYPE_FLYING ) ) then
                call UnitDamageTarget( Caster, f, 400.0, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC, null )
            endif

        endloop

        call DestroyGroup( g )
        set  g  =  null

        call FlushChildHashtable( udg_Hash, i )
        call DestroyTimer( timerer )
        set  Dummy  =  CreateUnit( GetOwningPlayer( Caster ), 'u001', xd, yd, 0.0 )
        call UnitApplyTimedLife( Dummy, 'BTLF', 2.0 )

    else
        set  xd = GetUnitX( Dummy ) + 10.0 * Cos( GetUnitFacing( Dummy ) * bj_DEGTORAD )
        set  yd = GetUnitY( Dummy ) + 10.0 * Sin( GetUnitFacing( Dummy ) * bj_DEGTORAD )
        call SetUnitPosition( Dummy, xd, yd )
    endif

    set  timerer  =  null
    set  Caster   =  null
    set  Dummy    =  null
endfunction


function Trig_R_Actions takes nothing returns nothing
    local  unit     Caster   =  GetTriggerUnit( )
    local  real     xt       =  GetSpellTargetX( )
    local  real     yt       =  GetSpellTargetY( )
    local  real     xc       =  GetUnitX( Caster )
    local  real     yc       =  GetUnitY( Caster )
    local  unit     Dummy    =  CreateUnit( GetOwningPlayer( Caster ), 'u000', xc, yc, bj_RADTODEG * Atan2( yt - yc, xt - xc ) )
    local  timer    timerer  =  CreateTimer( )
    local  integer  i        =  GetHandleId( timerer )

    call SetUnitAnimation( Dummy, "Birth" )
    call UnitApplyTimedLife( Dummy, 'BTLF', 1.0 )
    call SaveUnitHandle( udg_Hash, i, 3, Dummy )
    call SaveUnitHandle( udg_Hash, i, 4, Caster )
    call TimerStart( timerer, 0.01, true, function Trig_LOCAL_TimerR )

    set  Caster   =  null
    set  Dummy    =  null
    set  timerer  =  null
endfunction
Принятый ответ
0
32
6 лет назад
0
В фильтрах незачем обьявлять локалки, для этого есть темповые глобалки.
0
20
6 лет назад
0
quq_CCCP:
В фильтрах незачем обьявлять локалки, для этого есть темповые глобалки.
почему?
0
32
6 лет назад
0
Diaboliko, во первых их нужно еще и обнулять, когда речь идет о хендлах, во вторых внезапно это тоже операция и затрачивается время, потом вспоминаем что фильтры работают постоянно перебирая юнитов и понимаем зачем нужны глобалки...
0
7
6 лет назад
0
ScopteRectuS, Огромное спасибо, никак не мог понять работу с отрядами, то есть с фильтром, оказывается можно было обойтись одним условием. Это всё облегчает. Благодарю за советы.
Extremator:
А я вот вижу проверку на 0.405 хп, вместо проверки мёртвости юнита
Так это же, юнит умирает когда у него хп не ноль, а где-то 0.4. Кончено у меня целостный урон я мог бы и так написать:
GetUnitState(whichUnit, UNIT_STATE_LIFE) <= 0
Но и в этом случаи всё равно работало бы, кроме одного: а если предположим у юнита (мёртвого) 0.3 здоровья, он мёртв, но его выделит в отряд и нанесёт ему ещё урон, но зачем? Он как бы итак мёртв.
quq_CCCP:
В фильтрах незачем объявлять локалки, для этого есть темповые глобалки.
Не думаю, что от глобалок лучше станет, как написал ScopteRectuS, можно обойтись условием, не создавая лишних функций.
0
16
6 лет назад
0
IsUnitType(u,UNIT_TYPE_DEAD)
0
20
6 лет назад
0
quq_CCCP:
Diaboliko, во первых их нужно еще и обнулять, когда речь идет о хендлах, во вторых внезапно это тоже операция и затрачивается время, потом вспоминаем что фильтры работают постоянно перебирая юнитов и понимаем зачем нужны глобалки...
даже в не-кешированном виде локалка быстрее глобалки. А, касательно обнуления, лично я пихаю фильтры в глобалки, да.
0
16
6 лет назад
0
нет понятия "переменная быстрее", они все одним скопом идут
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.