XGM Forum
Сайт - Статьи - Проекты - Ресурсы - Блоги

Форуме в режиме ТОЛЬКО ЧТЕНИЕ. Вы можете задать вопросы в Q/A на сайте, либо создать свой проект или ресурс.
Вернуться   XGM Forum > Warcraft> Академия: форум для вопросов> Jass
Ник
Пароль
Войти через VK в один клик
Сайт использует только имя.

Закрытая тема
 
Faion
Noblesse Oblige
offline
Опыт: 30,395
Активность:
Эвенты
Достаточно стандартная конструкция для отлова события применения способности:
Код:
function funcname takes nothing returns nothing
    trigger trig = CreateTrigger()
    integer i = 0
    loop
        TriggerRegisterPlayerUnitEvent(trig,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,fun  ction func_condition)
        i = i + 1
        exitwhen i == 11
    endloop
    TriggerAddAction(trig, function fun_action)
    trig = null
endfunction


Конечно лучше Бж, но все же, если мы имеем сотни способностей, и для каждой существует подобная конструкция, то выйдет, что TriggerRegisterPlayerUnitEvent сработает столько раз, сколько существует конструкция.

В прочем подобная вещь не особо ощутимо сказывается на производительности, но все же.
Как то давно я видел через 1 эвент обрабатывать все имеющиеся способности. Людей которые шарят в этом вопросе прошу показать свой пример решения данной проблемы, или линк на тему в которой обсуждался данный вопрос.
Старый 26.02.2011, 14:47
Feronetick

offline
Опыт: 86
Активность:
TriggerRegisterPlayerUnitEvent(trig,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,fun ction func_condition) поправь :)
Старый 26.02.2011, 14:51
reALien

offline
Опыт: 29,211
Активность:
делаю точно так же)
Старый 26.02.2011, 14:53
Faion
Noblesse Oblige
offline
Опыт: 30,395
Активность:
Цитата:
Сообщение от Feronetick
TriggerRegisterPlayerUnitEvent(trig,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,fun ction func_condition) поправь :)

это просто форум так отображает, там то все норм.
Цитата:
Сообщение от reALien
делаю точно так же)

Да в том то и дело, что все так делают. Но вроде тк где то светил метод делать тоже самое, но через 1 эвент, типо по умному=)
Старый 26.02.2011, 14:55
reALien

offline
Опыт: 29,211
Активность:
Через гетлокал плеер предлагали, не юзаю по религиозным причинам
Старый 26.02.2011, 14:59
Faion
Noblesse Oblige
offline
Опыт: 30,395
Активность:
Там просто в чем фича, мало того что эвент сработает 100500 раз, так еще и цикл прокрутится кол-во эвентов*12. Дикое расточительство ресурса машины=)

Faion добавил:
Цитата:
Сообщение от reALien
Через гетлокал плеер предлагали, не юзаю по религиозным причинам


Это лишь сократит кол-во срабатываний в 12 раз, но обращений будет по прежнему куча, но идея дельная оч даже.
Старый 26.02.2011, 15:02
Hanabishi
COOL STATUS
offline
Опыт: отключен
Faion, разницы с бж здесь немного, но я делаю сам как участник сообщества антибж=)
ты это имел ввиду? сделать разные функции с подачей нужных аргументов
function Abil_A000 takes unit u returns nothing
    //actions
endfunction

function Abil_A001 takes real x, real y returns nothing
    //actions
endfunction

function AbilSeparator takes nothing returns nothing
    if GetSpellAbilityId()=='A000' then
        call Abil_A000(GetSpellAbilityUnit())
    elseif GetSpellAbilityId()=='A001' then
        call Abil_A001(GetSpellTargetX(),GetSpellTargetY())
    endif
endfunction

function Init takes nothing returns nothing
    local trigger abil_trg = CreateTrigger()
    local integer i = 0
    loop
    exitwhen(i>11)
        call TriggerRegisterPlayerUnitEvent(abil_trg,Player(i),EVENT_PLAYER_UNIT_SPELL_CAST,null)
        set i = i+1
    endloop
    call TriggerAddAction(abil_trg,function AbilSeparator)
    set abil_trg = null
endfunction
Старый 26.02.2011, 15:08
Faion
Noblesse Oblige
offline
Опыт: 30,395
Активность:
У меня собсно есть некоторые идеи, но не думаю что идея рациональна.

Код:
function func_cond takes nothing returns boolean
    // список всех абилок
    return GetSpellAbilityId() == наша абилка.
endfunction

function funcname takes nothing returns nothing
    trigger trig = CreateTrigger()
    // сокращаем уже в 12 раз вызовы
    if (GetLocalPlayer() == GetTriggerPlayer()) {TriggerRegisterPlayerUnitEvent(trig,GetTriggerPlayer(),EVENT_PLAYER_UNIT_SPELL_  EFFECT,function func_condition)}    
    // вызываем через 1 эвент любое количество экшнов
    TriggerAddAction(trig, function LoadStr(h,GetHandleId(GetSpellAbility()),0) 
    trig = null
endfunction


Мне кажется есть способ круче=)
Старый 26.02.2011, 15:12
Hanabishi
COOL STATUS
offline
Опыт: отключен
TriggerAddAction(trig, function LoadStr(h,GetHandleId(GetSpellAbility()),0) 
за такое как минимум тебя пошлёт компилятор
а ещё можно сделать несколько TriggerAddAction через цикл
Hanabishi добавил:
тогда триггер запустит все аттаченые на него функции разом
Старый 26.02.2011, 15:24
Faion
Noblesse Oblige
offline
Опыт: 30,395
Активность:
Цитата:
Сообщение от Hanabishi
за такое как минимум тебя пошлёт компилятор


И правда посылает.

Но если сделать так:

Код:
ExecuteFunc(LoadStr(h,GetHandleId(GetSpellAbility()),0))


То не пошлет, а смысл вроде тот же будет.
Старый 26.02.2011, 15:28
Hanabishi
COOL STATUS
offline
Опыт: отключен
Faion, тоже пошлёт, т.к. в AddAction можно толкать только функции без аргументов
Hanabishi добавил:
и если ещё учесть невозможность code array то всё равно придётся писать вручную
Старый 26.02.2011, 15:33
Faion
Noblesse Oblige
offline
Опыт: 30,395
Активность:
Hanabishi, так я вынес предложение вместо аддэкшн, использовать ExecuteFunc. Поидее должно работать.
TriggerRegisterPlayerUnitEvent работает вроде так, что если там false, то код ниже не срабатывает, а если сработал, то в нашем случае должен запустить нужную нам функци.

Да и аддэкшн не рулит, по той причине, что способности разместить в 1 триггере... это анриал.
Тут суть темы в создании\нахождении самого лучшего способа обрабатывать события.

Далее если такой вариант использовать, то просто создается бд где сейвятся func_name нужные.
Возможно даже можно обойтись без хт, типо использовать массив.

GetSpellAbilityId() это же int, и как я понимаю можно сделать вот что: 'A000' == 40960 ж, юзать абилити ид - 40960, как индекс в массиве. И хранить это все в массиве, таким образом сделаем тоже самое и без ХТ.

Типо как то так:
Код:
ExecuteFunc(str[GetSpellAbilityId()-40960])

Я подобное не пробовал, так что вполне может быть что я предложил полный бред=)
Старый 26.02.2011, 15:41
Hanabishi
COOL STATUS
offline
Опыт: отключен
Faion, всё равно придётся в массив вручную забивать
точнее не массив а хэш, т.к. массив имеет индекс [0..8191]
Старый 26.02.2011, 15:46
Faion
Noblesse Oblige
offline
Опыт: 30,395
Активность:
Цитата:
Сообщение от Hanabishi
всё равно придётся в массив вручную забивать


Да, но зато нам не нужно будет писать в каждом спеле конструкцию.

Код:
function funcname takes nothing returns nothing
    trigger trig = CreateTrigger()
    integer i = 0
    loop
        TriggerRegisterPlayerUnitEvent(trig,Player(i),EVENT_PLAYER_UNIT_SPELL_EFFECT,fun    ction func_condition)
        i = i + 1
        exitwhen i == 11
    endloop
    TriggerAddAction(trig, function fun_action)
    trig = null
endfunction


Это будет заменено 1-й строчкой.

Кстати, это компилится нормально:

Код:
function func_cond takes nothing returns boolean
    return GetSpellAbilityId() == 'A000'
endfunction

function funcname takes nothing returns nothing
    trigger trig = CreateTrigger()
    if (GetLocalPlayer() == GetTriggerPlayer()) {TriggerRegisterPlayerUnitEvent(trig,GetTriggerPlayer(),EVENT_PLAYER_UNIT_SPELL_  EFFECT,function func_cond)}    
    ExecuteFunc(ss[GetSpellAbilityId()-40960])
    trig = null
endfunction
Старый 26.02.2011, 15:48
Hanabishi
COOL STATUS
offline
Опыт: отключен
Faion, я не пойму что ты имел ввиду, ведь экзекут вызовется 1 раз при ините карты
причём неправильно
Старый 26.02.2011, 16:15
Faion
Noblesse Oblige
offline
Опыт: 30,395
Активность:
Цитата:
Сообщение от Hanabishi
Faion, я не пойму что ты имел ввиду, ведь экзекут вызовется 1 раз при ините карты
причём неправильно

На сколько я знаю, ExecuteFunc просто запускает функцию в отдельном потоке. Конкретно эту функцию не тестировал, но к примеру TriggerExecute() работает на ура
Старый 26.02.2011, 16:19
Hanabishi
COOL STATUS
offline
Опыт: отключен
тогда так
function abil_40960 takes nothing returns nothing
    //actions
endfunction

function AbilSeparator takes nothing returns nothing
    call ExecuteFunc("abil_"+I2S(GetSpellAbilityId())
endfunction

function Init takes nothing returns nothing
    local trigger abil_trg = CreateTrigger()
    local integer i = 0
    loop
    exitwhen(i>11)
        call TriggerRegisterPlayerUnitEvent(abil_trg,Player(i),EVENT_PLAYER_UNIT_SPELL_CAST,null)
        set i = i+1
    endloop
    call TriggerAddAction(abil_trg,function AbilSeparator)
    set abil_trg = null
endfunction
но в любом случае при экзекуте теряются аргуметы
Hanabishi добавил:
поэтому во избежание изврата над глобалками рекомендую вариант из 7 поста
Старый 26.02.2011, 16:30
Faion
Noblesse Oblige
offline
Опыт: 30,395
Активность:
Над будет затестить, а про то что при экзекуте аргументы не передаются, не слышал, и вероятно даж будет лучше 1 раз поизвращатся, чем потом как нить в будущем переписывать все=)
Старый 26.02.2011, 16:37
Hanabishi
COOL STATUS
offline
Опыт: отключен
и ещё если в экзекут послать имя несуществующей функции, будет фатал
Старый 26.02.2011, 16:42
Faion
Noblesse Oblige
offline
Опыт: 30,395
Активность:
Цитата:
Сообщение от Hanabishi
и ещё если в экзекут послать имя несуществующей функции, будет фатал


Эт проблема решается проверкой if var != null {} =)

Faion добавил:
Тему можно на свалку=)
Старый 26.02.2011, 16:56
Закрытая тема

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы можете скачивать файлы

BB-коды Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход



Часовой пояс GMT +3, время: 16:32.