Необходимо посчитать количество боевых единиц (не зданий). Написал следующий код:
    integer result = -1
    unit first = null
    group units = GetUnitsInRectOfPlayer(GetPlayableMapRect(), Player(id))
    
    do {
        first = FirstOfGroup(units)
        if (not(IsUnitType(first, UNIT_TYPE_STRUCTURE))) {result++}
        GroupRemoveUnit(units, first)
    } while (first == null)    
    
    return result
Код написан на cJass. Есть ли возможность сделать то же без перебора группы?

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

Может это поможет?
native GetUnitCount           takes integer unitid              returns integer
native GetPlayerUnitTypeCount takes player p, integer unitid    returns integer

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
0
16
6 лет назад
Отредактирован avuremybe
0
ScopteRectuS, с таким подходом можно скопировать сюда пару статей по ядерной физике.
Мало ли, этот код окажется частью ядерного реактора.
0
21
6 лет назад
0
avuremybe, да, всё верно. Теперь мы мыслим одинаково. )
0
9
6 лет назад
0
Вообще, функция "GetPlayerUnitCount()" делает то, что нужно: считает количество боевых единиц (не зданий) у игрока. Единственное - считает, также, и вызванных. Поэтому без перебора, возможно, обойтись и не удастся.
0
16
6 лет назад
0
nup4ik, а она сама разве не на переборе работает?
0
9
6 лет назад
0
avuremybe, к сожалению, не погрузился пока так глубоко.
0
23
6 лет назад
0
чем не угодил создать группу через фильтр другого не дано
0
9
6 лет назад
0
pro100master, какая функция для создания через фильтр?
0
32
6 лет назад
0
ну та же GroupEnumUnitsInRange, берет болекспр, это тот самый фильтр. В отдельной функции описываешь кого нужно выбрать
вот пример фильтра:
function EnemyFilter takes nothing returns boolean
    set bj_lastFilterUnit = GetFilterUnit( )
    return GetUnitState( bj_lastFilterUnit, UNIT_STATE_LIFE ) > 0.405 and IsUnitEnemy( bj_lastFilterUnit, bj_groupEnumOwningPlayer ) and not( IsUnitType( bj_lastFilterUnit, UNIT_TYPE_MAGIC_IMMUNE ) or IsUnitType( bj_lastFilterUnit, UNIT_TYPE_MECHANICAL ) or IsUnitInvulnerable( bj_lastFilterUnit ) or IsUnitWard( bj_lastFilterUnit ) )
endfunction
))
0
9
6 лет назад
0
Но у тебя BJ-функция GetUnitsInRectOfPlayer утекает =(( и группой в конце не удаляем
Правильно ли я понимаю, что любая функция, возвращающая объект, "утекает", а избежать утечки можно, записав этот объект в переменную и затем, по окончании работы функции, удалив? То есть, такой код содержит утечки памяти:
group units = GetUnitsInRectOfPlayer(GetPlayableMapRect(), Player(id))
А такой - не содержит:
player pl = Player(id)
rect map = GetPlayableMapRect()
group units = GetUnitsInRectOfPlayer(map, pl)
...
RemovePlayer(pl)
RemoveRect(map)
DestroyGroup(units)
Немного переосмыслил предыдущий ответ. На деле, функции типа "RemovePlayer", "RemoveUnit" и т.д., удаляют объекты, и данные объекты удалятся из игры вообще. То есть, если в событии "Боевая единица умирает" получить "KillingUnit" (убивший), и затем вызвать к нему "RemoveUnit()", то и эта боевая единица, также, удалится с карты.
То есть, удалять объекты, во избежание утечек, надо только в тех ситуациях, когда вызванная функция генерирует новый объект, который не используется после завершения работы функции. Здесь поможет только понимание внутренней логики работы этих функций и, в общем, игры. В остальных случаях, думаю, достаточно просто "map = null", притом, как мне кажется, эта строка будет равносильна "int = 0" (обнулению числовой переменной), то есть, в ней отсутствует острая необходимость (только если количество ссылок на объекты не учитывается интерпретатором, как в некоторых современных языках программирования).
Думаю, это верное понимание, возможно, в деталях был неточен.
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.