Делаю одну большую карту на Warcraft 3 и столкнулся с проблемой утечек - почти стабильный краш примерно на 2 часу игры. Всё делаю (только не бейте) на обычном GUI, как я понял из поиска в интернете - это проблема с утечками, и скорее всего с точками создания юнитов.
Собственно, суть вопроса.
Избавлюсь ли я от утечек с точками, если будут перед каждым спавном иметь какую то переменную точки (назовём её P) и юнит будет создаваться не в "Область 019", а в "P", которая всегда меняется.
Избавлюсь ли я от утечек юнитов, если спустя n-минут после смерти труп удаляется действием "Боевая единица - Удалить".
Избавлюсь ли я от утечек спецэффектов, если аналогично юнитам, спецэффекты (и плавающий текст) удаляются спустя n-минут?
Нужно ли добавить к этому всему что то ещё?
Пы.сы. те статьи от бота я уже посмотрел, но не нашёл того, чего хотел

Надо, конечно, взглянуть на триггеры в карте, но при спавне удалять нужно не только точки, но и группы, так как при спавне создаются не только юниты, но и группа для них (даже из одного юнита группы). Без утечек создание юнитов выглядит так:
вот код для custom script:
call DestroyGroup( GetLastCreatedGroup() )
call RemoveLocation( udg_P )
Если отдаёшь приказ группе юнитов отправиться в область, там тоже создаётся группа и точка, тоже нужны эти custom script. Но вообще сомнительно, что это вызывает дикие лаги через два часа. Наверное, есть какие-то события с малым периодом, что тоже плодят утечки, поэтому и надо триггеры в карте смотреть.
Загруженные файлы
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
28
По поводу групп: можно не удалять группу через Destroy Group, а перед вызовом (выбрать всех юнитов в группе и сделать то-то) написать в Custom Script
set bj_wantDestroyGroup = true
Тогда группа сама удалится.

Счётчикам особо доверять не стоит, но если что-то постоянно утекает, то они это заметят.
26
Но это не работает с выбором всех юнитов определённого типа на карте.
28
Но это не работает с выбором всех юнитов определённого типа на карте.
Pick every unit in group and do actions вызывает ForGroupBJ(), в которой при bj_wantDestroyGroup == true группа удаляется.
ForGroupBJ
function ForGroupBJ takes group whichGroup, code callback returns nothing
    // If the user wants the group destroyed, remember that fact and clear
    // the flag, in case it is used again in the callback.
    local boolean wantDestroy = bj_wantDestroyGroup
    set bj_wantDestroyGroup = false

    call ForGroup(whichGroup, callback)

    // If the user wants the group destroyed, do so now.
    if (wantDestroy) then
        call DestroyGroup(whichGroup)
    endif
endfunction
Не работает как раз-таки способ с удалением GetLastCreatedGroup(), потому что все BJ функции групп используют локалки.
Функции
function GetUnitsInRangeOfLocMatching takes real radius, location whichLocation, boolexpr filter returns group
    local group g = CreateGroup()
    call GroupEnumUnitsInRangeOfLoc(g, whichLocation, radius, filter)
    call DestroyBoolExpr(filter)
    return g
endfunction

function GetUnitsInRectMatching takes rect r, boolexpr filter returns group
    local group g = CreateGroup()
    call GroupEnumUnitsInRect(g, r, filter)
    call DestroyBoolExpr(filter)
    return g
endfunction

function GetUnitsInRectOfPlayer takes rect r, player whichPlayer returns group
    local group g = CreateGroup()
    set bj_groupEnumOwningPlayer = whichPlayer
    call GroupEnumUnitsInRect(g, r, filterGetUnitsInRectOfPlayer)
    return g
endfunction

function GetUnitsOfPlayerAndTypeId takes player whichPlayer, integer unitid returns group
    local group g = CreateGroup()
    set bj_groupEnumTypeId = unitid
    call GroupEnumUnitsOfPlayer(g, whichPlayer, filterGetUnitsOfPlayerAndTypeId)
    return g
endfunction

function GetUnitsOfPlayerMatching takes player whichPlayer, boolexpr filter returns group
    local group g = CreateGroup()
    call GroupEnumUnitsOfPlayer(g, whichPlayer, filter)
    call DestroyBoolExpr(filter)
    return g
endfunction

function GetUnitsOfTypeIdAll takes integer unitid returns group
    local group   result = CreateGroup()
    local group   g      = CreateGroup()
    local integer index

    set index = 0
    loop
        set bj_groupEnumTypeId = unitid
        call GroupClear(g)
        call GroupEnumUnitsOfPlayer(g, Player(index), filterGetUnitsOfTypeIdAll)
        call GroupAddGroup(g, result)

        set index = index + 1
        exitwhen index == bj_MAX_PLAYER_SLOTS
    endloop
    call DestroyGroup(g)

    return result
endfunction

function GetUnitsSelectedAll takes player whichPlayer returns group
    local group g = CreateGroup()
    call SyncSelections()
    call GroupEnumUnitsSelected(g, whichPlayer, null)
    return g
endfunction
Так что самый верный способ будет через присвоение.
set bj_wantDestroyGroup = true

Локации удалять через RemoveLocation(), а группы через set bj_wantDestroyGroup = true.
26
Обработает лишь красного игрока и удалит группу, а у остальных игроков юнитов нужного типа неоткуда будет брать.
PT153:
Не работает как раз-таки способ с удалением GetLastCreatedGroup(), потому что все BJ функции групп используют локалки.
Так это что получается, нужно сначала присвоить глобальную переменную локальной группе, чтобы потом её удалить?
28
Обработает лишь красного игрока и удалит группу, а у остальных игроков юнитов нужного типа неоткуда будет брать.
Это было проверено на практике или нет?
Потому что по коду я вижу, что всё будет работать верно. Сначала сработает GetUnitsOfTypeIdAll(), и только потом ForGroupBJ(). Их код я кинул выше.
Если сконвертировать, то будет следующее.
call ForGroupBJ( GetUnitsOfTypeIdAll('hfoo'), function Trig_Untitled_Trigger_001_Func001A )
Это сработает так, как я сказал выше, потому что в JASS, как и во многих языках, передача по значению.

Так это что получается, нужно сначала присвоить глобальную переменную локальной группе, чтобы потом её удалить?
Нет, наоборот. Делаем переменную типа группа, в неё записываем нужную группу, после для неё вызываем Pick every unit in group and do actions, а затем удаляем. Это 3 строчки. Но зачем это, когда можно перед Pick every unit in group and do actions просто написать set bj_wantDestroyGroup = true с таким же результатом? И займет это 2 строчки.
Но это не работает с выбором всех юнитов определённого типа на карте.
Как я уже описал выше, работает, для практической проверки стоит посмотреть карту Лазурные башни, триггер Tech\Zenith Refresh.
26
Ты же задавался уже этим вопросом, почему обрабатываются лишь юниты красного игрока, а остальных нет.
Нет, наоборот. Делаем переменную типа группа, в неё записываем нужную группу, после для неё вызываем Pick every unit in group and do actions, а затем удаляем.
Речь о группе, когда юнитов создают
CreateNUnitsAtLoc
function CreateNUnitsAtLoc takes integer count, integer unitId, player whichPlayer, location loc, real face returns group
    call GroupClear(bj_lastCreatedGroup)
    loop
        set count = count - 1
        exitwhen count < 0
        call CreateUnitAtLocSaveLast(whichPlayer, unitId, loc, face)
        call GroupAddUnit(bj_lastCreatedGroup, bj_lastCreatedUnit)
    endloop
    return bj_lastCreatedGroup
endfunction
Загруженные файлы
28
Ты же задавался уже этим вопросом, почему обрабатываются лишь юниты красного игрока, а остальных нет.
Гхм, залез в код, словил рофл от этого. Совсем не ожидал того, что внутри GroupAddGroup тоже будет проверятся этот флаг.
Мда, ОЧЕНЬ много ошибок в лазурных башнях и в самих bj.
8gabriel8:
Речь о группе, когда юнитов создают
Тут совершенно верно замечено. Я изначально вёл речь о Pick every unit in group and do actions.
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.