Вот такой кусочек кода
Код
private function myfilt takes nothing returns boolean
    set bj_lastReplacedUnit = GetFilterUnit()
    return not IsUnitDead(bj_lastReplacedUnit) and not IsUnitType(bj_lastReplacedUnit,UNIT_TYPE_STRUCTURE) and IsUnitEnemy(bj_lastReplacedUnit,bj_groupEnumOwningPlayer) and not IsUnitInGroup(bj_lastReplacedUnit,TempG)
endfunction

private function dmgk takes nothing returns nothing
    call UnitDamageTarget(bj_lastCreatedUnit,GetEnumUnit(),TempReal,true,false,AttackType,DamageType,WeaponType)
    call GroupAddUnit(TempG,GetEnumUnit())
endfunction

private function move1 takes nothing returns nothing
    local unit u = GetEnumUnit()
    local real a = GetUnitFacing(u)*bj_DEGTORAD
    local group g = CreateGroup()
    
    call SetUnitX(u,GetUnitX(u)+WavesSpeed*Cos(a))
    call SetUnitY(u,GetUnitY(u)+WavesSpeed*Sin(a))
    
    set bj_groupEnumOwningPlayer = GetOwningPlayer(u)
    call GroupEnumUnitsInRange(g,GetUnitX(u),GetUnitY(u),WaveRadius,Condition(function myfilt))
    set bj_groupEnumOwningPlayer = null
    set bj_lastCreatedUnit = u
    call ForGroup(g,function dmgk)
    set bj_lastCreatedUnit = null
    
    call GroupClear(g)
    call DestroyGroup(g)
    set g = null
    set u = null
endfunction

private function move takes nothing returns nothing
	...
    set TempG = LoadGroupHandle(udg_Hash,i,4)
    call ForGroup(g,function move1)
    call SaveGroupHandle(udg_Hash,i,4,TempG)
    call GroupClear(TempG)
    set TempG = null
	...
endfunction
прим. TempG глобальная группа
Как поведёт себя выгружаемая группа "set TempG = LoadGroupHandle(udg_Hash,i,4)" после "call GroupClear(TempG)"? По сути же каждый раз мы будем выгружать пустую группу? А мне нужна, чтобы она уже была с продамаженными юнитами. Я могу это спокойно реализовать через луп, но тогда придётся отказаться от двух функций ForGroup (move, move1), а это на скорость обработки вроде влияет.. как быть?

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

Всё, довольно быстро разобрался
Помогла функция от quq_CCCP если не ошибаюсь
function CopyGroup takes group g returns group
    set bj_groupAddGroupDest = CreateGroup()
    call ForGroup(g, function GroupAddGroupEnum)
    return bj_groupAddGroupDest
endfunction
Вот так переделал
	...
	local group gg = null
	...
	set TempG = LoadGroupHandle(udg_Hash,i,4)
    set TempReal = LoadReal(udg_Hash,i,3)
    call ForGroup(g,function move1)
    set gg = CopyGroup(TempG)
    call SaveGroupHandle(udg_Hash,i,4,gg)
    call GroupClear(TempG)
    set TempG = null
	...
Хотя вроде каждые 0.03 сек создаётся новая группа, а удаляется лишь один раз вместе с таймером, мне кажется там утечек из-за этого дофига. Но это чуть позже проверю, в таком случае откажусь от ForGroup

Да, к сожалению оно вызывает утечки, но это было очевидно. Копирование группы лучше использовать для локальных групп, которые можно будет потом уничтожить. В общем перенесу всё в луп

Код
private function move takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer i = GetHandleId(t)
    local group g = LoadGroupHandle(udg_Hash,i,0)
    local group gg = CopyGroup(g)
    local group ggg = CreateGroup()
    local group g1 = LoadGroupHandle(udg_Hash,i,4)
    local real d = LoadReal(udg_Hash,i,2)+WavesSpeed
    local real a
    local unit u = null
    local unit uu = null
    
    loop
        set u = FirstOfGroup(gg)
        exitwhen u == null
        set a = GetUnitFacing(u)*bj_DEGTORAD
        call SetUnitX(u,GetUnitX(u)+WavesSpeed*Cos(a))
        call SetUnitY(u,GetUnitY(u)+WavesSpeed*Sin(a))
        set bj_groupEnumOwningPlayer = GetOwningPlayer(u)
        call GroupEnumUnitsInRange(ggg,GetUnitX(u),GetUnitY(u),WaveRadius,Condition(function myfilt))
        set bj_groupEnumOwningPlayer = null
        loop
            set uu = FirstOfGroup(ggg)
            exitwhen uu == null
            if not IsUnitInGroup(uu,g1) then
                call UnitDamageTarget(u,uu,LoadReal(udg_Hash,i,3),true,false,AttackType,DamageType,WeaponType)
                call GroupAddUnit(g1,uu)
            endif
            call GroupRemoveUnit(ggg,uu)
            set uu = null
        endloop
        call GroupRemoveUnit(gg,u)
        set u = null
    endloop
    
    if d >= LoadReal(udg_Hash,i,1) then
    DisplayTextToPlayer(Player(0),0,0,I2S(1))
        call PauseTimer(t)
        call DestroyTimer(t)
        call FlushChildHashtable(udg_Hash,i)
        call ForGroup(g,function kill)
        call GroupClear(g)
        call DestroyGroup(g)
        call GroupClear(g1)
        call DestroyGroup(g1)
    else
        call SaveReal(udg_Hash,i,2,d)
    endif
    
    call DestroyGroup(gg)
    call DestroyGroup(ggg)
    set g = null
    set gg = null
    set ggg = null
    set g1 = null
    set t = null
    set g = null
endfunction

Что это за абилку я делаю, можете посмотреть с 20.12.2020 вечером в моём блоге))
Да, это реклама говноабилок, я лох
`
ОЖИДАНИЕ РЕКЛАМЫ...
0
19
3 года назад
0
Похожие вопросы:

ответ
Я бы на вашем месте использовал "Custom Script", то есть вставил локальные переменные на языке jass. Вышло бы приблизительно так:
Вот рабочий триггер. Никаких глобальных переменных. Работает со множествами игроков и юнитов. Не тормозит карту.
В условиях: (Ability being cast) равно "Здесь поставь способность которая применяется на юнита"
Описываю действия:
  1. Создаем локальную переменную юнита
  2. Даем юниту на которого применяется способность "Невидимость", способность "Змеиная ловкость"
  3. В локальную переменную юнита вписываем юнита на которого применена способность
  4. Ждем тридцать секунд, то есть столько времени, сколько у юнита будет доп. способность "Змеиная ловкость"
  5. По истечении времени забираем у юнита доп. способность "Змеиная ловкость"
В пятой строке 'AEev' - это код способности "Змеиная ловкость"
Если что-то не понятно - обращайся.
Напоминаю - триггер полностью играбельный!
К комментарию добавляю карту с рабочим триггером:

0
27
3 года назад
Отредактирован rsfghd
0
Всё, довольно быстро разобрался
Помогла функция от quq_CCCP если не ошибаюсь
function CopyGroup takes group g returns group
    set bj_groupAddGroupDest = CreateGroup()
    call ForGroup(g, function GroupAddGroupEnum)
    return bj_groupAddGroupDest
endfunction
Вот так переделал
	...
	local group gg = null
	...
	set TempG = LoadGroupHandle(udg_Hash,i,4)
    set TempReal = LoadReal(udg_Hash,i,3)
    call ForGroup(g,function move1)
    set gg = CopyGroup(TempG)
    call SaveGroupHandle(udg_Hash,i,4,gg)
    call GroupClear(TempG)
    set TempG = null
	...
Хотя вроде каждые 0.03 сек создаётся новая группа, а удаляется лишь один раз вместе с таймером, мне кажется там утечек из-за этого дофига. Но это чуть позже проверю, в таком случае откажусь от ForGroup

Да, к сожалению оно вызывает утечки, но это было очевидно. Копирование группы лучше использовать для локальных групп, которые можно будет потом уничтожить. В общем перенесу всё в луп

Код
private function move takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer i = GetHandleId(t)
    local group g = LoadGroupHandle(udg_Hash,i,0)
    local group gg = CopyGroup(g)
    local group ggg = CreateGroup()
    local group g1 = LoadGroupHandle(udg_Hash,i,4)
    local real d = LoadReal(udg_Hash,i,2)+WavesSpeed
    local real a
    local unit u = null
    local unit uu = null
    
    loop
        set u = FirstOfGroup(gg)
        exitwhen u == null
        set a = GetUnitFacing(u)*bj_DEGTORAD
        call SetUnitX(u,GetUnitX(u)+WavesSpeed*Cos(a))
        call SetUnitY(u,GetUnitY(u)+WavesSpeed*Sin(a))
        set bj_groupEnumOwningPlayer = GetOwningPlayer(u)
        call GroupEnumUnitsInRange(ggg,GetUnitX(u),GetUnitY(u),WaveRadius,Condition(function myfilt))
        set bj_groupEnumOwningPlayer = null
        loop
            set uu = FirstOfGroup(ggg)
            exitwhen uu == null
            if not IsUnitInGroup(uu,g1) then
                call UnitDamageTarget(u,uu,LoadReal(udg_Hash,i,3),true,false,AttackType,DamageType,WeaponType)
                call GroupAddUnit(g1,uu)
            endif
            call GroupRemoveUnit(ggg,uu)
            set uu = null
        endloop
        call GroupRemoveUnit(gg,u)
        set u = null
    endloop
    
    if d >= LoadReal(udg_Hash,i,1) then
    DisplayTextToPlayer(Player(0),0,0,I2S(1))
        call PauseTimer(t)
        call DestroyTimer(t)
        call FlushChildHashtable(udg_Hash,i)
        call ForGroup(g,function kill)
        call GroupClear(g)
        call DestroyGroup(g)
        call GroupClear(g1)
        call DestroyGroup(g1)
    else
        call SaveReal(udg_Hash,i,2,d)
    endif
    
    call DestroyGroup(gg)
    call DestroyGroup(ggg)
    set g = null
    set gg = null
    set ggg = null
    set g1 = null
    set t = null
    set g = null
endfunction

Что это за абилку я делаю, можете посмотреть с 20.12.2020 вечером в моём блоге))
Да, это реклама говноабилок, я лох
Принятый ответ
Чтобы оставить комментарий, пожалуйста, войдите на сайт.