Добавлен
Подскажите плз, как сделать на 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 секунды на функцию, в которой из таймера будут выгружены координаты с юнитом, юнит будет в них перемещён (кстати, перемещать ничто не мешает сразу, разницы в игре не будет, а данных меньше таскать/хранить) и раскрыть кастера.
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
23
Похожие вопросы:

ответ
особо не смотри туда, смотри по съеденной оперативке в диспетчере задач
ответ
действительно, почему же не работает?
Это вообще никак не влияет. Ты ещё скажи, что set a = a + 1 не работает.

Дело может быть в том, что юнит за 10 секунд разлагается.
немного исправленный код
function Reborn takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer s = GetHandleId(t)
    local unit dead = LoadUnitHandle (udg_hash, s, 6)
    call FlushChildHashtable(udg_hash, s)
    call CreateUnit(GetOwningPlayer(dead), GetUnitTypeId(dead), GetUnitX(dead), GetUnitY(dead), GetUnitFacing(dead))
    call DestroyTimer(t)
    set dead = null
    set t = null
endfunction

function Trig_Kill_Unit_Actions takes nothing returns nothing
    local unit dead = GetTriggerUnit()                      //Присваиваем убитого юнита
    local timer t = CreateTimer()                              //Создаём таймер
    local integer s = GetHandleId(t)                         //Узнаём его ID
    call SaveUnitHandle(udg_hash, s, 6, dead)       //Сохраняем юнита 
    call TimerStart(t, 10, false, function Reborn)        //Активируем одноразовый таймер на 10 секунд
    set dead = null
    set t = null
endfunction
код с учётом разложения
function Reborn takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local integer s = GetHandleId(t)
    local player p = LoadPlayerHandle(udg_hash, s, 0)
    local integer id = LoadInteger(udg_hash, s, 0)
    local real x = LoadReal(udg_hash, s, 0)
    local real y = LoadReal(udg_hash, s, 1)
    local real f = LoadReal(udg_hash, s, 2)
    call CreateUnit(p, id, x, y, f)
    call FlushChildHashtable(udg_hash, s)
    call DestroyTimer(t)
    set t = null
    set p = null
endfunction

function Trig_Kill_Unit_Actions takes nothing returns nothing
    local unit dead = GetTriggerUnit()
    local timer t = CreateTimer()
    local integer s = GetHandleId(t)
    call SavePlayerHandle(udg_hash, s, 0, GetOwningPlayer(dead))
    call SaveInteger(udg_hash, s, 0, GetUnitTypeId(dead))
    call SaveReal(udg_hash, s, 0, GetUnitX(dead))
    call SaveReal(udg_hash, s, 1, GetUnitY(dead))
    call SaveReal(udg_hash, s, 2, GetUnitFacing(dead))
    call TimerStart(t, 10, false, function Reborn)
    set dead = null
    set t = null
endfunction
ответ
на жассе - глобальный массив, если таймер один или хештаблица если таких таймеров много
на Lua в 1.31 - есть более удобные способы
ответ
Я полагаю, надо сравнивать вот так, ибо индексация идёт с 1.
GROUP[GetHandleId(unit)][1] == nil
Ну и нужно вот так присваивать.
GROUP[caster_uid][1] = CreateGroup()

18
если я правильно понял вопрос
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
27
вот код
function CheckTimer takes nothing returns nothing

local timer t = GetExpiredTimer()
local integer h1 = GetHandleId(t)

local unit caster = LoadUnitHandle(udg_hash,h1,StringHash("caster")) //вызывается функция CheckTimer таймером, то вар константы вроде GetSpellAbilityUnit() не работают. тк завяны на потоки. Поэтому загружаем кастера из хэша, который сохраняю по ключу хэндла таймера t

local integer h2 = GetHandleId(caster) //далее достаем ключ хэндла кастера

local location point = LoadLocationHandle(udg_hash,h2,StringHash("point"))
local boolean check = LoadBoolean(udg_hash,h2,StringHash("check"))
//call SaveInteger(udg_hash,h2,StringHash("h"), h2 ) //не понятное действие
далее 3 варианта:
1)пересохраняем call SaveBoolean(udg_hash,h2,StringHash("check"), false)
2) очищаете ячейку call RemoveSavedHandle(udg_hash,h2,StringHash("check"))
3) по привычке удалить таймер и очистить таблицу по h1 и h2
берем 3 вариант, тк очистим ячейки хэша и удалим таймер.
call DestroyTimer(t)
call FlushChildHashtable(udg_hash,h1)
call FlushChildHashtable(udg_hash,h2)

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 h1 = GetHandleId(t)
local integer h2 = GetHandleId(caster)
local boolean check = true

call SaveUnitHandle(udg_hash,h1,StringHash("caster"),caster)
call SaveLocationHandle(udg_hash,h1,StringHash("point"),point) //зачем точку создавать?
call SaveBoolean(udg_hash,h2,StringHash("check"),check)
call TimerStart(t, 1, false, function CheckTimer)
set caster = null
set point = null
set t = null

endfunction
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?
Думал, это список всех функций в триггере.
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.