Как работает функция(или что это такое) Filter?
Копнув, нашёл такие вот конструкции:
call TriggerAddCondition(xIx,Filter(function UVo))
//или
function vlx takes nothing returns boolean
return true
endfunction

set vdx=Filter(function vlx)
Хотелось бы узнать что они делают и как это можно использовать

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

ну это условие. отличие в том, что с помощью этих фильтров можно отсеивать не нужных юнитов, игроков, итемов, декорации. даже в регистре событии можно указать на каких-юнитов не может срабатывать. вот пример, вы выбираете через нативку EnumGroup юнитов, и вам нужно отсеять не нужных юнитов, и подобрать нужных. Например, нужно вражеский герой:
function A takes nothing returns boolean
return IsUnitType(GetFilterUnit(), UNIT_TYPE_HERO) and IsUnitEnemy(GetFilterUnit(), Player(0))
endfunction
local boolexpr b = Condition(function A)
call GroupEnumUnitsInRange(g, x, y, 900, b)
в группу добавляются только герои. тут с логическими условиями работать надо, составляя конструкции (условие 1) и/или (условие 2). Например, нужно вражеский герои либо здание. и так далее
хотя здесь фильтр и условие ничем не отличаются. когда юниты добавляются в группу через GroupEnumUnitsInRange, тут стоит фильтр. Если вернет true пропускает, а false отсеивает, удаляет. Здесь точно также как условие триггера
событие - активировал абилу
условие - id абилы == "..." <= точно также
раньше почему думал что там цикл. что берет всю группу перебирает всех и фильтрует. это не точно. это самый настоящий фильтр.
`
ОЖИДАНИЕ РЕКЛАМЫ...
3
28
6 лет назад
Отредактирован PT153
3
Разницы между Filter() и Condition() нет. Обе функции создают boolexpr, который можно использовать как условия в функциях групп, кланов и событий триггеров и для создания условий в триггерах. Текущий проверяемый объект можно получить с помощью функции GetFilter<>(), где <> - имя объекта (Unit, Item, Player). А ещё их можно вот так использовать.
4
27
6 лет назад
Отредактирован MpW
4
ну это условие. отличие в том, что с помощью этих фильтров можно отсеивать не нужных юнитов, игроков, итемов, декорации. даже в регистре событии можно указать на каких-юнитов не может срабатывать. вот пример, вы выбираете через нативку EnumGroup юнитов, и вам нужно отсеять не нужных юнитов, и подобрать нужных. Например, нужно вражеский герой:
function A takes nothing returns boolean
return IsUnitType(GetFilterUnit(), UNIT_TYPE_HERO) and IsUnitEnemy(GetFilterUnit(), Player(0))
endfunction
local boolexpr b = Condition(function A)
call GroupEnumUnitsInRange(g, x, y, 900, b)
в группу добавляются только герои. тут с логическими условиями работать надо, составляя конструкции (условие 1) и/или (условие 2). Например, нужно вражеский герои либо здание. и так далее
хотя здесь фильтр и условие ничем не отличаются. когда юниты добавляются в группу через GroupEnumUnitsInRange, тут стоит фильтр. Если вернет true пропускает, а false отсеивает, удаляет. Здесь точно также как условие триггера
событие - активировал абилу
условие - id абилы == "..." <= точно также
раньше почему думал что там цикл. что берет всю группу перебирает всех и фильтрует. это не точно. это самый настоящий фильтр.
Принятый ответ
3
28
6 лет назад
Отредактирован PT153
3
local boolexpr b = Condition(function A)
call GroupEnumUnitsInRange(g, x, y, 900, b)
Не надо такие сложности, можно сразу function A передавать. Да и в boolexpr можно что угодно делать, а не только возвращать логическую.
Вот один из примеров, как я их использую. Отсеиваю ненужных в фильтре и там же выполняю необходимые действия. Так как возвращаемый тип nothing, то фильтр всегда возвращает 0, что является ложью, и потому никто в группу не добавляется.
    static method filter takes nothing returns nothing
        local Minion m = GetUnitUserData(GetFilterUnit())
        if IsUnitMinion(GetFilterUnit()) and IsUnitType(m.minion, UNIT_TYPE_GROUND) and m.isFieldAlive and m.owner == TransCaster.owner and m.data.nonheroic then
            if m.typ != KnightId then
                call BuffInspiration.launch(m, TransCaster, DefaultArmorBonus, DefaultMoveSpeedBonus)
            elseif not TransKnightPresense then
                set TransKnightPresense = m != TransCaster
            endif
        endif
    endmethod
    
    private static Minion TransCaster
    private static boolean TransKnightPresense
    
    method cooldownEnd takes nothing returns nothing
        local Minion m = caster
        local integer bonus
        set TransCaster = m
        set TransKnightPresense = false
        call GroupEnumUnitsInRange(bj_lastCreatedGroup, GetUnitX(m.minion), GetUnitY(m.minion), abildata.range, function thistype.filter)
        if m.data.upgrade[Knight.LordsId] then
            set bonus = B2I(TransKnightPresense) * Knight.Lords_ArmorByKnight
            set m.s_physarm = bonus
            set m.s_magcarm = bonus
            call m.updateArmor()
        endif
    endmethod
0
27
6 лет назад
0
PT153, просто мне пишет: Cannot convert codere turns boolean to boolexpr
ну это понятно, главное вернуть boolean (условие), ааа у тебя filter ничего не возвращает (nothing) как это возможно. Но мне пишет одну и ту же ошибку, что нельзя конверкнуть в ...
ладно забейте. не так важно это
0
28
6 лет назад
Отредактирован PT153
0
Cannot convert codere turns boolean to boolexpr
Ошибки зависят от pjass.exe.
У меня пишет ошибку несоответствия типов (cannot convert code to boolexpr) только там, где я передаю code как аргумент, а не прямую ссылку на функцию.
private function AddMinionAbilityTrigger takes integer T, code init, code leave returns nothing
    if init != null then
        set MinionAbilityHomeInit[T] = CreateTrigger()
        call TriggerAddCondition(MinionAbilityHomeInit[T], Condition(init))
    endif
    if leave != null then
        set MinionAbilityFieldInit[T] = CreateTrigger()
        call TriggerAddCondition(MinionAbilityFieldInit[T], Condition(leave))
    endif
endfunction
как это возможно
Эмпирическим путём выяснил, что JASS забивает на возвращаемый тип. Я делал тесты, где действия и условия у триггеров возвращают real, при этом всё работало. Самый наглядный пример этого есть в структурах.

Код ниже.
struct A
    method M takes nothing returns nothing
        call K.execute()
    endmethod
    
    stub method K takes nothing returns nothing
        call DisplayTextToPlayer(Player(0), 0., 0., "Message")
    endmethod
endstruct
Преобразуется вот во что.
globals
//JASSHelper struct globals:
constant integer si__A=1
integer si__A_F=0
integer si__A_I=0
integer array si__A_V
trigger st__A_K
trigger array st___prototype2
integer f__arg_integer1
integer f__arg_this
endglobals


//Generated method caller for A.K
function sc__A_K takes integer this returns nothing
        call DisplayTextToPlayer(Player(0), 0., 0., "Message")
endfunction

//Generated method executor for A.K
function sx__A_K takes integer this returns nothing
    set f__arg_this=this
    call TriggerExecute(st__A_K)
endfunction

//Generated allocator of A
function s__A__allocate takes nothing returns integer
 local integer this=si__A_F
    if (this!=0) then
        set si__A_F=si__A_V[this]
    else
        set si__A_I=si__A_I+1
        set this=si__A_I
    endif
    if (this>8190) then
        call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Unable to allocate id for an object of type: A")
        return 0
    endif

    set si__A_V[this]=-1
 return this
endfunction

//Generated destructor of A
function s__A_deallocate takes integer this returns nothing
    if this==null then
            call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Attempt to destroy a null struct of type: A")
        return
    elseif (si__A_V[this]!=-1) then
            call DisplayTimedTextToPlayer(GetLocalPlayer(),0,0,1000.,"Double free of type: A")
        return
    endif
    set si__A_V[this]=si__A_F
    set si__A_F=this
endfunction
function sc___prototype2_execute takes integer i,integer a1 returns nothing
    set f__arg_integer1=a1

    call TriggerExecute(st___prototype2[i])
endfunction
function sc___prototype2_evaluate takes integer i,integer a1 returns nothing
    set f__arg_integer1=a1

    call TriggerEvaluate(st___prototype2[i])

endfunction

//Struct method generated initializers/callers:
function sa__A_K takes nothing returns boolean
local integer this=f__arg_this
        call DisplayTextToPlayer(Player(0), 0., 0., "Message")
   return true
endfunction
function sa___prototype2_s__A_K takes nothing returns boolean
 local integer this=f__arg_integer1

        call DisplayTextToPlayer(Player(0), 0., 0., "Message")
    return true
endfunction

function jasshelper__initstructs7678703 takes nothing returns nothing
    set st__A_K=CreateTrigger()
    call TriggerAddCondition(st__A_K,Condition( function sa__A_K))
    call TriggerAddAction(st__A_K, function sa__A_K)
    set st___prototype2[1]=CreateTrigger()
    call TriggerAddAction(st___prototype2[1],function sa___prototype2_s__A_K)
    call TriggerAddCondition(st___prototype2[1],Condition(function sa___prototype2_s__A_K))


endfunction
Тут как действие триггера передаются функция, что возвращает boolean.

Кстати, я же недавно задавал такой же вопрос.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.