Добавлен
Подскажите плз, как сделать на JASS такой таймер, чтоб он не периодически что-то выполнял, а чтоб просто обратный отчёт начинался. Чтоб перед его началом я смог написать local boolean check = true. Дальше типо стартует таймер, и когда таймер истечёт( GetExpiredTimer(), как я понял ), чтоб я смог написать local boolean = false. И чтоб это правильно работало.
у меня функции такие:
function CheckTimer takes nothing returns nothing

    local unit caster = GetSpellAbilityUnit()
    local integer h = GetHandleId(caster)
    local timer t = GetExpiredTimer()

    local location point = LoadLocationHandle(udg_hash,h,StringHash("point"))  
    local boolean check = LoadBoolean(udg_hash,h,StringHash("check"))
    
    
    call LoadUnitHandle(udg_hash,h,StringHash("caster"))
    call SaveInteger(udg_hash,h,StringHash("h"), h )
    call SaveBoolean(udg_hash,h,StringHash("check"), false)
    
    set caster = null
    set point = null
    set t = null
endfunction
function Attack takes nothing returns nothing

    local unit caster = GetSpellAbilityUnit()
    local location point = GetSpellTargetLoc()
    local timer t = CreateTimer()           //Создаём таймер
    local integer h = GetHandleId(caster)
    local boolean check = true
 
    call SaveUnitHandle(udg_hash,h,StringHash("caster"),caster) 
    call SaveLocationHandle(udg_hash,h,StringHash("point"),point) 
    call SaveBoolean(udg_hash,h,StringHash("check"),check) 
    
    call TimerStart(t, 1, false, function CheckTimer) //Стартуем таймер (fasle - так как не цикличен, если я правильно понял)

    set caster = null
    set point = null
    set t = null
endfunction
Когда я убираю этот таймер вообще, у меня работает, как надо всё. А мне надо, чтоб у меня включался таймер на секунду и за это время работала верхняя функция.

если юнита бьют, он может нажать кнопку и заменит себя на бревно, исчезнет(hide), появится бревно, эффекты и звук, и через 1.5 секунды появится(unhide) в точке, которая указана, как цель заклинания. А если не бьют, то ничего не произоидёт. Так же эффект работает всего 1 секунду(то есть применять типо надо прям перед ударом)
Если это то, о чём идёт речь, то я бы делал так:
  1. Создаётся триггер
    событие — юнит атакован (то есть был отдан приказ атаки с этим юнитом в качестве цели и он находится в пределах дальности атаки атакующего)
    условие — атакованный юнит имеет эту абилку
    действия — сохранить на юнита-цель флаг "сейчас можно применить Каварими но Дзюцу" (как я понимаю, это ты и делаешь в коде в посте), затем создать таймер и запустить его на функцию, в которой этот флаг поменяется на обратное значение/удалится (больше ничего).
  2. Создаётся ещё один триггер
    событие — юнит применяет способность Каварими но Дзюцу
    условие — для применяющего юнита сохранён флаг "сейчас можно применить Каварими но Дзюцу"
    действия — скрыть кастера, создать таймер, сохранить на этот таймер кастера и целевые координаты применённой способности, затем запустить его с задержкой 1.5 секунды на функцию, в которой из таймера будут выгружены координаты с юнитом, юнит будет в них перемещён (кстати, перемещать ничто не мешает сразу, разницы в игре не будет, а данных меньше таскать/хранить) и раскрыть кастера.
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
11
если я правильно понял вопрос
Да, вы правильно поняли. У меня всё заработало благодаря вашему коду.
Поясните плз, для чего нам точка-цель применения способности.
У меня был сохранён кастер-юнит в handl и по нему загружались данные в другом триггере. Щас у меня в другом триггере загружаются данные по тому же юниту. Но теперь в триггере с таймером его нету... Почему это так работает?
Вот код, что у меня. На 3-м скрине мой второй триггер, который загружает всё по хэндлу, в том числе boolean из первого триггера...
для чего точка используется?
Точка используется, чтоб в следующем триггере к ней обратиться и потом типо в неё юнит переместится мгновенно.
Steal nerves:
» вот код
Щас тоже посмотрю. Надо вникнуть.
18
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?
11
» вот код
У меня всё работает и по вашему коду. Но посмотрите на мой ответ Hodor'у. На скринах я не сохраняю по хэндлу юнита(на первых двух). А на третьем я загружаю все данные по хэндлу этого атакованного юнита. Это тот же, что и в первом триггере.
Ну то есть, когда юнит жмёт определённую способность, то на секунду(благодаря этому таймеру) второй триггер становится ТРУ, и этот второй триггер сработает при условии, что юнита бьют. И я не понимаю, почему работает, если я раньше сравнивал кастера из первого триггера с атакованным( GetTroggerUnit() ) из второго. И я сохранял всё по хэндлу кастера из первого триггера, а загружал по хэндлу ТриггерЮнита во втором триггере. И типо так как это один и тот же юнит, то всё работало, кроме запуска таймера.
Просто посмотрите на мой ответ Hodor'у и скажите, почему во втором триггере(3 скрин) функции понимают, что этот GetTriggerUnit() - это юнит из первого триггера...
Если что: первые два скрина - один тригер, а третий - другой триггер.
Как вы вообще так шарите, не пойму:DDD
Hodor:
DopaMine, теперь точка записывается по идентификатору юнита (чтобы можно было использовать на 3 скрине)
Спасибо. Пока разбираюсь, как это работает...
Hodor:
и зачем на втором скриншоте в действиях триггера записаны обе функции: Attack и CheckTimer?
Думал, это список всех функций в триггере.
18
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
11
А вот таймер создает свой поток, в котором уже нету той информации от события триггера, поэтому нужно сохранять эту информацию по идентефикатору таймера
Т.е функция CheckTimer уже будет выполняться в другом потоке
Да, я так и подумал, что надо было из таймера по хэндлу таймера сохранять.
Но откуда на 3скрине(во втором триггере) загружается всё по хэндлу юнита(из первого триггера) - для меня пока загадка...это уже не про таймеры вопрос((
30
DopaMine, две двойные "программистские" кавычки на отдельной строке открывают или закрывают блок кода, и весь текст, находящийся между двумя парами таких кавычек отображается как код.

Работает как на отдельных строках,
так и на одной строке, делая шрифт моноширинным.

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

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

Далее во втором триггере информация берется по индексу юнита из той же хештаблицы и если индекс юнита будет 1092431, то вы получите записанную в первом триггере информацию
Будет другой юнит - будет другой индекс
11
» 2
АААААААА, ясно. То есть, чтоб сработала функция, её нужно вызвать где-нибудь. По дефолту это происходит в событиях. А если есть таймер, то функция, зависящая от параметров таймера, должна быть вызвана только из таймера, а не откуда-то ещё. Правильно я понял?
Clamp:
Работает как на отдельных строках,
Спасибо!
18
DopaMine, если вам нужно вызвать функцию через время - то да, это делается через таймер
если моментально, можно даже сказать в том же потоке выполнения, то достаточно команды call

Ну можно ещё записать функцию в действия триггера, тогда при срабатывании события триггер вызовет эту функцию
11
ну так в первом триггере нужная информация записывается в хеш-таблицу по идентификатору юнита
Да, всё понятно. Вчера уже по хэндлу вопросы задавал здесь))) Щас просто не заметил, что всё сохраняется и в первом триггере через этого юнита. Для меня со вчера немного в диковинку эти хендлы да хеши)))
Всем спасибо! Вопрос закрыт)))
18
Ещё добавлю:
Триггер = приводящий нечто в действие элемент
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.