Не могу понять как добавить в функции GroupEnumUnitsInRange фильтр, который добавлял бы в группу только врагов кастера.
Пробовал делать функцию фильтр, которая фильтровала бы юнитов. (возвращает boolean) Для типов юнитов это работает, но как прописать в фильтр враждебность к игроку - понять затрудняюсь. (интерег игрока различается в зависимости от кастующего)
В общем, какими способами можно заставить добавлять в группу юнитов только врага другого юнита?

Обычно в группу собираю всех юнитов, перебирая их вручную через цикл
Вот только фильтры куда быстрее циклов (JASS плохо справляется с циклами), а внутри фильтров можно делать абсолютно все необходимые действия.
Не могу понять как добавить в функции GroupEnumUnitsInRange фильтр, который добавлял бы в группу только врагов кастера.
Ниже пример, когда группа вообще не заполняется, а нужна только для вызова фильтра, чтобы выполнить нужные действия.
globals
    player P
endglobals

function filter takes nothing returns boolean
    if IsUnitEnemy(GetFilterUnit(), P) then
        // твои действия
    endif
    return false
endfunction

function f takes integer i, real x, real, y, real range returns nothing
    set P = Player(i)
    call GroupEnumUnitsInRange(bj_lastCreatedGroup, x, y, range, function filter)
endfunction
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
15
Что же, очень хорошо, теперь будут знать.
Вряд ли это можно назвать хорошо. Эта та часть синтаксиса, что приводит к серьезной неразберихе. Подумать только, совершенно неявное приведение.
PT153:
Про этот сахар написано в мануале JassHelper? Я вот что-то не помню.
Да, написано. В самом низу, в ченжлоге
0.A.0.0
  • . or this. are not required anymore to use members. Note that this may cause issues if for some (incredibly weird) reason you try to use global variables from a method of a struct that has variables of the same name. To disable this feature, you can add [noimplicitthis] to jasshelper.conf.
  • Improved the syntax error when you place a function inside a struct.
  • Code values might get implicitly casted to boolexpr in some occasions, specifically, when using them as arguments for natives/bjfunc that take boolexpr. More cases will get added when type safety gets on its way for more stuff...
Я не включил этот момент в перевод, о чем в итоге сам напрочь забыл.Все таки стоило.
28
Да, написано. В самом низу, в ченжлоге
Было бы неплохо вытащить это из чейнжлога в отдел Jass Syntax extensions.
И это никак нельзя отключить, печально. :(
Вряд ли это можно назвать хорошо. Эта та часть синтаксиса, что приводит к серьезной неразберихе. Подумать только, совершенно неявное приведение.
Хорошо, что теперь я и многие другие знают о таком сахаре.

Вообще, JassHelper любит кое-что менять не уведомляя.
Вот например, я забыл поставить равно.
globals
    boolean B true
endglobals
JassHelper превратит это в
globals
    boolean B
endglobals
То есть B будет без значения, и когда я буду его использовать, ожидая там изначальное значение, поток прервётся.
Хорошо, что последний pjass может такие случаи вывести на поверхность.
16
filter и condition - одно и то же, у них свой поток, это да
перебор группы в цикле медленнее, но удобнее и гарантированно локальные. Если события могут привести к срабатыванию этой же группировки во время обработки цикла, локальные переменные останутся нетронутыми, а глобалки могут перезатереться. Например, если мы собирает группу в действии триггера, реагирующего на урон, и наносит каждому юниту в группе урон, получится еще один вызов, который перебьет общие глобалки, и дальше первый проход по группе пойдет не по плану. Нужно четко осознавать, когда какой подход выгоднее.
24
DracoL1ch, настоящий отдельный поток или варовский "последовательный" отдельный поток? Пример с нанесением урона удавалось повторить на практике или это теоретическое рассуждение? Я просто помню, что активно пользовался кодом в фильтрах и кондишнах и как-то этого типа "багов" не возникало.
28
Пример с нанесением урона удавалось повторить на практике или это теоретическое рассуждение?
Я так понял, он имел ввиду такой случай.
В триггере на получение урона юниты выбираются группой и в фильтре им наносится урон, то есть триггер срабатывает ещё раз, глобалки перезаписываются. На практике вар просто вылетит из-за зацикливания события.
32
фильтры на то и фильтры чтобы в них делать проверки на не инициировать события, в том числе нанесение урона. Лич же писал про ForGroup куда передаются глобалками данные, нужно либо иметь глобалки которые нигде более не используются кроме как для ForGoup потоков в таких местах, где не может быть перезаписи из за инициации другого события, к примеру наносить урон в спеллах которые по типу волны силы или стомпа, при этом абики срабатывающие на урон эти глобалки не юзают. Это все к тому - думайте своей головой что и как юзать, учитывайте взаимодействие и зацикливания событий.
16
prog:
Пусть у меня пассивка, которая в ответ на входящий урон наносит урон в ответ по аое, типа пассивки вайпера, но с одним зарядом (чтобы не крашнуться от вечного цикла) и в аое
Встретились два вайпера, №1 получил урон от второго и инициирует ответный урон в аое, в котрое входит №2, я использую глобалки:
function Nanesti_Uron_v_aoe takes nothing returns nothing
call DamageTarget(tt_unit1,GetEnumUnit(),100)//типа 100 урона по юниту в группе
//... здесь сработает триггер на урон и мы придём сюда уже с новой глобалкой
call BJDebugMsg("damage dealt by "+GetUnitName(tt_unit1)+" to "+GetUnitName(GetEnumUnit()))//дважды увидим имя вайпера №2 в первой части, во второй части будет №1, затем №2
//если здесь были любые операции с tt_unit1, они пойдут неверно
endfunction

... set tt_unit1=GetTriggerUnit()//типа вайпер №1
call ForGroup(g,function Nanesti_Uron_v_aoe)//в группу попал №2
Очевидно, если действие одно и обращения к глобалке (после потенциально-вызывающего-такое-же-событие действия) нет, то пофиг на пересечение
Варкрафт строго линеен, "поток" лишь определяет то, есть ли шанс упереться в лимит операций или нет. Новый поток - снова 300к операций, гуляй душа. В цикле по FirstOfGroup, если в группе СУПЕР много юнитов или действий над ними супер много, упереться возможно.
24
DracoL1ch, спасибо за подробный разбор. Значит ничего не поменялось за годы пока я не трогал вар и все потоки как были последовательными, так и остались.
А проблема перезаписи глобалок в такой ситуации должна решаться очень просто - записываем значение глобалки в локалку при срабатывании события и потом в конце обработчика события возвращаем глобалке старое значение. Насколько я знаю, невозможна ситуация, когда вклинившееся событие вернет управление в предыдущий поток не закончив свой обработчик (не считая вейтов).
16
интересный подход, должно сработать, но, как говорится, нахера козе баян? Своя сфера применимости и всё
28
Варкрафт строго линеен
Тогда выходит, что 2 события не могут одновременно произойти ни при каких условиях?
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.