Тестирую свою карту (которая еще, конечно, не закончена), и вот иногда, чтобы проверить на утечность и другие траблы времени, оставляю ее на произвол и ухожу по делам. Но дважды, что я оставлял на ночь. Она переставала работать нормально ровно через 6000 сек (по таймеру времени карты). Второй раз я лично сам это наблюдал. То есть вначале юниты начинали бегать на месте, через 10 сек они телепортировались, а еще через 2-3 минуты экран в игре зависал, и даже не откликается. В диспетчере задач игра работает и отвечает, ресурсы не жрет чрезмерно. Утечек за все 6000 сек нет, но что не так, я не понимаю. Триггеров и таймеров или чего-то другого именно на 6000 сек - нет.
Есть идеи в чем проблема?

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

Возможно какой-либо переодический таймер на +- 0.7 сек, заполняющий массивы.
Массив в 8192 закончился, и при подборе свободных ячеек каждый раз уходит в бесконечный луп, который выдаёт лаг в 3 сек и обрывается на оп лимите.
Единственная идея, ибо сам сталкивался с этим
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
1
26
5 лет назад
1
У меня работает на 1.26а. NazarPunk, может из редактора запускал?
0
29
5 лет назад
0
8gabriel8:
У меня работает на 1.26а. NazarPunk, может из редактора запускал?
И из игры тоже, а карта оказывается для 1.2.4e.
А там насколько помню были баги в TriggerAddAction, из-за чего я досих пор в условиях действия пишу.
0
26
5 лет назад
0
Словил этот баг, как и описано, чуть ранее 6000 секунд. Причём понял его так, что часть юнитов триггерно получает приказ Стоп в ответ на другие приказы, а другая часть юнитов просто тупит на базе. Потому предполагаю какой-то косяк в триггерах на создание и движение волн. pAxsIs, ты говорил, что у тебя триггеры создаются, но может есть на них какой лимит. Не пробовал проверять их?
А вообще почему решил плодить триггеры, может саму систему переделать, чтобы использовать переменные по кругу вместо создания триггеров?
0
8
5 лет назад
0
8gabriel8:
pAxsIs, ты говорил, что у тебя триггеры создаются, но может есть на них какой лимит. Не пробовал проверять их?
Могу, конечно, счетчик завести на триггеры, но мне кажется вряд ли есть лимиты на триггеры. Та же дота написана на JASS и у нее каждая способность создает временный триггер. Попробую во всяком случае.
А вообще почему решил плодить триггеры, может саму систему переделать, чтобы использовать переменные по кругу вместо создания триггеров?
Вот пример, как ты представляешь сделать без временного триггера отлов момента удара юнита без создания временного триггера. В момент замаха юнита, на цель создается временный триггер с событием EVENT_UNIT_DAMAGED. Который отлавливает удар, чтобы нанести доп урон.
Альтернативный вариант:
Можно, конечно, написать уже заранее триггер без события и добавлять событие во время замаха. Тогда количество триггеров не изменится, но будут плодиться события, которые нельзя удалить.
Смотреть код
function StunnedSpellDmg_Actions takes unit attacker, unit target, boolean isStunned returns nothing
    if ( !isStunned ) then
        call UnitDamageTarget( attacker, target, ( ( I2R(GetUnitPointValueByType(GetUnitTypeId(attacker))) ) + 1 ), true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_POISON, WEAPON_TYPE_WHOKNOWS )
    else
        call UnitDamageTarget( attacker, target, ( ( 4.00 * I2R(GetUnitPointValueByType(GetUnitTypeId(attacker))) ) + 1 ), true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_POISON, WEAPON_TYPE_WHOKNOWS )
    endif
endfunction

function StunnedSpellDmg_Conditions takes nothing returns boolean
    local trigger trg      = GetTriggeringTrigger()
    local integer trgH     = GetHandleId( trg )
    local unit    attacker = LoadUnitHandle( udg_kiwHash, trgH, StringHash("attacker") )
    local unit    target   = LoadUnitHandle( udg_kiwHash, trgH, StringHash("target") )
    local boolean isBuffed = LoadBoolean( udg_kiwHash, trgH, StringHash("isStunned") )
    
    if GetTriggerEventId() == EVENT_UNIT_DAMAGED then
        if GetEventDamageSource() == attacker then
            call DisableTrigger( trg )
            call StunnedSpellDmg_Actions( attacker, target, isBuffed )
            
            call FlushChildHashtable( udg_kiwHash, trgH )
            call DestroyTriggerEx( trg )
        endif
    else
        call FlushChildHashtable( udg_kiwHash, trgH )
        call DestroyTriggerEx( trg )
    endif
    
    set trg      = null
    set attacker = null
    set target   = null
    
    return false
endfunction

function StunnedSpellDmg_EventReg takes nothing returns nothing
    local trigger trg      = CreateTrigger()
    local unit    target   = GetTriggerUnit()
    local unit    attacker = GetAttacker()
    local integer trgH     = GetHandleId( trg )
    local boolean isBuffed = false
    
    if ( GetUnitAbilityLevel( target, 'BPSE') > 0 ) then
        set isBuffed = true
    endif
    
    
    call TriggerRegisterUnitEvent( trg, target, EVENT_UNIT_DAMAGED )
    call TriggerRegisterTimerEvent( trg, 1, false )
    call TriggerAddCondition( trg, Condition( function StunnedSpellDmg_Conditions ) )
    call SaveUnitHandle( udg_kiwHash, trgH, StringHash("attacker"), attacker )
    call SaveUnitHandle( udg_kiwHash, trgH, StringHash("target"), target )
    call SaveBoolean( udg_kiwHash, trgH, StringHash("isStunned"), isBuffed )
    
    set target   = null
    set attacker = null
    set trg      = null
endfunction

function Trig_Stunned_Conditions takes nothing returns boolean
    return ( ( GetUnitTypeId(GetAttacker()) == udg_arrBTypes_Warriors[1] ) or \\
    ( GetUnitTypeId(GetAttacker()) == udg_arrBTypes_Warriors[2] ) or \\
    ( GetUnitTypeId(GetAttacker()) == udg_arrBTypes_Warriors[3] ) or \\
    ( GetUnitTypeId(GetAttacker()) == udg_arrBTypes_Warriors[4] ) or \\
    ( GetUnitTypeId(GetAttacker()) == udg_arrBTypes_Warriors[5] ) )
endfunction

function Trig_Stunned_Actions takes nothing returns nothing
    call StunnedSpellDmg_EventReg()
endfunction

//===========================================================================
function InitTrig_Stunned takes nothing returns nothing
    set gg_trg_Stunned = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Stunned, EVENT_PLAYER_UNIT_ATTACKED )
    call TriggerAddCondition( gg_trg_Stunned, Condition( function Trig_Stunned_Conditions ) )
    call TriggerAddAction( gg_trg_Stunned, function Trig_Stunned_Actions )
endfunction
NazarPunk:
А там насколько помню были баги в TriggerAddAction, из-за чего я досих пор в условиях действия пишу.
Поподробнее пожалуйста. Что за баги?
0
30
5 лет назад
0
как ты представляешь сделать без временного триггера отлов момента удара юнита без создания временного триггера
0
29
5 лет назад
0
Можно, конечно, написать уже заранее триггер без события и добавлять событие во время замаха. Тогда количество триггеров не изменится, но будут плодиться события, которые нельзя удалить.
Самым попсовым вариантом было и является попадание юнита на карту и добавление ему события "получает урон"
0
8
5 лет назад
Отредактирован pAxsIs
0
Msey:
Самым попсовым вариантом было и является попадание юнита на карту и добавление ему события "получает урон"
Пробовал этот вариант, но это в этом случае будет постоянный рост событий в триггере, как я уже писал. Неужели динамические триггеры могут быть проблемой? И вызывать подобный баг.

Clamp:
Разве у Msey не такие же трудозатраты по количеству событий в итоге? Ведь из комментариев под твоей наработкой:
ScorpioT1000:
это просто штука которая регает "юнит получил урон" на всех юнитов на карте.
0
29
5 лет назад
0
Поподробнее пожалуйста. Что за баги?
В подробностях уже не помню, а гугл нашёл только xgm.guru/p/wc3/165628?postid=313095
для отлова урона можно использовать system-physical-damage-detection , там можно модифицировать урон.
0
26
5 лет назад
0
pAxsIs, чтобы обнулить события, есть действие, которое приводит триггер в первоначальное состояние. Можно заносить юнитов в виде событий и в группу, триггер на смерть будет удалять из группы, потом, например, каждые 5 минут обновлять триггер до первоначального состояния и сразу добавлять туда события на членов группы.

Запамятовал упомянуть, что игра зависла, когда попытался выйти из неё после 6000-секундного бага.
0
8
5 лет назад
0
Всех услышал, пойду тестить каждый кейс, отпишусь как найду в чем (хотя бы примерно) причина.

8gabriel8:
pAxsIs, чтобы обнулить события, есть действие, которое приводит триггер в первоначальное состояние. Можно заносить юнитов в виде событий и в группу, триггер на смерть будет удалять из группы, потом, например, каждые 5 минут обновлять триггер до первоначального состояния и сразу добавлять туда события на членов группы.

Запамятовал упомянуть, что игра зависла, когда попытался выйти из неё после 6000-секундного бага.
Спасибо за идею, попробую.
0
29
5 лет назад
0
Та же дота написана на JASS и у нее каждая способность создает временный триггер. Попробую во всяком случае.
JASS автоматически не делает весь код хорошим, а популярность карты не залог оптимального решения.
Порылся я в вашем коде и это ужасно. Копирование триггера, чтобы сделать теже действия, но с другими параметрами повеселило.
Лучше переделать всё пока не позно, а то потом в этой каше ничего не разберёте.
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.