18

» WarCraft 3 / Бета версия Warcraft III Reforged 1.32

VladBmw530, попробуй запустить его с новыми моделями и скинуть полный скриншот
18

» WarCraft 3 / CreateTimer

Clamp, ну и то и другое, кое где надо переписать натыкать пробелов название поменять, кое где переместить

ладно всё, я ушёл
18

» WarCraft 3 / CreateTimer

про 1000 потоков было
да просто почти все карты на гуи имеют на одно и тоже событие (например юнит атакован) около 50 триггеров
а во всяких петробалансах вообще лютейшая дичь, тупо событие на вход в регион имеет около двухста триггеров

Ну и даже если у тебя 10к+ строк кода, этот код же можно нормально структурировать, а не тупо приписывать в Map Custom Script каждый раз внизу.
так я и не говорил что нельзя переписывать)
я прямо так и подчеркнул что с нуля
хотяяяя, оно тоже мазохизм, но меньший)))

Алсо оффтоп, закругляемся.
ладно, пойду посплю
18

» WarCraft 3 / CreateTimer

структурировать надо код всегда
и по возможности на каждый вид события один триггер
иначе при дальнейших модификациях карты будет получаться всё более жесткое месиво из кода
и в один день настанет момент когда уже нереально будет контроллировать ~10к строк перемешанного кода, всплывет вопрос об оптимизации
любой человек без склонностей к мазохизму придет к выводу что надо переписывать с нуля всё
хотяяяя, оно тоже мазохизм, но меньший)))
18

» WarCraft 3 / CreateTimer

DopaMine, луа начинается с версии варкрафта 1.31 и в рефордже 100% будет
18

» WarCraft 3 / CreateTimer

блин, да почему я путаю всё сегодня
вот заново примеры:
1
Регистрируется событие на "Горного короля" когда он начинает применять способность
Так же записываются условия и действия
Далее я жму любую из его способностей
Срабатывает событие
Вызывается первая функция-условие Condition1, она возвращает true - значит всё нормально
так же у Condition2
Далее на экран выводится текст:
text1
text2
Т.е сработали функции Action1 и Action2
function Action1 takes nothing returns nothing
    call BJDebugMsg("text1")
endfunction
function Action2 takes nothing returns nothing
    call BJDebugMsg("text2")
endfunction

function Condition1 takes nothing returns boolean
    return true
endfunction
function Condition2 takes nothing returns boolean
    return true
endfunction

function InitTrig_s takes nothing returns nothing
    local trigger trg = CreateTrigger(  )

    call TriggerRegisterUnitEvent(trg, gg_unit_Hmkg_0001, EVENT_UNIT_SPELL_CHANNEL )
    
    call TriggerAddCondition(trg, Condition(function Condition1))
    call TriggerAddCondition(trg, Condition(function Condition2))
    
    call TriggerAddAction(trg, function Action1)
    call TriggerAddAction(trg, function Action2)
endfunction
2
я жму любую из его способностей
Срабатывает событие
Вызывается первая функция-условие Condition1, она возвращает true - значит всё нормально
а вот Condition2 возвращает false - значит действия триггера не будут выполняться и на экран ничего не выведется
function Action1 takes nothing returns nothing
    call BJDebugMsg("text1")
endfunction
function Action2 takes nothing returns nothing
    call BJDebugMsg("text2")
endfunction

function Condition1 takes nothing returns boolean
    return true
endfunction
function Condition2 takes nothing returns boolean
    return false
endfunction

function InitTrig_s takes nothing returns nothing
    local trigger trg = CreateTrigger(  )

    call TriggerRegisterUnitEvent(trg, gg_unit_Hmkg_0001, EVENT_UNIT_SPELL_CHANNEL )
    
    call TriggerAddCondition(trg, Condition(function Condition1))
    call TriggerAddCondition(trg, Condition(function Condition2))
    
    call TriggerAddAction(trg, function Action1)
    call TriggerAddAction(trg, function Action2)
endfunction
3
тоже самое как в первом примере
function Action1 takes nothing returns nothing
    call BJDebugMsg("text1")
endfunction

function Condition1 takes nothing returns boolean
    return true
endfunction

function InitTrig_s takes nothing returns nothing
    local trigger trg = CreateTrigger(  )

    call TriggerRegisterUnitEvent(trg, gg_unit_Hmkg_0001, EVENT_UNIT_SPELL_CHANNEL )
    
    call TriggerAddCondition(trg, Condition(function Condition1))
    
    call TriggerAddAction(trg, function Action1)
endfunction
18

» WarCraft 3 / CreateTimer

1
Регистрируется событие на "Горного короля" когда он начинает применять способность
Так же записываются условия и действия
Далее я жму любую из его способностей
Срабатывает событие
Вызывается первая функция-условие Condition1, она возвращает true - значит всё нормально
так же у Condition2
Далее на экран выводится текст:
text1
text2
Т.е сработали функции Action1 и Action2
function Action1 takes nothing returns nothing
    call BJDebugMsg("text1")
endfunction
function Action2 takes nothing returns nothing
    call BJDebugMsg("text2")
endfunction

function Condition1 takes nothing returns boolean
    return true
endfunction
function Condition2 takes nothing returns boolean
    return true
endfunction

function InitTrig_s takes nothing returns nothing
    local trigger trg = CreateTrigger(  )

    call TriggerRegisterUnitEvent(trg, gg_unit_Hmkg_0001, EVENT_UNIT_SPELL_CHANNEL )
    
    call TriggerAddCondition(trg, Condition(function Condition1))
    call TriggerAddCondition(trg, Condition(function Condition2))
    
    call TriggerAddAction(trg, function Action1)
    call TriggerAddAction(trg, function Action2)
endfunction
2
я жму любую из его способностей
Срабатывает событие
Вызывается первая функция-условие Condition1, она возвращает true - значит всё нормально
а вот Condition2 возвращает false - значит действия триггера не будут выполняться и на экран ничего не выведется
function Action1 takes nothing returns nothing
    call BJDebugMsg("text1")
endfunction
function Action2 takes nothing returns nothing
    call BJDebugMsg("text2")
endfunction

function Condition1 takes nothing returns boolean
    return true
endfunction
function Condition2 takes nothing returns boolean
    return false
endfunction

function InitTrig_s takes nothing returns nothing
    local trigger trg = CreateTrigger(  )

    call TriggerRegisterUnitEvent(trg, gg_unit_Hmkg_0001, EVENT_UNIT_SPELL_CHANNEL )
    
    call TriggerAddCondition(trg, Condition(function Condition1))
    call TriggerAddCondition(trg, Condition(function Condition2))
    
    call TriggerAddAction(trg, function Action1)
    call TriggerAddAction(trg, function Action2)
endfunction
3
тоже самое как в первом примере
function Action1 takes nothing returns nothing
    call BJDebugMsg("text1")
endfunction

function Condition1 takes nothing returns boolean
    return true
endfunction

function InitTrig_s takes nothing returns nothing
    local trigger trg = CreateTrigger(  )

    call TriggerRegisterUnitEvent(trg, gg_unit_Hmkg_0001, EVENT_UNIT_SPELL_CHANNEL )
    
    call TriggerAddCondition(trg, Condition(function Condition1))
    
    call TriggerAddAction(trg, function Action1)
endfunction
18

» WarCraft 3 / CreateTimer

DopaMine:
Но я вот, что хотел всегда понять ещё: несколько событий могут быть написаны на одного юнита? То есть, чтоб что-то сработало, когда юнит и атакованный, к примеру, и входящий в зону.
могут
18

» WarCraft 3 / CreateTimer

Так же добавлю:
функций условий может быть несколько
Ща примеры подгоню
18

» WarCraft 3 / CreateTimer

И ещё такое понятие: условие триггера
В пищевой цепочке оно примерно так лежит
Событие => Условие => Действие

Условие тоже является функцией (на 3 скрине самая верхняя)
Если функция-условие вернет true - значит триггер начнет вызывать функции-действия
Если вернет false - значит не будет вызывать
18

» WarCraft 3 / CreateTimer

DopaMine, чуть ошибся) Исправил
Ну можно ещё записать функцию в действия триггера, тогда при срабатывании события триггер вызовет эту функцию

События триггера это к примеру когда вы регистрируете событие ЮНИТ-АТАКОВАН
И при атаке вашего юнита - в триггере сработает событие и он вызовет функции из действий
18

» WarCraft 3 / CreateTimer

Ещё добавлю:
Триггер = приводящий нечто в действие элемент
18

» WarCraft 3 / CreateTimer

DopaMine, если вам нужно вызвать функцию через время - то да, это делается через таймер
если моментально, можно даже сказать в том же потоке выполнения, то достаточно команды call

Ну можно ещё записать функцию в действия триггера, тогда при срабатывании события триггер вызовет эту функцию
18

» WarCraft 3 / CreateTimer

DopaMine, ну так в первом триггере нужная информация записывается в хеш-таблицу по идентификатору юнита
и потом та же информация во втором триггере берется по идентификатору юнита из хеш-таблицы

GetHandleId возвращает число, грубо говоря индекс юнита (к примеру 1092431)
Нужная вам информация сохраняется в хеш-таблицу под индексом 1092431

Далее во втором триггере информация берется по индексу юнита из той же хештаблицы и если индекс юнита будет 1092431, то вы получите записанную в первом триггере информацию
Будет другой юнит - будет другой индекс
18

» WarCraft 3 / CreateTimer

DopaMine, в jass есть такое понятие как "поток выполнения":
к примеру каждое событие триггера создает новый поток и в этом потоке хранится информация типа GetSpellAbilityUnit/GetTriggerUnit
Вызывая функцию GetSpellAbilityUnut() вы берете из потока информацию которую заложило в него событие триггера

А вот таймер создает свой поток, в котором уже нету той информации от события триггера, поэтому нужно сохранять эту информацию по идентификатору таймера
Т.е функция CheckTimer уже будет выполняться в другом потоке

Пример:
1
myFunc2 - это действия триггера

function myFunc1 takes nothing returns nothing
	call BJDebugMsg(GetUnitName(GetTriggerUnit()))
	//на экран будет выведено имя юнита
endfunction
function myFunc2 takes nothing returns nothing
	call myFunc1
endfunction
2
myFunc2 - это действия триггера
т.е поток выполнения начинается с функции myFunc2, запускается таймер, поток выполнения заканчивается
проходит 1 секунда
таймер создает свой поток выполнения, который начинается с функции myFunc1

function myFunc1 takes nothing returns nothing
	call BJDebugMsg(GetUnitName(GetTriggerUnit()))
	//на экран ничего не выведется, т.к поток совсем другой и в нем нету информации от события триггера
endfunction
function myFunc2 takes nothing returns nothing
	call TimerStart(CreateTimer(), 1.00, false, function myFunc1)
endfunction
18

» WarCraft 3 / CreateTimer

DopaMine, теперь точка записывается по идентификатору юнита (чтобы можно было использовать на 3 скрине)
код
function CheckTimer takes nothing returns nothing
    local    timer t      = GetExpiredTimer()
    local  integer h      = GetHandleId(t)
    local     unit caster = LoadUnitHandle    (udg_hash, h, 0) //Загружаем юнита по идентификатору таймера

    //Удаляем таймер и то что было записано в хеш-таблице
    call FlushChildHashtable(udg_hash, h)
    call DestroyTimer(t)
    
    //Таймер завершил отсчет и теперь его можно будет заново создавать и запускать
    call SaveBoolean(udg_hash, GetHandleId(caster), StringHash("check"), false)

    set caster = null
    set      p = null
    set      t = null
endfunction

function Attack takes nothing returns nothing
    local     unit caster = GetSpellAbilityUnit()
    local    timer t
    local  integer h      = GetHandleId(caster)
    local  boolean check  = LoadBoolean(udg_hash, h, StringHash("check")) //Для того, чтобы знать запущен ли таймер

    if( not check ) then
    
        //Таймер запущен
        call SaveBoolean(udg_hash, h, StringHash("check"), true)
        //Удаляем точку
        call RemoveLocation(LoadLocationHandle(udg_hash, h, StringHash("point")))
        //Сохраняем точку по идентификатору юнита
        call SaveLocationHandle(udg_hash, h, StringHash("point"), GetSpellTargetLoc())

        set t = CreateTimer()  //Создаем таймер
        set h = GetHandleId(t) //Берем идентификатор таймера
        
        call SaveUnitHandle    (udg_hash, h, 0, caster             ) //Сохраняем юнита по идентификатору таймера
        
        call TimerStart(t, 1.00, false, function CheckTimer)
        
    endif
    
    set caster = null
    set      t = null
endfunction

и зачем на втором скриншоте в действиях триггера записаны обе функции: Attack и CheckTimer?
18

» WarCraft 3 / CreateTimer

если я правильно понял вопрос
function CheckTimer takes nothing returns nothing
    local    timer t      = GetExpiredTimer()
    local  integer h      = GetHandleId(t)
    local     unit caster = LoadUnitHandle    (udg_hash, h, 0) //Загружаем юнита по идентификатору таймера
    local location p      = LoadLocationHandle(udg_hash, h, 1) //Загружаем точку по идентификатору таймера

    //Удаляем таймер и то что было записано в хеш-таблице
    call FlushChildHashtable(udg_hash, h)
    call DestroyTimer(t)
    
    //Таймер завершил отсчет и теперь его можно будет заново создавать и запускать
    call SaveBoolean(udg_hash, GetHandleId(caster), StringHash("check"), false)

    //Удаляем точку
    call RemoveLocation(p)
    set caster = null
    set      p = null
    set      t = null
endfunction

function Attack takes nothing returns nothing
    local     unit caster = GetSpellAbilityUnit()
    local    timer t
    local  integer h      = GetHandleId(caster)
    local  boolean check  = LoadBoolean(udg_hash, h, StringHash("check")) //Для того, чтобы знать запущен ли таймер

    if( not check ) then
    
        call SaveBoolean(udg_hash, h, StringHash("check"), true) //Таймер запущен

        set t = CreateTimer()  //Создаем таймер
        set h = GetHandleId(t) //Берем идентификатор таймера
        
        call SaveUnitHandle    (udg_hash, h, 0, caster             ) //Сохраняем юнита по идентификатору таймера
        call SaveLocationHandle(udg_hash, h, 1, GetSpellTargetLoc()) //Сохраняем точку по идентификатору таймера
        
        call TimerStart(t, 1.00, false, function CheckTimer)
        
    endif
    
    set caster = null
    set      t = null
endfunction
18

» WarCraft 3 / Конвертер карты в 1.26

Че то случайно обнаружил косяк
В структуре файла триггеров 1.31 какое то изменение (не знаю каким образом у меня редактор 1.26 открыл карту, но ща обновлю ресурс и добавлю фишку чтобы .wtg/.wct удалялись)