Моя карта разрастается все больше и потихоньку начинаю сокращать и по возможности оптимизировать код.
Идея в том, что я хочу на один триггер повесить несколько заклинаний с событием "боевая единица приводит способность в действие и условием if, then.
Одно из заклинаний просто выполняет действие. Другое имеет ожидание ( вейт или таймер не важно)
Я так понял, каждый раз событие запускается в отдельном потоке и это ничем не грозит, даже если внутри одного будет loop ? То есть ожидание до определенного события?
`
ОЖИДАНИЕ РЕКЛАМЫ...
9
Так попробовал бы на практике, в чем проблема? У меня такая система работает, но я не использую "вейты". Советую в конце каждого заклинания писать return, чтобы следующие ифы не проглядывались.
Ответы (18)
9
SсRealm, "пропустить остальные действия" в гуи, если это не сарказм
15
IzobretatelBoom, в каком смысле?
чтобы следующие ифы не проглядывались.
25
LastUchiha, он имеет ввиду если писать if не в друг в друге, а линейно без else:
if {
	return
} 
if {
	return
}
....
15
konvan5, аа, типо что-бы лишний раз не чекать, если много способностей? Почему бы через elseif не сделать?
25
LastUchiha, именно.
По поводу elseif - много вложенностей может получиться, а в варике есть ограничения на вложенность, из-за чего потом код выполнятся не будет на определенном уровне. Не помню, какие там лимиты.
15
konvan5, это так только с if и loop? Или на loop не распространяется?
25
LastUchiha, по поводу вложенных loop скорее у тебя лимит операций возникнет чем лимиты вложенных циклов)))
Даже 3 вложенных цикла уже может дать тебе большое количество действий.
25
LastUchiha, вот пример:
loop1
	loop2
		loop3

		end3
	end2
end1
loop4
end4
4 цикл не вложенный а последовательно идет после 1 цикла.
Вложенный - когда один цикл внутри другого.
4
LastUchiha, именно.
По поводу elseif - много вложенностей может получиться, а в варике есть ограничения на вложенность, из-за чего потом код выполнятся не будет на определенном уровне. Не помню, какие там лимиты.
Мне стало интересно и решил проверить. У меня работает максимум 116 вложенностей If...Else. На 117-ой и выше варик вылетает. Если конечно я все правильно сделал)
Загруженные файлы
30
IzobretatelBoom, а ещё можно прикинуть, какие заклинания используются на карте чаще других и расположить их выше.
30
konvan5, мы проверяли вложенные loop с одним действием. Там именно лимиты вложенных нод.
25
nazarpunk, а для циклов тоже 150? Или сколько вложений можно :D
30
konvan5, у меня чувство, что там на вложенных годах лимит и тип ноды значения не имеет.
25
Ну в целом ничем не грозит кроме пару НО.
  1. Не используй вейты внутри циклов (ведь счетчик цикла то глобальный).
  2. Если ты сейвишь какие-то данные в переменные, то ты должен понимать, что при вызове этого триггера во время вейта твои переменные могут пересохранится на другие данные и твоя система может сломаться так, думай как такое обходить.
  3. Некоторые переменные могут не сохраниться локально в триггере после вейта, вроде напарывался на подобное, уже точно не помню какие это переменные, к примеру "юнит применяющий способность", но это не точно, надо тестить.
  4. Если у тебя будет слишком много вложений ифов или просто много действий то триггер может до конца не работать (в плане сделает половину действий а дальше делать не будет).
Ответы (3)
21
konvan5, Много это сколько? Просто на будущее визуально цифру в голове держать?
25
SсRealm, по поводу лимитов вот есть статейка
По поводу if вложенных (слышал как 50 так и 90).
30
konvan5, мы тестили, там порядком 150. Но сильно от железа зависит.
4
Забыть что такой wait. Все через таймер!
В целом, если много триггеров с одинаковым событием, можно объединить их в одну (или на несколько). Думаю это может снизить нагрузку на цп. Главное потом не запутаться во всем этом.
Этот комментарий удален
28
юзай это xgm.guru/p/wc3/spellcast
library AllGlobalsLib initializer init
globals
    constant hashtable H = InitHashtable( )
    constant key AbilityKey
endglobals

private function actions takes nothing returns nothing
    if HaveSavedString( H, GetSpellAbilityId( ), AbilityKey ) then
        call ExecuteFunc( LoadStr( H, GetSpellAbilityId( ), AbilityKey ) )
    endif
endfunction

private function init takes nothing returns nothing
    local trigger trg = CreateTrigger( )
    local integer i = 0
    
    loop
        call TriggerRegisterPlayerUnitEvent( trg, Player( i ), EVENT_PLAYER_UNIT_SPELL_EFFECT, null )
        set i = i + 1
        exitwhen i >= bj_MAX_PLAYER_SLOTS
    endloop
    
    call TriggerAddAction( trg, function actions )
    
    call SaveStr( H, 'A000', AbilityKey, "FirstAbility_Actions" )
    call SaveStr( H, 'A001', AbilityKey, "SecondAbility_Actions" )
    call SaveStr( H, 'A002', AbilityKey, "ThirdAbility_Actions" )
    call SaveStr( H, 'A003', AbilityKey, "FourthAbility_Actions" )
    
    set trg = null
endfunction
endlibrary
просто сохраняешь в равкод абилки вызываемую ей функцию, ты сможешь получать кастера, точку каста, цель каста и всё остальное, поскольку ExecuteFunc наследует параметры потока, из которого вызывается эта функция, создавая новый поток
4
Или при инициализации карты выключить все триггеры со способностями. И когда игрок выберет некого героя, включить триггеры способностей только выбранного героя.
Ответы (1)
30
Joma, из нужно не выключать, а не создавать. При выборе героя создать три горы и повесить на них нужные действия.
23
Ну если у тебя в if'е стоит цикл, или даже вейт в цикле (при условии что счётчик цикла локальный или есть нормальное условие выхода из цикла, тоже с локалками) и есть return'ы, то работать будет нормально. Желательно сделать ещё и более общие условия, чтобы отсеять например не героев или здания итд итп
Ответы (6)
30
EugeAl, не забудь уточнить, что общие условия необходимо в начале проверять чтоб как можно раньше завершить функцию. А то были прецеденты.
23
nazarpunk, ну блин, это и так очевидно. Думаю, разберётся автор поста)
30
EugeAl, ты много чужого кода читал? Просто я с позиции своего опыта говорю.
23
nazarpunk, доводилось... чуть мозг не сломал себе
В общем да, все общие условия нужно первым делом проверять, а потом уже конкретику проверять
30
EugeAl, ну вот, так что лучше взять за правило, что даже очевидные вещи желательно лишний раз уточнить.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.