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

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

Закрытая тема
 
Enein
Silenced by ZlaYa1000
offline
Опыт: 43,453
Активность:
Триггер "ломается" со временем
Есть код спелла:
» code
scope oms initializer Init

  globals
    private trigger A
    private group B
  endglobals

  private function ActionsFinish takes nothing returns nothing
    local unit t = GetTriggerUnit()
    local unit a = GetEventDamageSource()
    call UnitRemoveAbility(a, 'B000')
    //...
    set t = null
    set a = null
  endfunction

  private function ConditionsFinish takes nothing returns boolean
    return GetUnitAbilityLevel(GetEventDamageSource(), 'B000') == 1
  endfunction

  private struct spell
    static spell array data
    static integer count = 0
    static timer timer = CreateTimer()
    unit a
    static method onTimer takes nothing returns nothing
        local integer i = 0
        loop
            if GetUnitAbilityLevel(spell.data[i].a, 'B000') == 0 then
                call spell.data[i].destroy()
                set spell.count = spell.count - 1
                set spell.data[i] = spell.data[spell.count]
                set i = i - 1
                if spell.count == 0 then
                    call PauseTimer(spell.timer)
                endif
            endif
            set i = i + 1
            exitwhen i >= spell.count
        endloop
    endmethod

    static method create takes unit a returns spell
        local spell s = spell.allocate()
        if spell.count == 0 then
            call TimerStart(spell.timer, .1, true, function spell.onTimer)
        endif
        set spell.data[spell.count] = s
        set spell.count = spell.count + 1
        set s.a = a
        //...
        return s
    endmethod
    
    method onDestroy takes nothing returns nothing
        //...
        set .a = null
    endmethod

  endstruct

  private function Actions takes nothing returns nothing
    call spell.create(GetTriggerUnit())
  endfunction

  private function Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A000'
  endfunction

  private function ActionsDamage takes nothing returns nothing
    local unit t = GetTriggerUnit()
    call GroupAddUnit(B, t)
    call TriggerRegisterUnitEvent(A, t, EVENT_UNIT_DAMAGED)
    set t = null
  endfunction

  private function ConditionsDamage takes nothing returns boolean
    return not IsUnitInGroup(GetTriggerUnit(), B) and GetUnitAbilityLevel(GetAttacker(), 'B000') == 1
  endfunction

  private function Init takes nothing returns nothing
    local trigger t = CreateTrigger()
    local trigger r = CreateTrigger()
    local integer i = 0
    set A = CreateTrigger()
    set B = CreateGroup()
    loop
        call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
        call TriggerRegisterPlayerUnitEvent(r, Player(i), EVENT_PLAYER_UNIT_ATTACKED, null)
        set i = i + 1
        exitwhen i > 12
    endloop
    call TriggerAddCondition(t, Condition(function Conditions))
    call TriggerAddAction(t, function Actions)
    call TriggerAddCondition(r, Condition(function ConditionsDamage))
    call TriggerAddAction(r, function ActionsDamage)
    call TriggerAddCondition(A, Condition(function ConditionsFinish))
    call TriggerAddAction(A, function ActionsFinish)
    set t = null
    set r = null
  endfunction

endscope
Что он делает:
При использовании на юнита вешается бафф 'B000'. Первое нанесение урона этим юнитом кому-либо должно снимать бафф и выполнять кое-какие действия в структуре. Все отлично работает минут 20-30 активного использования, но потом внезапно перестаёт (сниматься бафф, а следовательно и перестают выполнятся действия в структуре, когда мне это надо).
Влияние стронних триггеров/систем и т.п. исключено.
Вылавливать все условия, при которых система даёт сбой - большой гемор, поэтому.. чо посоветуете?
Старый 18.01.2011, 03:40
J64_

offline
Опыт: 4,724
Активность:
Останавливай таймер после цикла. Помоему так.
Есчо для малой оптимизации в добавь else и там увеличивай счетчик, ато лишние присвоения.
Старый 18.01.2011, 04:30
DioD

offline
Опыт: 45,134
Активность:
где отладочные сообщения?
Старый 18.01.2011, 05:28
Zanozus
Уехал учиться
offline
Опыт: 8,512
Активность:
возможно у тебя переполняется группа мертвыми юнитами или что-то в этом роде.
попробуй очищать группу или удалять умерших юнитов.
И зачем вобще эта группа ? Ты сначала добавляешь юнита в группу и добавляешь событие что этот юнит получил урон, а в действиях опять проверяешь в группе ли этот юнит.
или я что-то не так понял ?
А всё понял, у тебя юнит удаляется из группы, у тебя в коде это выпущенно. Может заменить
группу логической переменной приаттаченной к юниту ?
Старый 18.01.2011, 12:56
ScorpioT1000
Работаем
online
Опыт: отключен
Попробуй:


// ifdebug library



// spell

scope oms initializer Init

  globals
    private trigger A
    private group B
  endglobals

  private function ActionsFinish takes nothing returns nothing
    local unit t = GetTriggerUnit()
    local unit a = GetEventDamageSource()
    IFDEBUG(t==null or a==null, )
    call UnitRemoveAbility(a, 'B000')
    //...
    set t = null
    set a = null
  endfunction

  private function ConditionsFinish takes nothing returns boolean
    return GetUnitAbilityLevel(GetEventDamageSource(), 'B000') == 1
  endfunction

  private struct spell
    static spell array data
    static integer count = 0
    static timer timer = CreateTimer()
    unit a
    static method onTimer takes nothing returns nothing
        local integer i = 0
        loop
            if GetUnitAbilityLevel(spell.data[i].a, 'B000') == 0 then
                call spell.data[i].destroy()
                set spell.count = spell.count - 1
                set spell.data[i] = spell.data[spell.count]
                set i = i - 1
                if spell.count == 0 then
                    IFDEBUG(spell.timer==null, )
                    call PauseTimer(spell.timer)
                endif
            endif
            set i = i + 1
            exitwhen i >= spell.count
        endloop
    endmethod

    static method create takes unit a returns spell
        local spell s = spell.allocate()
        IFDEBUG(a==null, 0)
        if spell.count == 0 then
            IFDEBUG(spell.timer == null, 0)
            call TimerStart(spell.timer, .1, true, function spell.onTimer)
        endif
        set spell.data[spell.count] = s
        set spell.count = spell.count + 1
        set s.a = a
        //...
        return s
    endmethod
    
    method onDestroy takes nothing returns nothing
        //...
        set .a = null
    endmethod

  endstruct

  private function Actions takes nothing returns nothing
    IFDEBUG(GetTriggerUnit()==null, )
    call spell.create(GetTriggerUnit())
  endfunction

  private function Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A000'
  endfunction

  private function ActionsDamage takes nothing returns nothing
    local unit t = GetTriggerUnit()
    IFDEBUG(t==null, )
    call GroupAddUnit(B, t)
    call TriggerRegisterUnitEvent(A, t, EVENT_UNIT_DAMAGED)
    set t = null
  endfunction

  private function ConditionsDamage takes nothing returns boolean
    IFDEBUG(GetTriggerUnit()==null or GetAttacker()==null, false)
    return not IsUnitInGroup(GetTriggerUnit(), B) and GetUnitAbilityLevel(GetAttacker(), 'B000') == 1
  endfunction

  private function Init takes nothing returns nothing
    local trigger t = CreateTrigger()
    local trigger r = CreateTrigger()
    local integer i = 0
    set A = CreateTrigger()
    set B = CreateGroup()
    loop
        call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
        call TriggerRegisterPlayerUnitEvent(r, Player(i), EVENT_PLAYER_UNIT_ATTACKED, null)
        set i = i + 1
        exitwhen i > 12
    endloop
    call TriggerAddCondition(t, Condition(function Conditions))
    call TriggerAddAction(t, function Actions)
    call TriggerAddCondition(r, Condition(function ConditionsDamage))
    call TriggerAddAction(r, function ActionsDamage)
    call TriggerAddCondition(A, Condition(function ConditionsFinish))
    call TriggerAddAction(A, function ActionsFinish)
    set t = null
    set r = null
  endfunction

endscope
а вобще это говнокод какойто:
static timer timer = CreateTimer()
и куча копипасты вместо constant integer spellraw1 = 'B000'
Старый 18.01.2011, 14:09
Enein
Silenced by ZlaYa1000
offline
Опыт: 43,453
Активность:
AdamanTX, уволен
Zanozus, уволен
static timer timer = CreateTimer()
?
и куча копипасты вместо constant integer spellraw1 = 'B000'
лол зачем?
Enein добавил:
и как всегда, по делу ниразу не отвечено -_- но сумничать попытался каждый
Старый 18.01.2011, 17:39
Hanabishi
COOL STATUS
offline
Опыт: отключен
о великий разработчик эвикса Enein, ты разве не знаешь, что в варике триггерам свойственно ломаться когда они натыкаются на ошибки?
method onDestroy
это ЗЛО корень всех твоих бед
люди никогда не используйте это ЗЛО
Старый 18.01.2011, 18:01
Enein
Silenced by ZlaYa1000
offline
Опыт: 43,453
Активность:
еще один клоун
структура работает безотказно всю игру, ломается триггер A
Старый 18.01.2011, 18:05
Hanabishi
COOL STATUS
offline
Опыт: отключен
Enein
  1. onDestroy создаёт триггер с ивентом
2)
	call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
        call TriggerRegisterPlayerUnitEvent(r, Player(i), EVENT_PLAYER_UNIT_ATTACKED, null)
а теперь суть: ИВЕНТЫ НЕ УДАЛЯЮТСЯ ПОСЛЕ УДАЛЕНИЯ ТРИГГЕРА
Старый 18.01.2011, 18:10
Icy
Это Я!
offline
Опыт: 1,785
Активность:
1 - ____
2 - чушь написал!
Enein, почему я в коде увидел
  private function ActionsDamage takes nothing returns nothing
    local unit t = GetTriggerUnit()
// Это \/
    call GroupAddUnit(B, t)
//
    call TriggerRegisterUnitEvent(A, t, EVENT_UNIT_DAMAGED)
    set t = null
  endfunction
Но не увидел
  private function ActionsFinish takes nothing returns nothing
    local unit t = GetTriggerUnit()
    local unit a = GetEventDamageSource()
    call UnitRemoveAbility(a, 'B000')
// Этого \/
    call GroupRemoveUnit(B, t)
//
    //...
    set t = null
    set a = null
  endfunction
?
Icy добавил:
Получается что абилка работает только на тех юнитов, которых ещё не атаковал засранец с бафом
Насчёт обрыва какого то трига и прекращение удаления бафа, я ничего сверхестественного не заметил
Вижу что скил переносил в пустую карту, значит посторонние косяки: "Влияние стронних триггеров/систем и т.п. исключено."
Icy добавил:
Ах да:
Скорпи ты как всегда =)
ScorpioT1000:
вобще это говнокод какойто
Старый 18.01.2011, 18:30
Enein
Silenced by ZlaYa1000
offline
Опыт: 43,453
Активность:
Получается что абилка работает только на тех юнитов, которых засранец с бафом уже атаковал
Если я буду удалять из группы, каждый раз при атаке на юнита будет снова вешаться триггер. Чем вы думаете, а?
Старый 18.01.2011, 18:30
Hanabishi
COOL STATUS
offline
Опыт: отключен
Enein, у тебя в карте есть дебаг количества выделенной памяти?
Hanabishi добавил:
Icy, сам не верил
Старый 18.01.2011, 19:26
Enein
Silenced by ZlaYa1000
offline
Опыт: 43,453
Активность:
ConditionsDamage и ActionsFinish относятся к разным триггерам, клоун
Старый 18.01.2011, 19:45
Enein
Silenced by ZlaYa1000
offline
Опыт: 43,453
Активность:
18:49:36: да они тупые ппц
18:49:51: но каждый считает себя мог кодером же
18:50:06: ну смотри - у нашего героя есть BUFF
18:50:29: когда он атакует кого-то - мы забрасываем атакованного в триггер
18:51:47: ну и по стандарту каждый раз, когда он будет атаковать - будет срабатывать действие и этот атакованный юнит КАЖДЫЙ РАЗ БУДЕТ ЗАБРАСЫВАТЬСЯ В ТРИГГЕР
18:52:32: зачем нам при каждой атаке выполнять уже выполненное ранее действие?
18:53:42: если юнит атакован - на нем до конца игры (или пока не уничтожим триггер) будет срабатывать нанесение урона
18:54:25: поэтому создаем группу, что дает нам возможность не записывать юнита повторно в триггер нанесения урона
18:54:48: =О
Старый 18.01.2011, 19:58
Icy
Это Я!
offline
Опыт: 1,785
Активность:
По сабжу: есть конечно извращенский, но всё же способ: обновлять каждые пять минут(например) триггер отвечающий за отлов дамага, за мазахизм не отвечаю, но помочь должно
Icy добавил:
Enein, именно это я и понял... Щас сижу втыкаю в код и думаю чё за Х*** с ним
Старый 18.01.2011, 20:03
Enein
Silenced by ZlaYa1000
offline
Опыт: 43,453
Активность:
да, это xgm...
таки гораздо быстрее я найду ответ через
отладочные сообщения
позже отпишусь, в чем была проблема)
Enein добавил:
расставил дебаги, ~полчаса мы наблюдали за сообщениями
все не ломалось и не ломалось.. вскоре надоело и ушли
Enein добавил:
ну и фиг с ним О_О
Старый 18.01.2011, 22:06
Закрытая тема

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

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

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

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



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